static void out_debug_aranges (segT aranges_seg, segT info_seg) { unsigned int addr_size = sizeof_address; struct line_seg *s; expressionS exp; symbolS *aranges_end; char *p; int sizeof_offset; sizeof_offset = out_header (aranges_seg, &exp); aranges_end = exp.X_add_symbol; /* Version. */ out_two (DWARF2_VERSION); /* Offset to .debug_info. */ TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), sizeof_offset); /* Size of an address (offset portion). */ out_byte (addr_size); /* Size of a segment descriptor. */ out_byte (0); /* Align the header. */ frag_align (ffs (2 * addr_size) - 1, 0, 0); for (s = all_segs; s; s = s->next) { fragS *frag; symbolS *beg, *end; frag = first_frag_for_seg (s->seg); beg = symbol_temp_new (s->seg, 0, frag); s->text_start = beg; frag = last_frag_for_seg (s->seg); end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag); s->text_end = end; exp.X_op = O_symbol; exp.X_add_symbol = beg; exp.X_add_number = 0; emit_expr (&exp, addr_size); exp.X_op = O_subtract; exp.X_add_symbol = end; exp.X_op_symbol = beg; exp.X_add_number = 0; emit_expr (&exp, addr_size); } p = frag_more (2 * addr_size); md_number_to_chars (p, 0, addr_size); md_number_to_chars (p + addr_size, 0, addr_size); symbol_set_value_now (aranges_end); }
static void out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg) { char producer[128]; const char *comp_dir; const char *dirname; expressionS exp; symbolS *info_end; char *p; int len; int sizeof_offset; sizeof_offset = out_header (info_seg, &exp); info_end = exp.X_add_symbol; /* DWARF version. */ out_two (DWARF2_VERSION); /* .debug_abbrev offset */ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); /* Target address size. */ out_byte (sizeof_address); /* DW_TAG_compile_unit DIE abbrev */ out_uleb128 (1); /* DW_AT_stmt_list */ TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), (DWARF2_FORMAT (line_seg) == dwarf2_format_32bit ? 4 : 8)); /* These two attributes are emitted if all of the code is contiguous. */ if (all_segs->next == NULL) { /* DW_AT_low_pc */ exp.X_op = O_symbol; exp.X_add_symbol = all_segs->text_start; exp.X_add_number = 0; emit_expr (&exp, sizeof_address); /* DW_AT_high_pc */ exp.X_op = O_symbol; exp.X_add_symbol = all_segs->text_end; exp.X_add_number = 0; emit_expr (&exp, sizeof_address); } else { /* This attribute is emitted if the code is disjoint. */ /* DW_AT_ranges. */ TC_DWARF2_EMIT_OFFSET (section_symbol (ranges_seg), sizeof_offset); } /* DW_AT_name. We don't have the actual file name that was present on the command line, so assume files[1] is the main input file. We're not supposed to get called unless at least one line number entry was emitted, so this should always be defined. */ if (files_in_use == 0) abort (); if (files[1].dir) { dirname = remap_debug_filename (dirs[files[1].dir]); len = strlen (dirname); #ifdef TE_VMS /* Already has trailing slash. */ p = frag_more (len); memcpy (p, dirname, len); #else p = frag_more (len + 1); memcpy (p, dirname, len); INSERT_DIR_SEPARATOR (p, len); #endif } len = strlen (files[1].filename) + 1; p = frag_more (len); memcpy (p, files[1].filename, len); /* DW_AT_comp_dir */ comp_dir = remap_debug_filename (getpwd ()); len = strlen (comp_dir) + 1; p = frag_more (len); memcpy (p, comp_dir, len); /* DW_AT_producer */ sprintf (producer, "GNU AS %s", VERSION); len = strlen (producer) + 1; p = frag_more (len); memcpy (p, producer, len); /* DW_AT_language. Yes, this is probably not really MIPS, but the dwarf2 draft has no standard code for assembler. */ out_two (DW_LANG_Mips_Assembler); symbol_set_value_now (info_end); }
static void out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg) { char producer[128]; char *comp_dir; expressionS expr; symbolS *info_start; symbolS *info_end; char *p; int len; enum dwarf2_format d2f; int sizeof_offset; subseg_set (info_seg, 0); info_start = symbol_temp_new_now (); info_end = symbol_temp_make (); /* Compilation Unit length. */ expr.X_op = O_subtract; expr.X_add_symbol = info_end; expr.X_op_symbol = info_start; d2f = DWARF2_FORMAT (); if (d2f == dwarf2_format_32bit) { expr.X_add_number = -4; emit_expr (&expr, 4); sizeof_offset = 4; } else if (d2f == dwarf2_format_64bit) { expr.X_add_number = -12; out_four (-1); emit_expr (&expr, 8); sizeof_offset = 8; } else if (d2f == dwarf2_format_64bit_irix) { expr.X_add_number = -8; emit_expr (&expr, 8); sizeof_offset = 8; } else { as_fatal (_("internal error: unknown dwarf2 format")); } /* DWARF version. */ out_two (2); /* .debug_abbrev offset */ TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); /* Target address size. */ out_byte (sizeof_address); /* DW_TAG_compile_unit DIE abbrev */ out_uleb128 (1); /* DW_AT_stmt_list */ /* ??? sizeof_offset */ TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), 4); /* These two attributes may only be emitted if all of the code is contiguous. Multiple sections are not that. */ if (all_segs->next == NULL) { /* DW_AT_low_pc */ expr.X_op = O_symbol; expr.X_add_symbol = all_segs->text_start; expr.X_add_number = 0; emit_expr (&expr, sizeof_address); /* DW_AT_high_pc */ expr.X_op = O_symbol; expr.X_add_symbol = all_segs->text_end; expr.X_add_number = 0; emit_expr (&expr, sizeof_address); } /* DW_AT_name. We don't have the actual file name that was present on the command line, so assume files[1] is the main input file. We're not supposed to get called unless at least one line number entry was emitted, so this should always be defined. */ if (!files || files_in_use < 1) abort (); if (files[1].dir) { len = strlen (dirs[files[1].dir]); p = frag_more (len + 1); memcpy (p, dirs[files[1].dir], len); p[len] = '/'; } len = strlen (files[1].filename) + 1; p = frag_more (len); memcpy (p, files[1].filename, len); /* DW_AT_comp_dir */ comp_dir = getpwd (); len = strlen (comp_dir) + 1; p = frag_more (len); memcpy (p, comp_dir, len); /* DW_AT_producer */ sprintf (producer, "GNU AS %s", VERSION); len = strlen (producer) + 1; p = frag_more (len); memcpy (p, producer, len); /* DW_AT_language. Yes, this is probably not really MIPS, but the dwarf2 draft has no standard code for assembler. */ out_two (DW_LANG_Mips_Assembler); symbol_set_value_now (info_end); }
static void out_debug_aranges (segT aranges_seg, segT info_seg) { unsigned int addr_size = sizeof_address; addressT size, skip; struct line_seg *s; expressionS expr; char *p; size = 4 + 2 + 4 + 1 + 1; skip = 2 * addr_size - (size & (2 * addr_size - 1)); if (skip == 2 * addr_size) skip = 0; size += skip; for (s = all_segs; s; s = s->next) size += 2 * addr_size; size += 2 * addr_size; subseg_set (aranges_seg, 0); /* Length of the compilation unit. */ out_four (size - 4); /* Version. */ out_two (2); /* Offset to .debug_info. */ /* ??? sizeof_offset */ TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), 4); /* Size of an address (offset portion). */ out_byte (addr_size); /* Size of a segment descriptor. */ out_byte (0); /* Align the header. */ if (skip) frag_align (ffs (2 * addr_size) - 1, 0, 0); for (s = all_segs; s; s = s->next) { fragS *frag; symbolS *beg, *end; frag = first_frag_for_seg (s->seg); beg = symbol_temp_new (s->seg, 0, frag); s->text_start = beg; frag = last_frag_for_seg (s->seg); end = symbol_temp_new (s->seg, get_frag_fix (frag), frag); s->text_end = end; expr.X_op = O_symbol; expr.X_add_symbol = beg; expr.X_add_number = 0; emit_expr (&expr, addr_size); expr.X_op = O_subtract; expr.X_add_symbol = end; expr.X_op_symbol = beg; expr.X_add_number = 0; emit_expr (&expr, addr_size); } p = frag_more (2 * addr_size); md_number_to_chars (p, 0, addr_size); md_number_to_chars (p + addr_size, 0, addr_size); }