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_ranges (segT ranges_seg) { unsigned int addr_size = sizeof_address; struct line_seg *s; expressionS exp; unsigned int i; subseg_set (ranges_seg, 0); /* Base Address Entry. */ for (i = 0; i < addr_size; i++) out_byte (0xff); for (i = 0; i < addr_size; i++) out_byte (0); /* Range List Entry. */ 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_symbol; exp.X_add_symbol = end; exp.X_add_number = 0; emit_expr (&exp, addr_size); } /* End of Range Entry. */ for (i = 0; i < addr_size; i++) out_byte (0); for (i = 0; i < addr_size; i++) out_byte (0); }
static void process_entries (segT seg, struct line_entry *e) { unsigned filenum = 1; unsigned line = 1; unsigned column = 0; unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_BEGIN_STMT : 0; fragS *frag = NULL; fragS *last_frag; addressT frag_ofs = 0; addressT last_frag_ofs; struct line_entry *next; while (e) { int changed = 0; if (filenum != e->loc.filenum) { filenum = e->loc.filenum; out_opcode (DW_LNS_set_file); out_uleb128 (filenum); changed = 1; } if (column != e->loc.column) { column = e->loc.column; out_opcode (DW_LNS_set_column); out_uleb128 (column); changed = 1; } if ((e->loc.flags ^ flags) & DWARF2_FLAG_BEGIN_STMT) { flags = e->loc.flags; out_opcode (DW_LNS_negate_stmt); changed = 1; } if (e->loc.flags & DWARF2_FLAG_BEGIN_BLOCK) { out_opcode (DW_LNS_set_basic_block); changed = 1; } /* Don't try to optimize away redundant entries; gdb wants two entries for a function where the code starts on the same line as the {, and there's no way to identify that case here. Trust gcc to optimize appropriately. */ if (1 /* line != e->loc.line || changed */) { int line_delta = e->loc.line - line; if (frag == NULL) { out_set_addr (seg, e->frag, e->frag_ofs); out_inc_line_addr (line_delta, 0); } else if (frag == e->frag) out_inc_line_addr (line_delta, e->frag_ofs - frag_ofs); else relax_inc_line_addr (line_delta, seg, e->frag, e->frag_ofs, frag, frag_ofs); frag = e->frag; frag_ofs = e->frag_ofs; line = e->loc.line; } else if (frag == NULL) { out_set_addr (seg, e->frag, e->frag_ofs); frag = e->frag; frag_ofs = e->frag_ofs; } next = e->next; free (e); e = next; } /* Emit a DW_LNE_end_sequence for the end of the section. */ last_frag = last_frag_for_seg (seg); last_frag_ofs = get_frag_fix (last_frag); if (frag == last_frag) out_inc_line_addr (INT_MAX, last_frag_ofs - frag_ofs); else relax_inc_line_addr (INT_MAX, seg, last_frag, last_frag_ofs, frag, frag_ofs); }
static void process_entries (segT seg, struct line_entry *e) { unsigned filenum = 1; unsigned line = 1; unsigned column = 0; unsigned isa = 0; unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; fragS *last_frag = NULL, *frag; addressT last_frag_ofs = 0, frag_ofs; symbolS *last_lab = NULL, *lab; struct line_entry *next; do { int line_delta; if (filenum != e->loc.filenum) { filenum = e->loc.filenum; out_opcode (DW_LNS_set_file); out_uleb128 (filenum); } if (column != e->loc.column) { column = e->loc.column; out_opcode (DW_LNS_set_column); out_uleb128 (column); } if (e->loc.discriminator != 0) { out_opcode (DW_LNS_extended_op); out_leb128 (1 + sizeof_leb128 (e->loc.discriminator, 0)); out_opcode (DW_LNE_set_discriminator); out_uleb128 (e->loc.discriminator); } if (isa != e->loc.isa) { isa = e->loc.isa; out_opcode (DW_LNS_set_isa); out_uleb128 (isa); } if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT) { flags = e->loc.flags; out_opcode (DW_LNS_negate_stmt); } if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK) out_opcode (DW_LNS_set_basic_block); if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END) out_opcode (DW_LNS_set_prologue_end); if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN) out_opcode (DW_LNS_set_epilogue_begin); /* Don't try to optimize away redundant entries; gdb wants two entries for a function where the code starts on the same line as the {, and there's no way to identify that case here. Trust gcc to optimize appropriately. */ line_delta = e->loc.line - line; lab = e->label; frag = symbol_get_frag (lab); frag_ofs = S_GET_VALUE (lab); if (last_frag == NULL) { out_set_addr (lab); out_inc_line_addr (line_delta, 0); } else if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC) out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs); else relax_inc_line_addr (line_delta, lab, last_lab); line = e->loc.line; last_lab = lab; last_frag = frag; last_frag_ofs = frag_ofs; next = e->next; free (e); e = next; } while (e); /* Emit a DW_LNE_end_sequence for the end of the section. */ frag = last_frag_for_seg (seg); frag_ofs = get_frag_fix (frag, seg); if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC) out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs); else { lab = symbol_temp_new (seg, frag_ofs, frag); relax_inc_line_addr (INT_MAX, lab, last_lab); } }
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); }