]> granicus.if.org Git - yasm/commitdiff
* dwarf2-dbgfmt.c (generate_section): Split off large chunks into gen_line_op
authorPeter Johnson <peter@tortall.net>
Fri, 3 Feb 2006 06:38:30 +0000 (06:38 -0000)
committerPeter Johnson <peter@tortall.net>
Fri, 3 Feb 2006 06:38:30 +0000 (06:38 -0000)
and finalize_locs functions, preparing for later asm-source dbg generation.

svn path=/trunk/yasm/; revision=1357

modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c

index a5fc92d374a0f3b1accec78711bfffab0b1a20d9..25556ab6fdd7b7f046ebb211ad139e8d6cf9702e 100644 (file)
@@ -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);