dbgdwarf.pas 65 KB

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