1 /* 2 * DWARF2 debugging format - info and abbreviation tables 3 * 4 * Copyright (C) 2006-2007 Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <util.h> 28 29 #include <libyasm.h> 30 31 #include "dwarf2-dbgfmt.h" 32 33 #define DW_LANG_Mips_Assembler 0x8001 34 35 /* Tag encodings */ 36 typedef enum { 37 DW_TAG_padding = 0x00, 38 DW_TAG_array_type = 0x01, 39 DW_TAG_class_type = 0x02, 40 DW_TAG_entry_point = 0x03, 41 DW_TAG_enumeration_type = 0x04, 42 DW_TAG_formal_parameter = 0x05, 43 DW_TAG_imported_declaration = 0x08, 44 DW_TAG_label = 0x0a, 45 DW_TAG_lexical_block = 0x0b, 46 DW_TAG_member = 0x0d, 47 DW_TAG_pointer_type = 0x0f, 48 DW_TAG_reference_type = 0x10, 49 DW_TAG_compile_unit = 0x11, 50 DW_TAG_string_type = 0x12, 51 DW_TAG_structure_type = 0x13, 52 DW_TAG_subroutine_type = 0x15, 53 DW_TAG_typedef = 0x16, 54 DW_TAG_union_type = 0x17, 55 DW_TAG_unspecified_parameters = 0x18, 56 DW_TAG_variant = 0x19, 57 DW_TAG_common_block = 0x1a, 58 DW_TAG_common_inclusion = 0x1b, 59 DW_TAG_inheritance = 0x1c, 60 DW_TAG_inlined_subroutine = 0x1d, 61 DW_TAG_module = 0x1e, 62 DW_TAG_ptr_to_member_type = 0x1f, 63 DW_TAG_set_type = 0x20, 64 DW_TAG_subrange_type = 0x21, 65 DW_TAG_with_stmt = 0x22, 66 DW_TAG_access_declaration = 0x23, 67 DW_TAG_base_type = 0x24, 68 DW_TAG_catch_block = 0x25, 69 DW_TAG_const_type = 0x26, 70 DW_TAG_constant = 0x27, 71 DW_TAG_enumerator = 0x28, 72 DW_TAG_file_type = 0x29, 73 DW_TAG_friend = 0x2a, 74 DW_TAG_namelist = 0x2b, 75 DW_TAG_namelist_item = 0x2c, 76 DW_TAG_packed_type = 0x2d, 77 DW_TAG_subprogram = 0x2e, 78 DW_TAG_template_type_param = 0x2f, 79 DW_TAG_template_value_param = 0x30, 80 DW_TAG_thrown_type = 0x31, 81 DW_TAG_try_block = 0x32, 82 DW_TAG_variant_part = 0x33, 83 DW_TAG_variable = 0x34, 84 DW_TAG_volatile_type = 0x35 85 } dwarf_tag; 86 87 /* Attribute form encodings */ 88 typedef enum { 89 DW_FORM_addr = 0x01, 90 DW_FORM_block2 = 0x03, 91 DW_FORM_block4 = 0x04, 92 DW_FORM_data2 = 0x05, 93 DW_FORM_data4 = 0x06, 94 DW_FORM_data8 = 0x07, 95 DW_FORM_string = 0x08, 96 DW_FORM_block = 0x09, 97 DW_FORM_block1 = 0x0a, 98 DW_FORM_data1 = 0x0b, 99 DW_FORM_flag = 0x0c, 100 DW_FORM_sdata = 0x0d, 101 DW_FORM_strp = 0x0e, 102 DW_FORM_udata = 0x0f, 103 DW_FORM_ref_addr = 0x10, 104 DW_FORM_ref1 = 0x11, 105 DW_FORM_ref2 = 0x12, 106 DW_FORM_ref4 = 0x13, 107 DW_FORM_ref8 = 0x14, 108 DW_FORM_ref_udata = 0x15, 109 DW_FORM_indirect = 0x16 110 } dwarf_form; 111 112 /* Attribute encodings */ 113 typedef enum { 114 DW_AT_sibling = 0x01, 115 DW_AT_location = 0x02, 116 DW_AT_name = 0x03, 117 DW_AT_ordering = 0x09, 118 DW_AT_subscr_data = 0x0a, 119 DW_AT_byte_size = 0x0b, 120 DW_AT_bit_offset = 0x0c, 121 DW_AT_bit_size = 0x0d, 122 DW_AT_element_list = 0x0f, 123 DW_AT_stmt_list = 0x10, 124 DW_AT_low_pc = 0x11, 125 DW_AT_high_pc = 0x12, 126 DW_AT_language = 0x13, 127 DW_AT_member = 0x14, 128 DW_AT_discr = 0x15, 129 DW_AT_discr_value = 0x16, 130 DW_AT_visibility = 0x17, 131 DW_AT_import = 0x18, 132 DW_AT_string_length = 0x19, 133 DW_AT_common_reference = 0x1a, 134 DW_AT_comp_dir = 0x1b, 135 DW_AT_const_value = 0x1c, 136 DW_AT_containing_type = 0x1d, 137 DW_AT_default_value = 0x1e, 138 DW_AT_inline = 0x20, 139 DW_AT_is_optional = 0x21, 140 DW_AT_lower_bound = 0x22, 141 DW_AT_producer = 0x25, 142 DW_AT_prototyped = 0x27, 143 DW_AT_return_addr = 0x2a, 144 DW_AT_start_scope = 0x2c, 145 DW_AT_stride_size = 0x2e, 146 DW_AT_upper_bound = 0x2f, 147 DW_AT_abstract_origin = 0x31, 148 DW_AT_accessibility = 0x32, 149 DW_AT_address_class = 0x33, 150 DW_AT_artificial = 0x34, 151 DW_AT_base_types = 0x35, 152 DW_AT_calling_convention = 0x36, 153 DW_AT_count = 0x37, 154 DW_AT_data_member_location = 0x38, 155 DW_AT_decl_column = 0x39, 156 DW_AT_decl_file = 0x3a, 157 DW_AT_decl_line = 0x3b, 158 DW_AT_declaration = 0x3c, 159 DW_AT_discr_list = 0x3d, 160 DW_AT_encoding = 0x3e, 161 DW_AT_external = 0x3f, 162 DW_AT_frame_base = 0x40, 163 DW_AT_friend = 0x41, 164 DW_AT_identifier_case = 0x42, 165 DW_AT_macro_info = 0x43, 166 DW_AT_namelist_items = 0x44, 167 DW_AT_priority = 0x45, 168 DW_AT_segment = 0x46, 169 DW_AT_specification = 0x47, 170 DW_AT_static_link = 0x48, 171 DW_AT_type = 0x49, 172 DW_AT_use_location = 0x4a, 173 DW_AT_variable_parameter = 0x4b, 174 DW_AT_virtuality = 0x4c, 175 DW_AT_vtable_elem_location = 0x4d 176 } dwarf_attribute; 177 178 typedef struct dwarf2_abbrev_attr { 179 STAILQ_ENTRY(dwarf2_abbrev_attr) link; 180 dwarf_attribute name; 181 dwarf_form form; 182 } dwarf2_abbrev_attr; 183 184 typedef struct dwarf2_abbrev { 185 unsigned long id; 186 dwarf_tag tag; 187 int has_children; 188 STAILQ_HEAD(dwarf2_abbrev_attrhead, dwarf2_abbrev_attr) attrs; 189 } dwarf2_abbrev; 190 191 /* Bytecode callback function prototypes */ 192 193 static void dwarf2_abbrev_bc_destroy(void *contents); 194 static void dwarf2_abbrev_bc_print(const void *contents, FILE *f, 195 int indent_level); 196 static int dwarf2_abbrev_bc_calc_len 197 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); 198 static int dwarf2_abbrev_bc_tobytes 199 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, 200 yasm_output_value_func output_value, 201 /*@null@*/ yasm_output_reloc_func output_reloc); 202 203 /* Bytecode callback structures */ 204 205 static const yasm_bytecode_callback dwarf2_abbrev_bc_callback = { 206 dwarf2_abbrev_bc_destroy, 207 dwarf2_abbrev_bc_print, 208 yasm_bc_finalize_common, 209 NULL, 210 dwarf2_abbrev_bc_calc_len, 211 yasm_bc_expand_common, 212 dwarf2_abbrev_bc_tobytes, 213 0 214 }; 215 216 217 static unsigned long 218 dwarf2_add_abbrev_attr(dwarf2_abbrev *abbrev, dwarf_attribute name, 219 dwarf_form form) 220 { 221 dwarf2_abbrev_attr *attr = yasm_xmalloc(sizeof(dwarf2_abbrev_attr)); 222 attr->name = name; 223 attr->form = form; 224 STAILQ_INSERT_TAIL(&abbrev->attrs, attr, link); 225 return yasm_size_uleb128(name) + yasm_size_uleb128(form); 226 } 227 228 static void 229 dwarf2_append_expr(yasm_section *sect, /*@only@*/ yasm_expr *expr, 230 unsigned int size, int leb) 231 { 232 yasm_datavalhead dvs; 233 yasm_bytecode *bc; 234 235 yasm_dvs_initialize(&dvs); 236 yasm_dvs_append(&dvs, yasm_dv_create_expr(expr)); 237 if (leb == 0) 238 bc = yasm_bc_create_data(&dvs, size, 0, NULL, 0); 239 else 240 bc = yasm_bc_create_leb128(&dvs, leb<0, 0); 241 yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc)); 242 yasm_bc_calc_len(bc, NULL, NULL); 243 } 244 245 static void 246 dwarf2_append_str(yasm_section *sect, const char *str) 247 { 248 yasm_datavalhead dvs; 249 yasm_bytecode *bc; 250 251 yasm_dvs_initialize(&dvs); 252 yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str), 253 strlen(str))); 254 bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0); 255 yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc)); 256 yasm_bc_calc_len(bc, NULL, NULL); 257 } 258 259 yasm_section * 260 yasm_dwarf2__generate_info(yasm_object *object, yasm_section *debug_line, 261 yasm_section *main_code) 262 { 263 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; 264 int new; 265 yasm_bytecode *abc; 266 dwarf2_abbrev *abbrev; 267 dwarf2_head *head; 268 char *buf; 269 yasm_section *debug_abbrev = 270 yasm_object_get_general(object, ".debug_abbrev", 4, 0, 0, &new, 0); 271 yasm_section *debug_info = 272 yasm_object_get_general(object, ".debug_info", 4, 0, 0, &new, 0); 273 274 yasm_section_set_align(debug_abbrev, 0, 0); 275 yasm_section_set_align(debug_info, 0, 0); 276 277 /* Create abbreviation table entry for compilation unit */ 278 abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev)); 279 abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0); 280 abbrev->id = 1; 281 abbrev->tag = DW_TAG_compile_unit; 282 abbrev->has_children = 0; 283 abc->len = yasm_size_uleb128(abbrev->id) + yasm_size_uleb128(abbrev->tag) 284 + 3; 285 STAILQ_INIT(&abbrev->attrs); 286 yasm_dwarf2__append_bc(debug_abbrev, abc); 287 288 /* info header */ 289 head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_info, debug_abbrev, 1, 0); 290 291 /* Generate abbreviations at the same time as info (since they're linked 292 * and we're only generating one piece of info). 293 */ 294 295 /* generating info using abbrev 1 */ 296 dwarf2_append_expr(debug_info, 297 yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(1)), 0), 298 0, 1); 299 300 /* statement list (line numbers) */ 301 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_stmt_list, DW_FORM_data4); 302 dwarf2_append_expr(debug_info, 303 yasm_expr_create_ident(yasm_expr_sym( 304 yasm_dwarf2__bc_sym(object->symtab, 305 yasm_section_bcs_first(debug_line))), 0), 306 dbgfmt_dwarf2->sizeof_offset, 0); 307 308 if (main_code) { 309 yasm_symrec *first; 310 first = yasm_dwarf2__bc_sym(object->symtab, 311 yasm_section_bcs_first(main_code)); 312 /* All code is contiguous in one section */ 313 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_low_pc, DW_FORM_addr); 314 dwarf2_append_expr(debug_info, 315 yasm_expr_create_ident(yasm_expr_sym(first), 0), 316 dbgfmt_dwarf2->sizeof_address, 0); 317 318 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_high_pc, DW_FORM_addr); 319 dwarf2_append_expr(debug_info, 320 yasm_expr_create(YASM_EXPR_ADD, yasm_expr_sym(first), 321 yasm_expr_int(yasm_calc_bc_dist( 322 yasm_section_bcs_first(main_code), 323 yasm_section_bcs_last(main_code))), 0), 324 dbgfmt_dwarf2->sizeof_address, 0); 325 } 326 327 /* input filename */ 328 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_name, DW_FORM_string); 329 dwarf2_append_str(debug_info, object->src_filename); 330 331 /* compile directory (current working directory) */ 332 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_comp_dir, DW_FORM_string); 333 buf = yasm__getcwd(); 334 dwarf2_append_str(debug_info, buf); 335 yasm_xfree(buf); 336 337 /* producer - assembler name */ 338 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_producer, DW_FORM_string); 339 if (getenv("YASM_TEST_SUITE")) 340 dwarf2_append_str(debug_info, "yasm HEAD"); 341 else 342 dwarf2_append_str(debug_info, PACKAGE_STRING); 343 344 /* language - no standard code for assembler, use MIPS as a substitute */ 345 abc->len += dwarf2_add_abbrev_attr(abbrev, DW_AT_language, DW_FORM_data2); 346 dwarf2_append_expr(debug_info, 347 yasm_expr_create_ident(yasm_expr_int( 348 yasm_intnum_create_uint(DW_LANG_Mips_Assembler)), 0), 2, 0); 349 350 /* Terminate list of abbreviations */ 351 abbrev = yasm_xmalloc(sizeof(dwarf2_abbrev)); 352 abc = yasm_bc_create_common(&dwarf2_abbrev_bc_callback, abbrev, 0); 353 abbrev->id = 0; 354 abbrev->tag = 0; 355 abbrev->has_children = 0; 356 STAILQ_INIT(&abbrev->attrs); 357 abc->len = 1; 358 yasm_dwarf2__append_bc(debug_abbrev, abc); 359 360 /* mark end of info */ 361 yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_info)); 362 363 return debug_info; 364 } 365 366 static void 367 dwarf2_abbrev_bc_destroy(void *contents) 368 { 369 dwarf2_abbrev *abbrev = (dwarf2_abbrev *)contents; 370 dwarf2_abbrev_attr *n1, *n2; 371 372 /* Delete attributes */ 373 n1 = STAILQ_FIRST(&abbrev->attrs); 374 while (n1) { 375 n2 = STAILQ_NEXT(n1, link); 376 yasm_xfree(n1); 377 n1 = n2; 378 } 379 380 yasm_xfree(contents); 381 } 382 383 static void 384 dwarf2_abbrev_bc_print(const void *contents, FILE *f, int indent_level) 385 { 386 /* TODO */ 387 } 388 389 static int 390 dwarf2_abbrev_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 391 void *add_span_data) 392 { 393 yasm_internal_error(N_("tried to calc_len a dwarf2 aranges head bytecode")); 394 /*@notreached@*/ 395 return 0; 396 } 397 398 static int 399 dwarf2_abbrev_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, 400 unsigned char *bufstart, void *d, 401 yasm_output_value_func output_value, 402 yasm_output_reloc_func output_reloc) 403 { 404 dwarf2_abbrev *abbrev = (dwarf2_abbrev *)bc->contents; 405 unsigned char *buf = *bufp; 406 dwarf2_abbrev_attr *attr; 407 408 if (abbrev->id == 0) { 409 YASM_WRITE_8(buf, 0); 410 *bufp = buf; 411 return 0; 412 } 413 414 buf += yasm_get_uleb128(abbrev->id, buf); 415 buf += yasm_get_uleb128(abbrev->tag, buf); 416 YASM_WRITE_8(buf, abbrev->has_children); 417 418 STAILQ_FOREACH(attr, &abbrev->attrs, link) { 419 buf += yasm_get_uleb128(attr->name, buf); 420 buf += yasm_get_uleb128(attr->form, buf); 421 } 422 423 YASM_WRITE_8(buf, 0); 424 YASM_WRITE_8(buf, 0); 425 426 *bufp = buf; 427 return 0; 428 } 429 430