dbgdwarf.pas 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  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. cgbase,
  194. finput,
  195. fmodule,
  196. defutil,
  197. symconst,symsym
  198. ;
  199. const
  200. DW_TAG_lo_user = $4080;
  201. DW_TAG_hi_user = $ffff;
  202. { Flag that tells whether entry has a child or not. }
  203. DW_children_no = 0;
  204. DW_children_yes = 1;
  205. const
  206. { Implementation-defined range start. }
  207. DW_AT_lo_user = $2000;
  208. { Implementation-defined range end. }
  209. DW_AT_hi_user = $3ff0;
  210. type
  211. { Source language names and codes. }
  212. tdwarf_source_language = (DW_LANG_C89 := $0001,DW_LANG_C := $0002,DW_LANG_Ada83 := $0003,
  213. DW_LANG_C_plus_plus := $0004,DW_LANG_Cobol74 := $0005,
  214. DW_LANG_Cobol85 := $0006,DW_LANG_Fortran77 := $0007,
  215. DW_LANG_Fortran90 := $0008,DW_LANG_Pascal83 := $0009,
  216. DW_LANG_Modula2 := $000a,DW_LANG_Java := $000b,
  217. { DWARF 3. }
  218. DW_LANG_C99 := $000c,DW_LANG_Ada95 := $000d,
  219. DW_LANG_Fortran95 := $000e,
  220. { MIPS. }
  221. DW_LANG_Mips_Assembler := $8001,
  222. { UPC. }
  223. DW_LANG_Upc := $8765
  224. );
  225. const
  226. { Implementation-defined range start. }
  227. DW_LANG_lo_user = $8000;
  228. { Implementation-defined range start. }
  229. DW_LANG_hi_user = $ffff;
  230. type
  231. { Names and codes for macro information. }
  232. tdwarf_macinfo_record_type = (DW_MACINFO_define := 1,DW_MACINFO_undef := 2,
  233. DW_MACINFO_start_file := 3,DW_MACINFO_end_file := 4,
  234. DW_MACINFO_vendor_ext := 255);
  235. type
  236. { Type encodings. }
  237. Tdwarf_type = (DW_ATE_void := $0,DW_ATE_address := $1,
  238. DW_ATE_boolean := $2,DW_ATE_complex_float := $3,
  239. DW_ATE_float := $4,DW_ATE_signed := $5,
  240. DW_ATE_signed_char := $6,DW_ATE_unsigned := $7,
  241. DW_ATE_unsigned_char := $8,DW_ATE_imaginary_float := $9,
  242. { HP extensions. }
  243. DW_ATE_HP_float80 := $80,DW_ATE_HP_complex_float80 := $81,
  244. DW_ATE_HP_float128 := $82,DW_ATE_HP_complex_float128 := $83,
  245. DW_ATE_HP_floathpintel := $84,DW_ATE_HP_imaginary_float80 := $85,
  246. DW_ATE_HP_imaginary_float128 := $86
  247. );
  248. const
  249. DW_ATE_lo_user = $80;
  250. DW_ATE_hi_user = $ff;
  251. type
  252. Tdwarf_array_dim_ordering = (DW_ORD_row_major := 0,DW_ORD_col_major := 1
  253. );
  254. { Access attribute. }
  255. Tdwarf_access_attribute = (DW_ACCESS_public := 1,DW_ACCESS_protected := 2,
  256. DW_ACCESS_private := 3);
  257. { Visibility. }
  258. Tdwarf_visibility_attribute = (DW_VIS_local := 1,DW_VIS_exported := 2,
  259. DW_VIS_qualified := 3);
  260. { Virtuality. }
  261. Tdwarf_virtuality_attribute = (DW_VIRTUALITY_none := 0,DW_VIRTUALITY_virtual := 1,
  262. DW_VIRTUALITY_pure_virtual := 2);
  263. { Case sensitivity. }
  264. Tdwarf_id_case = (DW_ID_case_sensitive := 0,DW_ID_up_case := 1,
  265. DW_ID_down_case := 2,DW_ID_case_insensitive := 3
  266. );
  267. { Calling convention. }
  268. Tdwarf_calling_convention = (DW_CC_normal := $1,DW_CC_program := $2,
  269. DW_CC_nocall := $3,DW_CC_GNU_renesas_sh := $40
  270. );
  271. { Location atom names and codes. }
  272. Tdwarf_location_atom = (DW_OP_addr := $03,DW_OP_deref := $06,DW_OP_const1u := $08,
  273. DW_OP_const1s := $09,DW_OP_const2u := $0a,
  274. DW_OP_const2s := $0b,DW_OP_const4u := $0c,
  275. DW_OP_const4s := $0d,DW_OP_const8u := $0e,
  276. DW_OP_const8s := $0f,DW_OP_constu := $10,
  277. DW_OP_consts := $11,DW_OP_dup := $12,DW_OP_drop := $13,
  278. DW_OP_over := $14,DW_OP_pick := $15,DW_OP_swap := $16,
  279. DW_OP_rot := $17,DW_OP_xderef := $18,DW_OP_abs := $19,
  280. DW_OP_and := $1a,DW_OP_div := $1b,DW_OP_minus := $1c,
  281. DW_OP_mod := $1d,DW_OP_mul := $1e,DW_OP_neg := $1f,
  282. DW_OP_not := $20,DW_OP_or := $21,DW_OP_plus := $22,
  283. DW_OP_plus_uconst := $23,DW_OP_shl := $24,
  284. DW_OP_shr := $25,DW_OP_shra := $26,DW_OP_xor := $27,
  285. DW_OP_bra := $28,DW_OP_eq := $29,DW_OP_ge := $2a,
  286. DW_OP_gt := $2b,DW_OP_le := $2c,DW_OP_lt := $2d,
  287. DW_OP_ne := $2e,DW_OP_skip := $2f,DW_OP_lit0 := $30,
  288. DW_OP_lit1 := $31,DW_OP_lit2 := $32,DW_OP_lit3 := $33,
  289. DW_OP_lit4 := $34,DW_OP_lit5 := $35,DW_OP_lit6 := $36,
  290. DW_OP_lit7 := $37,DW_OP_lit8 := $38,DW_OP_lit9 := $39,
  291. DW_OP_lit10 := $3a,DW_OP_lit11 := $3b,
  292. DW_OP_lit12 := $3c,DW_OP_lit13 := $3d,
  293. DW_OP_lit14 := $3e,DW_OP_lit15 := $3f,
  294. DW_OP_lit16 := $40,DW_OP_lit17 := $41,
  295. DW_OP_lit18 := $42,DW_OP_lit19 := $43,
  296. DW_OP_lit20 := $44,DW_OP_lit21 := $45,
  297. DW_OP_lit22 := $46,DW_OP_lit23 := $47,
  298. DW_OP_lit24 := $48,DW_OP_lit25 := $49,
  299. DW_OP_lit26 := $4a,DW_OP_lit27 := $4b,
  300. DW_OP_lit28 := $4c,DW_OP_lit29 := $4d,
  301. DW_OP_lit30 := $4e,DW_OP_lit31 := $4f,
  302. DW_OP_reg0 := $50,DW_OP_reg1 := $51,DW_OP_reg2 := $52,
  303. DW_OP_reg3 := $53,DW_OP_reg4 := $54,DW_OP_reg5 := $55,
  304. DW_OP_reg6 := $56,DW_OP_reg7 := $57,DW_OP_reg8 := $58,
  305. DW_OP_reg9 := $59,DW_OP_reg10 := $5a,DW_OP_reg11 := $5b,
  306. DW_OP_reg12 := $5c,DW_OP_reg13 := $5d,
  307. DW_OP_reg14 := $5e,DW_OP_reg15 := $5f,
  308. DW_OP_reg16 := $60,DW_OP_reg17 := $61,
  309. DW_OP_reg18 := $62,DW_OP_reg19 := $63,
  310. DW_OP_reg20 := $64,DW_OP_reg21 := $65,
  311. DW_OP_reg22 := $66,DW_OP_reg23 := $67,
  312. DW_OP_reg24 := $68,DW_OP_reg25 := $69,
  313. DW_OP_reg26 := $6a,DW_OP_reg27 := $6b,
  314. DW_OP_reg28 := $6c,DW_OP_reg29 := $6d,
  315. DW_OP_reg30 := $6e,DW_OP_reg31 := $6f,
  316. DW_OP_breg0 := $70,DW_OP_breg1 := $71,
  317. DW_OP_breg2 := $72,DW_OP_breg3 := $73,
  318. DW_OP_breg4 := $74,DW_OP_breg5 := $75,
  319. DW_OP_breg6 := $76,DW_OP_breg7 := $77,
  320. DW_OP_breg8 := $78,DW_OP_breg9 := $79,
  321. DW_OP_breg10 := $7a,DW_OP_breg11 := $7b,
  322. DW_OP_breg12 := $7c,DW_OP_breg13 := $7d,
  323. DW_OP_breg14 := $7e,DW_OP_breg15 := $7f,
  324. DW_OP_breg16 := $80,DW_OP_breg17 := $81,
  325. DW_OP_breg18 := $82,DW_OP_breg19 := $83,
  326. DW_OP_breg20 := $84,DW_OP_breg21 := $85,
  327. DW_OP_breg22 := $86,DW_OP_breg23 := $87,
  328. DW_OP_breg24 := $88,DW_OP_breg25 := $89,
  329. DW_OP_breg26 := $8a,DW_OP_breg27 := $8b,
  330. DW_OP_breg28 := $8c,DW_OP_breg29 := $8d,
  331. DW_OP_breg30 := $8e,DW_OP_breg31 := $8f,
  332. DW_OP_regx := $90,DW_OP_fbreg := $91,DW_OP_bregx := $92,
  333. DW_OP_piece := $93,DW_OP_deref_size := $94,
  334. DW_OP_xderef_size := $95,DW_OP_nop := $96,
  335. { DWARF 3 extensions. }
  336. DW_OP_push_object_address := $97,DW_OP_call2 := $98,
  337. DW_OP_call4 := $99,DW_OP_call_ref := $9a,
  338. { GNU extensions. }
  339. DW_OP_GNU_push_tls_address := $e0,
  340. { HP extensions. }
  341. DW_OP_HP_unknown := $e0,
  342. DW_OP_HP_is_value := $e1,DW_OP_HP_fltconst4 := $e2,
  343. DW_OP_HP_fltconst8 := $e3,DW_OP_HP_mod_range := $e4,
  344. DW_OP_HP_unmod_range := $e5,DW_OP_HP_tls := $e6
  345. );
  346. const
  347. { Implementation-defined range start. }
  348. DW_OP_lo_user = $e0;
  349. { Implementation-defined range end. }
  350. DW_OP_hi_user = $ff;
  351. function TDebugInfoDwarf.def_dwarf_lab(def:tdef) : tasmsymbol;
  352. begin
  353. { procdefs only need a number, mark them as already written
  354. so they won't be written implicitly }
  355. if (def.deftype=procdef) then
  356. def.dbg_state:=dbg_state_written;
  357. { dwarf must already be written, or we must be busy writing it }
  358. if writing_def_dwarf and
  359. not(def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  360. internalerror(200601241);
  361. { Keep track of used dwarf entries, this info is only usefull for dwarf entries
  362. referenced by the symbols. Definitions will always include all
  363. required stabs }
  364. if def.dbg_state=dbg_state_unused then
  365. def.dbg_state:=dbg_state_used;
  366. { Need a new label? }
  367. if def.dwarf_lab=nil then
  368. begin
  369. objectlibrary.getdatalabel(def.dwarf_lab);
  370. end;
  371. result:=def.dwarf_lab;
  372. end;
  373. { writing the data through a few simply procedures allows to create easily extra information
  374. for debugging of debug info }
  375. function TDebugInfoDwarf.append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const) : longint;
  376. var
  377. i : longint;
  378. begin
  379. inc(currabbrevnumber);
  380. asmlist[al_dwarf_abbrev].concat(tai_comment.Create(strpnew('Abbrev '+tostr(currabbrevnumber))));
  381. { abbrev number }
  382. asmlist[al_dwarf_info].concat(tai_const.create_uleb128bit(currabbrevnumber));
  383. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(currabbrevnumber));
  384. { tag }
  385. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(tag)));
  386. { children? }
  387. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(ord(has_children)));
  388. i:=0;
  389. while i<=high(data) do
  390. begin
  391. { attribute }
  392. if data[i].VType=vtInteger then
  393. begin
  394. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  395. end
  396. else
  397. internalerror(200601261);
  398. inc(i);
  399. { form }
  400. if data[i].VType=vtInteger then
  401. begin
  402. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  403. end
  404. else
  405. internalerror(200601262);
  406. inc(i);
  407. { info itself }
  408. case tdwarf_form(data[i-1].VInteger) of
  409. DW_FORM_string:
  410. case data[i].VType of
  411. vtChar:
  412. asmlist[al_dwarf_info].concat(tai_string.create(data[i].VChar));
  413. vtString:
  414. asmlist[al_dwarf_info].concat(tai_string.create(data[i].VString^));
  415. vtAnsistring:
  416. asmlist[al_dwarf_info].concat(tai_string.create(Ansistring(data[i].VAnsiString^)));
  417. else
  418. internalerror(200601264);
  419. end;
  420. DW_FORM_flag:
  421. asmlist[al_dwarf_info].concat(tai_const.create_8bit(byte(data[i].VBoolean)));
  422. DW_FORM_data1:
  423. asmlist[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  424. DW_FORM_data2:
  425. asmlist[al_dwarf_info].concat(tai_const.create_16bit(data[i].VInteger));
  426. DW_FORM_data4:
  427. asmlist[al_dwarf_info].concat(tai_const.create_32bit(data[i].VInteger));
  428. DW_FORM_data8:
  429. asmlist[al_dwarf_info].concat(tai_const.create_64bit(data[i].VInteger));
  430. DW_FORM_sdata:
  431. case data[i].VType of
  432. vtInteger:
  433. asmlist[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VInteger));
  434. vtInt64:
  435. asmlist[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VInt64^));
  436. vtQWord:
  437. asmlist[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VQWord^));
  438. else
  439. internalerror(200601285);
  440. end;
  441. DW_FORM_udata:
  442. case data[i].VType of
  443. vtInteger:
  444. asmlist[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VInteger));
  445. vtInt64:
  446. asmlist[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VInt64^));
  447. vtQWord:
  448. asmlist[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VQWord^));
  449. else
  450. internalerror(200601284);
  451. end;
  452. { block gets only the size, the rest is appended manually by the caller }
  453. DW_FORM_block1:
  454. asmlist[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  455. else
  456. internalerror(200601263);
  457. end;
  458. inc(i);
  459. end;
  460. end;
  461. procedure TDebugInfoDwarf.append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
  462. begin
  463. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  464. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_addr)));
  465. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  466. end;
  467. procedure TDebugInfoDwarf.append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
  468. begin
  469. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  470. {$ifdef cpu64bit}
  471. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_ref8)));
  472. {$else cpu64bit}
  473. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_ref4)));
  474. {$endif cpu64bit}
  475. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  476. end;
  477. procedure TDebugInfoDwarf.append_labelentry_data(attr : tdwarf_attribute;sym : tasmsymbol);
  478. begin
  479. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  480. {$ifdef cpu64bit}
  481. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  482. {$else cpu64bit}
  483. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  484. {$endif cpu64bit}
  485. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  486. end;
  487. procedure TDebugInfoDwarf.finish_entry;
  488. begin
  489. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  490. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  491. end;
  492. procedure TDebugInfoDwarf.finish_children;
  493. begin
  494. asmlist[al_dwarf_info].concat(tai_const.create_8bit(0));
  495. end;
  496. procedure TDebugInfoDwarf.append_dwarftag(list:taasmoutput;def:tdef);
  497. procedure append_dwarftag_orddef(def:torddef);
  498. begin
  499. case def.typ of
  500. s8bit,
  501. s16bit,
  502. s32bit :
  503. begin
  504. { we should generate a subrange type here }
  505. if assigned(def.typesym) then
  506. append_entry(DW_TAG_base_type,false,[
  507. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  508. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  509. DW_AT_byte_size,DW_FORM_data1,def.size
  510. ])
  511. else
  512. append_entry(DW_TAG_base_type,false,[
  513. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  514. DW_AT_byte_size,DW_FORM_data1,def.size
  515. ]);
  516. finish_entry;
  517. end;
  518. u8bit,
  519. u16bit,
  520. u32bit :
  521. begin
  522. { we should generate a subrange type here }
  523. if assigned(def.typesym) then
  524. append_entry(DW_TAG_base_type,false,[
  525. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  526. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  527. DW_AT_byte_size,DW_FORM_data1,def.size
  528. ])
  529. else
  530. append_entry(DW_TAG_base_type,false,[
  531. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  532. DW_AT_byte_size,DW_FORM_data1,def.size
  533. ]);
  534. finish_entry;
  535. end;
  536. uvoid :
  537. begin
  538. append_entry(DW_TAG_unspecified_type,false,[
  539. DW_AT_name,DW_FORM_string,'Void'#0]);
  540. finish_entry;
  541. end;
  542. uchar :
  543. begin
  544. append_entry(DW_TAG_base_type,false,[
  545. DW_AT_name,DW_FORM_string,'Char'#0,
  546. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  547. DW_AT_byte_size,DW_FORM_data1,1
  548. ]);
  549. finish_entry;
  550. end;
  551. uwidechar :
  552. begin
  553. append_entry(DW_TAG_base_type,false,[
  554. DW_AT_name,DW_FORM_string,'WideChar'#0,
  555. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  556. DW_AT_byte_size,DW_FORM_data1,2
  557. ]);
  558. finish_entry;
  559. end;
  560. bool8bit :
  561. begin
  562. append_entry(DW_TAG_base_type,false,[
  563. DW_AT_name,DW_FORM_string,'Boolean'#0,
  564. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  565. DW_AT_byte_size,DW_FORM_data1,1
  566. ]);
  567. finish_entry;
  568. end;
  569. bool16bit :
  570. begin
  571. append_entry(DW_TAG_base_type,false,[
  572. DW_AT_name,DW_FORM_string,'WordBool'#0,
  573. DW_AT_encoding,DW_FORM_data1,DW_ATE_boolean,
  574. DW_AT_byte_size,DW_FORM_data1,2
  575. ]);
  576. finish_entry;
  577. end;
  578. bool32bit :
  579. begin
  580. append_entry(DW_TAG_base_type,false,[
  581. DW_AT_name,DW_FORM_string,'LongBool'#0,
  582. DW_AT_encoding,DW_FORM_data1,DW_ATE_boolean,
  583. DW_AT_byte_size,DW_FORM_data1,4
  584. ]);
  585. finish_entry;
  586. end;
  587. u64bit :
  588. begin
  589. append_entry(DW_TAG_base_type,false,[
  590. DW_AT_name,DW_FORM_string,'QWord'#0,
  591. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  592. DW_AT_byte_size,DW_FORM_data1,8
  593. ]);
  594. finish_entry;
  595. end;
  596. s64bit :
  597. begin
  598. append_entry(DW_TAG_base_type,false,[
  599. DW_AT_name,DW_FORM_string,'Int64'#0,
  600. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  601. DW_AT_byte_size,DW_FORM_data1,8
  602. ]);
  603. finish_entry;
  604. end;
  605. else
  606. internalerror(200601287);
  607. end;
  608. end;
  609. procedure append_dwarftag_floatdef(def:tfloatdef);
  610. begin
  611. case def.typ of
  612. s32real,
  613. s64real,
  614. s80real:
  615. if assigned(def.typesym) then
  616. append_entry(DW_TAG_base_type,false,[
  617. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  618. DW_AT_encoding,DW_FORM_data1,DW_ATE_float,
  619. DW_AT_byte_size,DW_FORM_data1,def.size
  620. ])
  621. else
  622. append_entry(DW_TAG_base_type,false,[
  623. DW_AT_encoding,DW_FORM_data1,DW_ATE_float,
  624. DW_AT_byte_size,DW_FORM_data1,def.size
  625. ]);
  626. s64currency:
  627. { we should use DW_ATE_signed_fixed, however it isn't supported yet by GDB (FK) }
  628. if assigned(def.typesym) then
  629. append_entry(DW_TAG_base_type,false,[
  630. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  631. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  632. DW_AT_byte_size,DW_FORM_data1,8
  633. ])
  634. else
  635. append_entry(DW_TAG_base_type,false,[
  636. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  637. DW_AT_byte_size,DW_FORM_data1,8
  638. ]);
  639. s64comp:
  640. if assigned(def.typesym) then
  641. append_entry(DW_TAG_base_type,false,[
  642. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  643. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  644. DW_AT_byte_size,DW_FORM_data1,8
  645. ])
  646. else
  647. append_entry(DW_TAG_base_type,false,[
  648. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  649. DW_AT_byte_size,DW_FORM_data1,8
  650. ]);
  651. else
  652. internalerror(200601289);
  653. end;
  654. finish_entry;
  655. end;
  656. procedure append_dwarftag_enumdef(def:tenumdef);
  657. var
  658. hp : tenumsym;
  659. begin
  660. if assigned(def.typesym) then
  661. append_entry(DW_TAG_enumeration_type,true,[
  662. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  663. DW_AT_byte_size,DW_FORM_data1,def.size
  664. ])
  665. else
  666. append_entry(DW_TAG_enumeration_type,true,[
  667. DW_AT_byte_size,DW_FORM_data1,def.size
  668. ]);
  669. if assigned(def.basedef) then
  670. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.basedef));
  671. finish_entry;
  672. { write enum symbols }
  673. hp:=tenumsym(def.firstenum);
  674. while assigned(hp) do
  675. begin
  676. append_entry(DW_TAG_enumerator,false,[
  677. DW_AT_name,DW_FORM_string,hp.name+#0,
  678. DW_AT_const_value,DW_FORM_data4,hp.value
  679. ]);
  680. finish_entry;
  681. hp:=tenumsym(hp).nextenum;
  682. end;
  683. finish_children;
  684. end;
  685. begin
  686. list.concat(tai_symbol.create(def_dwarf_lab(def),0));
  687. case def.deftype of
  688. {
  689. stringdef :
  690. result:=stringdef_stabstr(tstringdef(def));
  691. }
  692. enumdef :
  693. append_dwarftag_enumdef(tenumdef(def));
  694. orddef :
  695. append_dwarftag_orddef(torddef(def));
  696. pointerdef :
  697. begin
  698. append_entry(DW_TAG_pointer_type,false,[]);
  699. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tpointerdef(def).pointertype.def));
  700. end;
  701. floatdef :
  702. append_dwarftag_floatdef(tfloatdef(def));
  703. {
  704. filedef :
  705. result:=filedef_stabstr(tfiledef(def));
  706. recorddef :
  707. result:=recorddef_stabstr(trecorddef(def));
  708. variantdef :
  709. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  710. classrefdef :
  711. result:=strpnew(def_stab_number(pvmttype.def));
  712. }
  713. setdef :
  714. begin
  715. if assigned(def.typesym) then
  716. append_entry(DW_TAG_enumeration_type,true,[
  717. DW_AT_name,DW_FORM_string,def.typesym.name+#0,
  718. DW_AT_byte_size,DW_FORM_data1,def.size
  719. ])
  720. else
  721. append_entry(DW_TAG_enumeration_type,true,[
  722. DW_AT_byte_size,DW_FORM_data1,def.size
  723. ]);
  724. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tsetdef(def).elementtype.def));
  725. finish_entry
  726. end;
  727. {
  728. formaldef :
  729. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  730. arraydef :
  731. result:=def_stabstr_evaluate(def,'ar$1;$2;$3;$4',[def_stab_number(tarraydef(def).rangetype.def),
  732. tostr(tarraydef(def).lowrange),tostr(tarraydef(def).highrange),def_stab_number(tarraydef(def).elementtype.def)]);
  733. procdef :
  734. result:=procdef_stabstr(tprocdef(def));
  735. procvardef :
  736. result:=strpnew('*f'+def_stab_number(tprocvardef(def).rettype.def));
  737. objectdef :
  738. result:=objectdef_stabstr(tobjectdef(def));
  739. undefineddef :
  740. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  741. }
  742. else
  743. internalerror(200601281);
  744. end;
  745. end;
  746. procedure TDebugInfoDwarf.insertdef(list:taasmoutput;def:tdef);
  747. var
  748. anc : tobjectdef;
  749. oldtypesym : tsym;
  750. begin
  751. if (def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  752. exit;
  753. { never write generic template defs }
  754. if df_generic in def.defoptions then
  755. begin
  756. def.dbg_state:=dbg_state_written;
  757. exit;
  758. end;
  759. { to avoid infinite loops }
  760. def.dbg_state := dbg_state_writing;
  761. { write dependencies first }
  762. case def.deftype of
  763. stringdef :
  764. begin
  765. if tstringdef(def).string_typ=st_widestring then
  766. insertdef(list,cwidechartype.def)
  767. else
  768. begin
  769. insertdef(list,cchartype.def);
  770. insertdef(list,u8inttype.def);
  771. end;
  772. end;
  773. floatdef :
  774. insertdef(list,s32inttype.def);
  775. filedef :
  776. begin
  777. insertdef(list,s32inttype.def);
  778. {$ifdef cpu64bit}
  779. insertdef(list,s64inttype.def);
  780. {$endif cpu64bit}
  781. insertdef(list,u8inttype.def);
  782. insertdef(list,cchartype.def);
  783. end;
  784. classrefdef :
  785. insertdef(list,pvmttype.def);
  786. pointerdef :
  787. insertdef(list,tpointerdef(def).pointertype.def);
  788. setdef :
  789. insertdef(list,tsetdef(def).elementtype.def);
  790. procvardef,
  791. procdef :
  792. insertdef(list,tprocdef(def).rettype.def);
  793. arraydef :
  794. begin
  795. insertdef(list,tarraydef(def).rangetype.def);
  796. insertdef(list,tarraydef(def).elementtype.def);
  797. end;
  798. recorddef :
  799. trecorddef(def).symtable.foreach(@field_write_defs,list);
  800. objectdef :
  801. begin
  802. insertdef(list,vmtarraytype.def);
  803. { first the parents }
  804. anc:=tobjectdef(def);
  805. while assigned(anc.childof) do
  806. begin
  807. anc:=anc.childof;
  808. insertdef(list,anc);
  809. end;
  810. tobjectdef(def).symtable.foreach(@field_write_defs,list);
  811. tobjectdef(def).symtable.foreach(@method_write_defs,list);
  812. end;
  813. end;
  814. case def.deftype of
  815. objectdef :
  816. begin
  817. { classes require special code to write the record and the invisible pointer }
  818. if is_class(def) then
  819. begin
  820. { Write the record class itself }
  821. tobjectdef(def).writing_class_record_dbginfo:=true;
  822. append_dwarftag(list,def);
  823. tobjectdef(def).writing_class_record_dbginfo:=false;
  824. { Write the invisible pointer class }
  825. oldtypesym:=def.typesym;
  826. def.typesym:=nil;
  827. append_dwarftag(list,def);
  828. def.typesym:=oldtypesym;
  829. end
  830. else
  831. append_dwarftag(list,def);
  832. { VMT symbol }
  833. if (oo_has_vmt in tobjectdef(def).objectoptions) and
  834. assigned(def.owner) and
  835. assigned(def.owner.name) then
  836. {
  837. list.concat(Tai_stab.create(stab_stabs,strpnew('"vmt_'+def.owner.name^+tobjectdef(def).name+':S'+
  838. def_stab_number(vmttype.def)+'",'+tostr(N_STSYM)+',0,0,'+tobjectdef(def).vmt_mangledname)));
  839. }
  840. ;
  841. end;
  842. procdef :
  843. begin
  844. { procdefs are handled separatly }
  845. end;
  846. else
  847. append_dwarftag(list,def);
  848. end;
  849. def.dbg_state := dbg_state_written;
  850. end;
  851. procedure TDebugInfoDwarf.write_symtable_defs(list:taasmoutput;st:tsymtable);
  852. procedure dowritedwarf(list:taasmoutput;st:tsymtable);
  853. var
  854. p : tdef;
  855. begin
  856. p:=tdef(st.defindex.first);
  857. while assigned(p) do
  858. begin
  859. if (p.dbg_state=dbg_state_used) then
  860. insertdef(list,p);
  861. p:=tdef(p.indexnext);
  862. end;
  863. end;
  864. var
  865. old_writing_def_dwarf : boolean;
  866. begin
  867. case st.symtabletype of
  868. staticsymtable :
  869. list.concat(tai_comment.Create(strpnew('Defs - Begin Staticsymtable')));
  870. globalsymtable :
  871. list.concat(tai_comment.Create(strpnew('Defs - Begin unit '+st.name^+' has index '+tostr(st.moduleid))));
  872. end;
  873. old_writing_def_dwarf:=writing_def_dwarf;
  874. writing_def_dwarf:=true;
  875. dowritedwarf(list,st);
  876. writing_def_dwarf:=old_writing_def_dwarf;
  877. case st.symtabletype of
  878. staticsymtable :
  879. list.concat(tai_comment.Create(strpnew('Defs - End Staticsymtable')));
  880. globalsymtable :
  881. list.concat(tai_comment.Create(strpnew('Defs - End unit '+st.name^+' has index '+tostr(st.moduleid))));
  882. end;
  883. end;
  884. procedure TDebugInfoDwarf.append_procdef(list:taasmoutput;pd:tprocdef);
  885. var
  886. procendlabel : tasmlabel;
  887. mangled_length : longint;
  888. p : pchar;
  889. hs : string;
  890. begin
  891. if assigned(pd.procstarttai) then
  892. begin
  893. append_entry(DW_TAG_subprogram,true,
  894. [DW_AT_name,DW_FORM_string,pd.procsym.name+#0
  895. { data continues below }
  896. { problem: base reg isn't known here
  897. DW_AT_frame_base,DW_FORM_block1,1
  898. }
  899. ]);
  900. { append block data }
  901. { asmlist[al_dwarf_info].concat(tai_const.create_8bit(dwarf_reg(pd.))); }
  902. if not(is_void(tprocdef(pd).rettype.def)) then
  903. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tprocdef(pd).rettype.def));
  904. { mark end of procedure }
  905. objectlibrary.getlabel(procendlabel,alt_dbgtype);
  906. asmlist[al_procedures].insertbefore(tai_label.create(procendlabel),pd.procendtai);
  907. append_labelentry(DW_AT_low_pc,objectlibrary.newasmsymbol(pd.mangledname,AB_LOCAL,AT_DATA));
  908. append_labelentry(DW_AT_high_pc,procendlabel);
  909. {
  910. if assigned(pd.funcretsym) and
  911. (tabstractnormalvarsym(pd.funcretsym).refs>0) then
  912. begin
  913. if tabstractnormalvarsym(pd.funcretsym).localloc.loc=LOC_REFERENCE then
  914. begin
  915. {$warning Need to add gdb support for ret in param register calling}
  916. if paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
  917. hs:='X*'
  918. else
  919. hs:='X';
  920. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  921. '"'+pd.procsym.name+':'+hs+def_stab_number(pd.rettype.def)+'",'+
  922. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  923. if (m_result in aktmodeswitches) then
  924. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  925. '"RESULT:'+hs+def_stab_number(pd.rettype.def)+'",'+
  926. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  927. end;
  928. end;
  929. }
  930. finish_entry;
  931. {
  932. { para types }
  933. write_def_stabstr(templist,pd);
  934. }
  935. if assigned(pd.parast) then
  936. write_symtable_syms(list,pd.parast);
  937. { local type defs and vars should not be written
  938. inside the main proc stab }
  939. if assigned(pd.localst) and
  940. (pd.localst.symtabletype=localsymtable) then
  941. write_symtable_syms(list,pd.localst);
  942. finish_children;
  943. end;
  944. end;
  945. procedure TDebugInfoDwarf.insertsym(list:taasmoutput;sym:tsym);
  946. function fieldvarsym_stabstr(sym:tfieldvarsym):Pchar;
  947. begin
  948. {
  949. result:=nil;
  950. if (sym.owner.symtabletype=objectsymtable) and
  951. (sp_static in sym.symoptions) then
  952. result:=sym_stabstr_evaluate(sym,'"${ownername}__${name}:S$1",${N_LCSYM},0,${line},${mangledname}',
  953. [def_stab_number(sym.vartype.def)]);
  954. }
  955. end;
  956. procedure append_varsym(sym:tabstractnormalvarsym);
  957. var
  958. templist : taasmoutput;
  959. blocksize : longint;
  960. regidx : longint;
  961. begin
  962. { external symbols can't be resolved at link time, so we
  963. can't generate stabs for them
  964. not sure if this applies to dwarf as well (FK)
  965. }
  966. if vo_is_external in sym.varoptions then
  967. exit;
  968. { There is no space allocated for not referenced locals }
  969. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  970. exit;
  971. templist:=taasmoutput.create;
  972. case sym.localloc.loc of
  973. LOC_REGISTER,
  974. LOC_CREGISTER,
  975. LOC_MMREGISTER,
  976. LOC_CMMREGISTER,
  977. LOC_FPUREGISTER,
  978. LOC_CFPUREGISTER :
  979. begin
  980. {
  981. regidx:=findreg_by_number(sym.localloc.register);
  982. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  983. { this is the register order for GDB}
  984. if regidx<>0 then
  985. result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  986. }
  987. end;
  988. else
  989. begin
  990. case sym.typ of
  991. globalvarsym:
  992. begin
  993. if (vo_is_thread_var in sym.varoptions) then
  994. begin
  995. {$warning !!! FIXME: dwarf for thread vars !!!}
  996. end
  997. else
  998. begin
  999. templist.concat(tai_const.create_8bit(3));
  1000. templist.concat(tai_const.createname(sym.mangledname,AT_DATA,0));
  1001. blocksize:=1+sizeof(aword);
  1002. end;
  1003. end;
  1004. localvarsym:
  1005. begin
  1006. regidx:=findreg_by_number(sym.localloc.reference.base);
  1007. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+regdwarf_table[regidx]));
  1008. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset));
  1009. blocksize:=Lengthsleb128(sym.localloc.reference.offset)+1;
  1010. end
  1011. else
  1012. internalerror(200601288);
  1013. end;
  1014. end;
  1015. end;
  1016. append_entry(DW_TAG_variable,false,[
  1017. DW_AT_name,DW_FORM_string,sym.name+#0,
  1018. {
  1019. DW_AT_decl_file,DW_FORM_data1,0,
  1020. DW_AT_decl_line,DW_FORM_data1,
  1021. }
  1022. DW_AT_external,DW_FORM_flag,true,
  1023. { data continues below }
  1024. DW_AT_location,DW_FORM_block1,blocksize
  1025. ]);
  1026. { append block data }
  1027. asmlist[al_dwarf_info].concatlist(templist);
  1028. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vartype.def));
  1029. templist.free;
  1030. finish_entry;
  1031. end;
  1032. function paravarsym_stabstr(sym:tparavarsym):Pchar;
  1033. var
  1034. st : string;
  1035. regidx : Tregisterindex;
  1036. c : char;
  1037. begin
  1038. {
  1039. result:=nil;
  1040. { set loc to LOC_REFERENCE to get somewhat usable debugging info for -Or }
  1041. { while stabs aren't adapted for regvars yet }
  1042. if (vo_is_self in sym.varoptions) then
  1043. begin
  1044. case sym.localloc.loc of
  1045. LOC_REGISTER,
  1046. LOC_CREGISTER:
  1047. regidx:=findreg_by_number(sym.localloc.register);
  1048. LOC_REFERENCE: ;
  1049. else
  1050. internalerror(2003091815);
  1051. end;
  1052. if (po_classmethod in tabstractprocdef(sym.owner.defowner).procoptions) or
  1053. (po_staticmethod in tabstractprocdef(sym.owner.defowner).procoptions) then
  1054. begin
  1055. if (sym.localloc.loc=LOC_REFERENCE) then
  1056. result:=sym_stabstr_evaluate(sym,'"pvmt:p$1",${N_TSYM},0,0,$2',
  1057. [def_stab_number(pvmttype.def),tostr(sym.localloc.reference.offset)]);
  1058. (* else
  1059. result:=sym_stabstr_evaluate(sym,'"pvmt:r$1",${N_RSYM},0,0,$2',
  1060. [def_stab_number(pvmttype.def),tostr(regstabs_table[regidx])]) *)
  1061. end
  1062. else
  1063. begin
  1064. if not(is_class(tprocdef(sym.owner.defowner)._class)) then
  1065. c:='v'
  1066. else
  1067. c:='p';
  1068. if (sym.localloc.loc=LOC_REFERENCE) then
  1069. result:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_TSYM},0,0,$2',
  1070. [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(sym.localloc.reference.offset)]);
  1071. (* else
  1072. result:=sym_stabstr_evaluate(sym,'"$$t:r$1",${N_RSYM},0,0,$2',
  1073. [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(regstabs_table[regidx])]); *)
  1074. end;
  1075. end
  1076. else
  1077. begin
  1078. st:=def_stab_number(sym.vartype.def);
  1079. if paramanager.push_addr_param(sym.varspez,sym.vartype.def,tprocdef(sym.owner.defowner).proccalloption) and
  1080. not(vo_has_local_copy in sym.varoptions) and
  1081. not is_open_string(sym.vartype.def) then
  1082. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1083. else
  1084. st := 'p'+st;
  1085. case sym.localloc.loc of
  1086. LOC_REGISTER,
  1087. LOC_CREGISTER,
  1088. LOC_MMREGISTER,
  1089. LOC_CMMREGISTER,
  1090. LOC_FPUREGISTER,
  1091. LOC_CFPUREGISTER :
  1092. begin
  1093. regidx:=findreg_by_number(sym.localloc.register);
  1094. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1095. { this is the register order for GDB}
  1096. if regidx<>0 then
  1097. result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(longint(regstabs_table[regidx]))]);
  1098. end;
  1099. LOC_REFERENCE :
  1100. { offset to ebp => will not work if the framepointer is esp
  1101. so some optimizing will make things harder to debug }
  1102. result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(sym.localloc.reference.offset)])
  1103. else
  1104. internalerror(2003091814);
  1105. end;
  1106. end;
  1107. }
  1108. end;
  1109. function constsym_stabstr(sym:tconstsym):Pchar;
  1110. var
  1111. st : string;
  1112. begin
  1113. {
  1114. case sym.consttyp of
  1115. conststring:
  1116. begin
  1117. if sym.value.len<200 then
  1118. st:='s'''+backspace_quote(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+''''
  1119. else
  1120. st:='<constant string too long>';
  1121. end;
  1122. constord:
  1123. st:='i'+tostr(sym.value.valueord);
  1124. constpointer:
  1125. st:='i'+tostr(sym.value.valueordptr);
  1126. constreal:
  1127. begin
  1128. system.str(pbestreal(sym.value.valueptr)^,st);
  1129. st := 'r'+st;
  1130. end;
  1131. else
  1132. begin
  1133. { if we don't know just put zero !! }
  1134. st:='i0';
  1135. end;
  1136. end;
  1137. { valgrind does not support constants }
  1138. if cs_gdb_valgrind in aktglobalswitches then
  1139. result:=nil
  1140. else
  1141. result:=sym_stabstr_evaluate(sym,'"${name}:c=$1;",${N_FUNCTION},0,${line},0',[st]);
  1142. }
  1143. end;
  1144. function typesym_stabstr(sym:ttypesym) : pchar;
  1145. var
  1146. stabchar : string[2];
  1147. begin
  1148. {
  1149. result:=nil;
  1150. if not assigned(sym.restype.def) then
  1151. internalerror(200509262);
  1152. if sym.restype.def.deftype in tagtypes then
  1153. stabchar:='Tt'
  1154. else
  1155. stabchar:='t';
  1156. result:=sym_stabstr_evaluate(sym,'"${name}:$1$2",${N_LSYM},0,${line},0',[stabchar,def_stab_number(sym.restype.def)]);
  1157. }
  1158. end;
  1159. procedure append_procsym(sym:tprocsym);
  1160. var
  1161. i : longint;
  1162. begin
  1163. for i:=1 to sym.procdef_count do
  1164. append_procdef(list,sym.procdef[i]);
  1165. end;
  1166. begin
  1167. case sym.typ of
  1168. globalvarsym :
  1169. append_varsym(tglobalvarsym(sym));
  1170. unitsym:
  1171. { for now, we ignore unit symbols }
  1172. ;
  1173. procsym :
  1174. append_procsym(tprocsym(sym));
  1175. {
  1176. labelsym :
  1177. stabstr:=sym_stabstr_evaluate(sym,'"${name}",${N_LSYM},0,${line},0',[]);
  1178. fieldvarsym :
  1179. stabstr:=fieldvarsym_stabstr(tfieldvarsym(sym));
  1180. }
  1181. localvarsym :
  1182. append_varsym(tlocalvarsym(sym));
  1183. {
  1184. paravarsym :
  1185. stabstr:=paravarsym_stabstr(tparavarsym(sym));
  1186. typedconstsym :
  1187. stabstr:=sym_stabstr_evaluate(sym,'"${name}:S$1",${N_STSYM},0,${line},${mangledname}',
  1188. [def_stab_number(ttypedconstsym(sym).typedconsttype.def)]);
  1189. constsym :
  1190. stabstr:=constsym_stabstr(tconstsym(sym));
  1191. }
  1192. typesym :
  1193. begin
  1194. append_entry(DW_TAG_pointer_type,false,[
  1195. DW_AT_name,DW_FORM_string,sym.name+#0
  1196. ]);
  1197. append_labelentry_ref(DW_AT_type,def_dwarf_lab(ttypesym(sym).restype.def));
  1198. end;
  1199. enumsym :
  1200. { ignore enum syms, they are written by the owner }
  1201. ;
  1202. rttisym :
  1203. { ignore rtti syms, they are only of internal use }
  1204. ;
  1205. else
  1206. internalerror(200601242);
  1207. end;
  1208. {
  1209. if stabstr<>nil then
  1210. list.concat(Tai_stab.create(stab_stabs,stabstr));
  1211. { For object types write also the symtable entries }
  1212. if (sym.typ=typesym) and (ttypesym(sym).restype.def.deftype=objectdef) then
  1213. write_symtable_syms(list,tobjectdef(ttypesym(sym).restype.def).symtable);
  1214. sym.isstabwritten:=true;
  1215. }
  1216. end;
  1217. procedure TDebugInfoDwarf.write_symtable_syms(list:taasmoutput;st:tsymtable);
  1218. var
  1219. p : tsym;
  1220. begin
  1221. case st.symtabletype of
  1222. staticsymtable :
  1223. list.concat(tai_comment.Create(strpnew('Syms - Begin Staticsymtable')));
  1224. globalsymtable :
  1225. list.concat(tai_comment.Create(strpnew('Syms - Begin unit '+st.name^+' has index '+tostr(st.moduleid))));
  1226. end;
  1227. p:=tsym(st.symindex.first);
  1228. while assigned(p) do
  1229. begin
  1230. if (not p.isstabwritten) then
  1231. insertsym(list,p);
  1232. p:=tsym(p.indexnext);
  1233. end;
  1234. case st.symtabletype of
  1235. staticsymtable :
  1236. list.concat(tai_comment.Create(strpnew('Syms - End Staticsymtable')));
  1237. globalsymtable :
  1238. list.concat(tai_comment.Create(strpnew('Syms - End unit '+st.name^+' has index '+tostr(st.moduleid))));
  1239. end;
  1240. end;
  1241. procedure TDebugInfoDwarf.insertmoduleinfo;
  1242. var
  1243. templist : taasmoutput;
  1244. begin
  1245. { insert .Ltext0 label }
  1246. templist:=taasmoutput.create;
  1247. new_section(templist,sec_code,'',0);
  1248. templist.concat(tai_symbol.createname('.Ltext0',AT_DATA,0));
  1249. asmlist[al_start].insertlist(templist);
  1250. templist.free;
  1251. { insert .Letext0 label }
  1252. templist:=taasmoutput.create;
  1253. new_section(templist,sec_code,'',0);
  1254. templist.concat(tai_symbol.createname('.Letext0',AT_DATA,0));
  1255. asmlist[al_end].insertlist(templist);
  1256. templist.free;
  1257. { insert .Ldebug_abbrev0 label }
  1258. templist:=taasmoutput.create;
  1259. new_section(templist,sec_debug_abbrev,'',0);
  1260. templist.concat(tai_symbol.createname('.Ldebug_abbrev0',AT_DATA,0));
  1261. asmlist[al_start].insertlist(templist);
  1262. templist.free;
  1263. { insert .Ldebug_line0 label }
  1264. templist:=taasmoutput.create;
  1265. new_section(templist,sec_debug_line,'',0);
  1266. templist.concat(tai_symbol.createname('.Ldebug_line0',AT_DATA,0));
  1267. asmlist[al_start].insertlist(templist);
  1268. templist.free;
  1269. end;
  1270. procedure TDebugInfoDwarf.inserttypeinfo;
  1271. var
  1272. storefilepos : tfileposinfo;
  1273. lenstartlabel : tasmlabel;
  1274. begin
  1275. storefilepos:=aktfilepos;
  1276. aktfilepos:=current_module.mainfilepos;
  1277. currabbrevnumber:=0;
  1278. writing_def_dwarf:=false;
  1279. { write start labels }
  1280. asmlist[al_dwarf_info].concat(tai_section.create(sec_debug_info,'',0));
  1281. asmlist[al_dwarf_info].concat(tai_symbol.createname('.Ldebug_info0',AT_DATA,0));
  1282. { start abbrev section }
  1283. new_section(asmlist[al_dwarf_abbrev],sec_debug_abbrev,'',0);
  1284. { debug info header }
  1285. objectlibrary.getlabel(lenstartlabel,alt_dbgfile);
  1286. { size }
  1287. asmlist[al_dwarf_info].concat(tai_const.create_rel_sym(aitconst_ptr,
  1288. lenstartlabel,tasmsymbol.create('.Ledebug_info0',AB_COMMON,AT_DATA)));
  1289. asmlist[al_dwarf_info].concat(tai_label.create(lenstartlabel));
  1290. { version }
  1291. asmlist[al_dwarf_info].concat(tai_const.create_16bit(2));
  1292. { abbrev table }
  1293. asmlist[al_dwarf_info].concat(tai_const.createname('.Ldebug_abbrev0',AT_DATA,0));
  1294. { address size }
  1295. asmlist[al_dwarf_info].concat(tai_const.create_8bit(sizeof(aint)));
  1296. append_entry(DW_TAG_compile_unit,true,[
  1297. DW_AT_name,DW_FORM_string,FixFileName(current_module.sourcefiles.get_file(1).name^)+#0,
  1298. DW_AT_producer,DW_FORM_string,'Free Pascal '+full_version_string+' '+date_string+#0,
  1299. DW_AT_comp_dir,DW_FORM_string,BsToSlash(FixPath(current_module.sourcefiles.get_file(1).path^,false))+#0,
  1300. DW_AT_language,DW_FORM_data1,DW_LANG_Pascal83,
  1301. DW_AT_identifier_case,DW_FORM_data1,DW_ID_case_insensitive]);
  1302. { reference to line info section }
  1303. append_labelentry_data(DW_AT_stmt_list,objectlibrary.newasmsymbol('.Ldebug_line0',AB_LOCAL,AT_DATA));
  1304. append_labelentry(DW_AT_low_pc,objectlibrary.newasmsymbol('.Ltext0',AB_LOCAL,AT_DATA));
  1305. append_labelentry(DW_AT_high_pc,objectlibrary.newasmsymbol('.Letext0',AB_LOCAL,AT_DATA));
  1306. finish_entry;
  1307. { first write all global/local symbols. This will flag all required tdefs }
  1308. if assigned(current_module.globalsymtable) then
  1309. write_symtable_syms(asmlist[al_dwarf_info],current_module.globalsymtable);
  1310. if assigned(current_module.localsymtable) then
  1311. write_symtable_syms(asmlist[al_dwarf_info],current_module.localsymtable);
  1312. { reset unit type info flag }
  1313. reset_unit_type_info;
  1314. { write used types from the used units }
  1315. write_used_unit_type_info(asmlist[al_dwarf_info],current_module);
  1316. { last write the types from this unit }
  1317. if assigned(current_module.globalsymtable) then
  1318. write_symtable_defs(asmlist[al_dwarf_info],current_module.globalsymtable);
  1319. if assigned(current_module.localsymtable) then
  1320. write_symtable_defs(asmlist[al_dwarf_info],current_module.localsymtable);
  1321. { close compilation unit entry }
  1322. finish_children;
  1323. { end of debug info table }
  1324. asmlist[al_dwarf_info].concat(tai_const.create_8bit(0));
  1325. asmlist[al_dwarf_info].concat(tai_symbol.createname('.Ledebug_info0',AT_DATA,0));
  1326. aktfilepos:=storefilepos;
  1327. end;
  1328. procedure TDebugInfoDwarf.referencesections(list:taasmoutput);
  1329. begin
  1330. end;
  1331. procedure TDebugInfoDwarf.insertlineinfo(list:taasmoutput);
  1332. var
  1333. currfileinfo,
  1334. lastfileinfo : tfileposinfo;
  1335. currfuncname : pstring;
  1336. currsectype : tasmsectiontype;
  1337. hlabel : tasmlabel;
  1338. hp : tai;
  1339. infile : tinputfile;
  1340. begin
  1341. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  1342. currfuncname:=nil;
  1343. currsectype:=sec_code;
  1344. hp:=Tai(list.first);
  1345. while assigned(hp) do
  1346. begin
  1347. case hp.typ of
  1348. ait_section :
  1349. currsectype:=tai_section(hp).sectype;
  1350. ait_function_name :
  1351. currfuncname:=tai_function_name(hp).funcname;
  1352. ait_force_line :
  1353. lastfileinfo.line:=-1;
  1354. end;
  1355. if (currsectype=sec_code) and
  1356. (hp.typ=ait_instruction) then
  1357. begin
  1358. currfileinfo:=tailineinfo(hp).fileinfo;
  1359. { file changed ? (must be before line info) }
  1360. if (currfileinfo.fileindex<>0) and
  1361. (lastfileinfo.fileindex<>currfileinfo.fileindex) then
  1362. begin
  1363. infile:=current_module.sourcefiles.get_file(currfileinfo.fileindex);
  1364. if assigned(infile) then
  1365. begin
  1366. inc(currfileidx);
  1367. if (infile.path^<>'') then
  1368. list.insertbefore(tai_file.create(
  1369. BsToSlash(FixPath(infile.path^,false)+FixFileName(infile.name^)),currfileidx
  1370. ),hp)
  1371. else
  1372. list.insertbefore(tai_file.create(
  1373. FixFileName(infile.name^),currfileidx),hp);
  1374. { force new line info }
  1375. lastfileinfo.line:=-1;
  1376. end;
  1377. end;
  1378. { line changed ? }
  1379. if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
  1380. list.insertbefore(tai_loc.create(
  1381. currfileidx,currfileinfo.line,currfileinfo.column),hp);
  1382. lastfileinfo:=currfileinfo;
  1383. end;
  1384. hp:=tai(hp.next);
  1385. end;
  1386. end;
  1387. const
  1388. dbg_dwarf_info : tdbginfo =
  1389. (
  1390. id : dbg_dwarf;
  1391. idtxt : 'DWARF';
  1392. );
  1393. initialization
  1394. RegisterDebugInfo(dbg_dwarf_info,TDebugInfoDwarf);
  1395. end.