dbgdwarf.pas 77 KB

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