From 274e1fa43c8b1d1dbbecaee1a98405c6ee40c5ba Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 3 Feb 2006 06:38:30 +0000 Subject: [PATCH] * dwarf2-dbgfmt.c (generate_section): Split off large chunks into gen_line_op and finalize_locs functions, preparing for later asm-source dbg generation. svn path=/trunk/yasm/; revision=1357 --- modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c | 292 ++++++++++++++----------- 1 file changed, 161 insertions(+), 131 deletions(-) diff --git a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c index a5fc92d3..25556ab6 100644 --- a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c +++ b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c @@ -149,6 +149,23 @@ typedef struct dwarf2_loc { yasm_symrec *sym; /* last symbol preceding */ } dwarf2_loc; +/* Line number state machine register state */ +typedef struct dwarf2_line_state { + /* static configuration */ + yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; + + /* DWARF2 state machine registers */ + unsigned long address; + unsigned long file; + unsigned long line; + unsigned long column; + unsigned long isa; + int is_stmt; + + /* other state information */ + /*@null@*/ yasm_bytecode *precbc; +} dwarf2_line_state; + /* Per-section data */ typedef struct dwarf2_section_data { /* The locations set by the .loc directives in this section, in assembly @@ -355,28 +372,12 @@ dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect, return bc; } -static int -dwarf2_dbgfmt_generate_section(yasm_section *sect, /*@null@*/ void *d) +static void +dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd) { - dwarf2_info *info = (dwarf2_info *)d; - yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; - /*@null@*/ dwarf2_section_data *dsd; - /*@null@*/ dwarf2_loc *loc; - /*@null@*/ yasm_bytecode *precbc = NULL, *bc; /*@dependent@*/ yasm_symrec *lastsym = NULL; - unsigned long addr_delta; - - /* registers for state machine for each sequence */ - unsigned long address = 0; - unsigned long file = 1; - unsigned long line = 1; - unsigned long column = 0; - unsigned long isa = 0; - int is_stmt = DWARF2_LINE_DEFAULT_IS_STMT; - - dsd = yasm_section_get_data(sect, &dwarf2_section_data_cb); - if (!dsd) - return 0; /* no line data for this section */ + /*@null@*/ yasm_bytecode *bc; + /*@null@*/ dwarf2_loc *loc; bc = yasm_section_bcs_first(sect); STAILQ_FOREACH(loc, &dsd->locs, link) { @@ -401,128 +402,157 @@ dwarf2_dbgfmt_generate_section(yasm_section *sect, /*@null@*/ void *d) loc->sym = lastsym; loc->bc = bc; } +} - STAILQ_FOREACH(loc, &dsd->locs, link) { - long line_delta; - int opcode1, opcode2; - - if (file != loc->file) { - file = loc->file; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_set_file, - yasm_intnum_create_uint(file)); - } - if (column != loc->column) { - column = loc->column; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_set_column, - yasm_intnum_create_uint(column)); - } +static int +dwarf2_dbgfmt_gen_line_op(yasm_section *debug_line, dwarf2_line_state *state, + dwarf2_loc *loc, /*@null@*/ dwarf2_loc *nextloc) +{ + unsigned long addr_delta; + long line_delta; + int opcode1, opcode2; + yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = state->dbgfmt_dwarf2; + + if (state->file != loc->file) { + state->file = loc->file; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file, + yasm_intnum_create_uint(state->file)); + } + if (state->column != loc->column) { + state->column = loc->column; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column, + yasm_intnum_create_uint(state->column)); + } #ifdef WITH_DWARF3 - if (loc->isa_change) { - isa = loc->isa; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_set_isa, - yasm_intnum_create_uint(isa)); - } + if (loc->isa_change) { + state->isa = loc->isa; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa, + yasm_intnum_create_uint(state->isa)); + } #endif - if (is_stmt == 0 && loc->is_stmt == IS_STMT_SET) { - is_stmt = 1; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_negate_stmt, - NULL); - } else if (is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) { - is_stmt = 0; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_negate_stmt, - NULL); - } - if (loc->basic_block) { - dwarf2_dbgfmt_append_line_op(info->debug_line, - DW_LNS_set_basic_block, NULL); - } + if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) { + state->is_stmt = 1; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); + } else if (state->is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) { + state->is_stmt = 0; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); + } + if (loc->basic_block) { + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_basic_block, NULL); + } #ifdef WITH_DWARF3 - if (loc->prologue_end) { - dwarf2_dbgfmt_append_line_op(info->debug_line, - DW_LNS_set_prologue_end, NULL); - } - if (loc->epilogue_begin) { - dwarf2_dbgfmt_append_line_op(info->debug_line, - DW_LNS_set_epilogue_begin, NULL); - } + if (loc->prologue_end) { + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_prologue_end, NULL); + } + if (loc->epilogue_begin) { + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_epilogue_begin, + NULL); + } #endif - /* If multiple loc for the same location, use last */ - bc = loc->bc; - if (STAILQ_NEXT(loc, link) - && STAILQ_NEXT(loc, link)->bc->offset == bc->offset) - continue; - - if (!precbc) { - /* Set the starting address for the section */ - if (!loc->sym) { - /* shouldn't happen! */ - yasm__error(loc->line, N_("could not find label prior to loc")); - return 1; - } - dwarf2_dbgfmt_append_line_ext_op(info->debug_line, - DW_LNE_set_address, dbgfmt_dwarf2->sizeof_address, - yasm_expr_create_ident(yasm_expr_sym(loc->sym), loc->line)); - addr_delta = 0; - } else if (bc) { - if (precbc->offset > bc->offset) - yasm_internal_error(N_("dwarf2 address went backwards?")); - addr_delta = bc->offset - precbc->offset; - } else - break; /* ran out of bytecodes! XXX: do something? */ + /* If multiple loc for the same location, use last */ + if (nextloc && nextloc->bc->offset == loc->bc->offset) + return 0; - /* Generate appropriate opcode(s). Address can only increment, - * whereas line number can go backwards. - */ - line_delta = loc->line - line; - line = loc->line; - - /* First handle the line delta */ - if (line_delta < DWARF2_LINE_BASE - || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) { - /* Won't fit in special opcode, use (signed) line advance */ - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_line, - yasm_intnum_create_int(line_delta)); - line_delta = 0; + if (!state->precbc) { + /* Set the starting address for the section */ + if (!loc->sym) { + /* shouldn't happen! */ + yasm__error(loc->line, N_("could not find label prior to loc")); + return 1; } + dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address, + dbgfmt_dwarf2->sizeof_address, + yasm_expr_create_ident(yasm_expr_sym(loc->sym), loc->line)); + addr_delta = 0; + } else if (loc->bc) { + if (state->precbc->offset > loc->bc->offset) + yasm_internal_error(N_("dwarf2 address went backwards?")); + addr_delta = loc->bc->offset - state->precbc->offset; + } else + return 0; /* ran out of bytecodes! XXX: do something? */ + + /* Generate appropriate opcode(s). Address can only increment, + * whereas line number can go backwards. + */ + line_delta = loc->line - state->line; + state->line = loc->line; + + /* First handle the line delta */ + if (line_delta < DWARF2_LINE_BASE + || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) { + /* Won't fit in special opcode, use (signed) line advance */ + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_line, + yasm_intnum_create_int(line_delta)); + line_delta = 0; + } - /* Next handle the address delta */ - opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + - DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len); - opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + - DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) / - dbgfmt_dwarf2->min_insn_len); - if (line_delta == 0 && addr_delta == 0) { - /* Both line and addr deltas are 0: do DW_LNS_copy */ - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_copy, NULL); - } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA - && opcode1 <= 255) { - /* Addr delta in range of special opcode */ - dwarf2_dbgfmt_append_line_op(info->debug_line, opcode1, NULL); - } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA - && opcode2 <= 255) { - /* Addr delta in range of const_add_pc + special */ + /* Next handle the address delta */ + opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + + DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len); + opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + + DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) / + dbgfmt_dwarf2->min_insn_len); + if (line_delta == 0 && addr_delta == 0) { + /* Both line and addr deltas are 0: do DW_LNS_copy */ + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL); + } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA && opcode1 <= 255) { + /* Addr delta in range of special opcode */ + dwarf2_dbgfmt_append_line_op(debug_line, opcode1, NULL); + } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA + && opcode2 <= 255) { + /* Addr delta in range of const_add_pc + special */ + unsigned int opcode; + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_const_add_pc, NULL); + dwarf2_dbgfmt_append_line_op(debug_line, opcode2, NULL); + } else { + /* Need advance_pc */ + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_pc, + yasm_intnum_create_uint(addr_delta)); + /* Take care of any remaining line_delta and add entry to matrix */ + if (line_delta == 0) + dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL); + else { unsigned int opcode; - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc, - NULL); - dwarf2_dbgfmt_append_line_op(info->debug_line, opcode2, NULL); - } else { - /* Need advance_pc */ - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_pc, - yasm_intnum_create_uint(addr_delta)); - /* Take care of any remaining line_delta and add entry to matrix */ - if (line_delta == 0) - dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_copy, - NULL); - else { - unsigned int opcode; - opcode = DWARF2_LINE_OPCODE_BASE + line_delta - - DWARF2_LINE_BASE; - dwarf2_dbgfmt_append_line_op(info->debug_line, opcode, NULL); - } + opcode = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE; + dwarf2_dbgfmt_append_line_op(debug_line, opcode, NULL); } + } + state->precbc = loc->bc; + return 0; +} - precbc = bc; +static int +dwarf2_dbgfmt_generate_section(yasm_section *sect, /*@null@*/ void *d) +{ + dwarf2_info *info = (dwarf2_info *)d; + yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; + /*@null@*/ dwarf2_section_data *dsd; + /*@null@*/ dwarf2_loc *loc; + /*@null@*/ yasm_bytecode *bc; + dwarf2_line_state state; + unsigned long addr_delta; + + dsd = yasm_section_get_data(sect, &dwarf2_section_data_cb); + if (!dsd) + return 0; /* no line data for this section */ + + /* initialize state machine registers for each sequence */ + state.dbgfmt_dwarf2 = dbgfmt_dwarf2; + state.address = 0; + state.file = 1; + state.line = 1; + state.column = 0; + state.isa = 0; + state.is_stmt = DWARF2_LINE_DEFAULT_IS_STMT; + state.precbc = NULL; + + dwarf2_dbgfmt_finalize_locs(sect, dsd); + + STAILQ_FOREACH(loc, &dsd->locs, link) { + if (dwarf2_dbgfmt_gen_line_op(info->debug_line, &state, loc, + STAILQ_NEXT(loc, link))) + return 1; } /* End sequence: bring address to end of section, then output end @@ -530,7 +560,7 @@ dwarf2_dbgfmt_generate_section(yasm_section *sect, /*@null@*/ void *d) * want an extra entry in the line matrix. */ bc = yasm_section_bcs_last(sect); - addr_delta = bc->offset + bc->len - precbc->offset; + addr_delta = bc->offset + bc->len - state.precbc->offset; if (addr_delta == DWARF2_MAX_SPECIAL_ADDR_DELTA) dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc, NULL);