Index: third_party/yasm/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-line.c |
=================================================================== |
--- third_party/yasm/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-line.c (revision 165590) |
+++ third_party/yasm/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-line.c (working copy) |
@@ -28,7 +28,6 @@ |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <util.h> |
-/*@unused@*/ RCSID("$Id: dwarf2-line.c 2130 2008-10-07 05:38:11Z peter $"); |
#include <libyasm.h> |
@@ -77,7 +76,8 @@ |
typedef enum { |
DW_LNE_end_sequence = 1, |
DW_LNE_set_address, |
- DW_LNE_define_file |
+ DW_LNE_define_file, |
+ DW_LNE_set_discriminator |
} dwarf_line_number_ext_op; |
/* Base and range for line offsets in special opcodes */ |
@@ -120,6 +120,7 @@ |
/* extended opcode */ |
dwarf_line_number_ext_op ext_opcode; |
/*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */ |
+ /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */ |
unsigned long ext_operandsize; |
} dwarf2_line_op; |
@@ -130,7 +131,7 @@ |
static int dwarf2_spp_bc_calc_len |
(yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); |
static int dwarf2_spp_bc_tobytes |
- (yasm_bytecode *bc, unsigned char **bufp, void *d, |
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
yasm_output_value_func output_value, |
/*@null@*/ yasm_output_reloc_func output_reloc); |
@@ -140,7 +141,7 @@ |
static int dwarf2_line_op_bc_calc_len |
(yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); |
static int dwarf2_line_op_bc_tobytes |
- (yasm_bytecode *bc, unsigned char **bufp, void *d, |
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
yasm_output_value_func output_value, |
/*@null@*/ yasm_output_reloc_func output_reloc); |
@@ -254,6 +255,7 @@ |
line_op->operand = operand; |
line_op->ext_opcode = 0; |
line_op->ext_operand = NULL; |
+ line_op->ext_operand_int = NULL; |
line_op->ext_operandsize = 0; |
bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
@@ -282,6 +284,7 @@ |
line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); |
line_op->ext_opcode = ext_opcode; |
line_op->ext_operand = ext_operand; |
+ line_op->ext_operand_int = NULL; |
line_op->ext_operandsize = ext_operandsize; |
bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
@@ -292,6 +295,30 @@ |
return bc; |
} |
+static yasm_bytecode * |
+dwarf2_dbgfmt_append_line_ext_op_int(yasm_section *sect, |
+ dwarf_line_number_ext_op ext_opcode, |
+ /*@only@*/ yasm_intnum *ext_operand) |
+{ |
+ dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); |
+ unsigned long ext_operandsize = yasm_intnum_size_leb128(ext_operand, 0); |
+ yasm_bytecode *bc; |
+ |
+ line_op->opcode = DW_LNS_extended_op; |
+ line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); |
+ line_op->ext_opcode = ext_opcode; |
+ line_op->ext_operand = NULL; |
+ line_op->ext_operand_int = ext_operand; |
+ line_op->ext_operandsize = ext_operandsize; |
+ |
+ bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
+ bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) + |
+ ext_operandsize; |
+ |
+ yasm_dwarf2__append_bc(sect, bc); |
+ return bc; |
+} |
+ |
static void |
dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd) |
{ |
@@ -344,6 +371,11 @@ |
dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column, |
yasm_intnum_create_uint(state->column)); |
} |
+ if (loc->discriminator != 0) { |
+ dwarf2_dbgfmt_append_line_ext_op_int(debug_line, |
+ DW_LNE_set_discriminator, |
+ yasm_intnum_create_uint(loc->discriminator)); |
+ } |
#ifdef WITH_DWARF3 |
if (loc->isa_change) { |
state->isa = loc->isa; |
@@ -453,12 +485,34 @@ |
} dwarf2_line_bc_info; |
static int |
+dwarf2_filename_equals(const dwarf2_filename *fn, |
+ char **dirs, |
+ const char *pathname, |
+ unsigned long dirlen, |
+ const char *filename) |
+{ |
+ /* check directory */ |
+ if (fn->dir == 0) { |
+ if (dirlen != 0) |
+ return 0; |
+ } else { |
+ if (strncmp(dirs[fn->dir-1], pathname, dirlen) != 0 || |
+ dirs[fn->dir-1][dirlen] != '\0') |
+ return 0; |
+ } |
+ |
+ /* check filename */ |
+ return strcmp(fn->filename, filename) == 0; |
+} |
+ |
+static int |
dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d) |
{ |
dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d; |
yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; |
unsigned long i; |
- const char *filename; |
+ size_t dirlen; |
+ const char *pathname, *filename; |
/*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc); |
if (nextbc && bc->offset == nextbc->offset) |
@@ -476,15 +530,20 @@ |
} |
} |
- yasm_linemap_lookup(info->linemap, bc->line, &filename, &info->loc.line); |
+ yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line); |
+ dirlen = yasm__splitpath(pathname, &filename); |
+ |
/* Find file index; just linear search it unless it was the last used */ |
if (info->lastfile > 0 |
- && strcmp(filename, dbgfmt_dwarf2->filenames[info->lastfile-1].pathname) |
- == 0) |
+ && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1], |
+ dbgfmt_dwarf2->dirs, pathname, dirlen, |
+ filename)) |
info->loc.file = info->lastfile; |
else { |
for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { |
- if (strcmp(filename, dbgfmt_dwarf2->filenames[i].pathname) == 0) |
+ if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i], |
+ dbgfmt_dwarf2->dirs, pathname, dirlen, |
+ filename)) |
break; |
} |
if (i >= dbgfmt_dwarf2->filenames_size) |
@@ -561,6 +620,7 @@ |
bcinfo.lastfile = 0; |
bcinfo.loc.isa_change = 0; |
bcinfo.loc.column = 0; |
+ bcinfo.loc.discriminator = 0; |
bcinfo.loc.is_stmt = IS_STMT_NOCHANGE; |
bcinfo.loc.basic_block = 0; |
bcinfo.loc.prologue_end = 0; |
@@ -717,7 +777,8 @@ |
} |
static int |
-dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, |
+dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
+ unsigned char *bufstart, void *d, |
yasm_output_value_func output_value, |
yasm_output_reloc_func output_reloc) |
{ |
@@ -780,6 +841,8 @@ |
dwarf2_line_op *line_op = (dwarf2_line_op *)contents; |
if (line_op->operand) |
yasm_intnum_destroy(line_op->operand); |
+ if (line_op->ext_operand_int) |
+ yasm_intnum_destroy(line_op->ext_operand_int); |
yasm_xfree(contents); |
} |
@@ -799,7 +862,8 @@ |
} |
static int |
-dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, |
+dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
+ unsigned char *bufstart, void *d, |
yasm_output_value_func output_value, |
yasm_output_reloc_func output_reloc) |
{ |
@@ -817,9 +881,12 @@ |
yasm_value_init_sym(&value, line_op->ext_operand, |
line_op->ext_operandsize*8); |
output_value(&value, buf, line_op->ext_operandsize, |
- (unsigned long)(buf-*bufp), bc, 0, d); |
+ (unsigned long)(buf-bufstart), bc, 0, d); |
buf += line_op->ext_operandsize; |
} |
+ if (line_op->ext_operand_int) { |
+ buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0); |
+ } |
} |
*bufp = buf; |
@@ -831,7 +898,7 @@ |
yasm_valparamhead *objext_valparams, unsigned long line) |
{ |
yasm_valparam *vp; |
- int in_is_stmt = 0, in_isa = 0; |
+ int in_is_stmt = 0, in_isa = 0, in_discriminator = 0; |
/*@dependent@*/ /*@null@*/ const yasm_intnum *intn; |
dwarf2_section_data *dsd; |
@@ -892,6 +959,7 @@ |
/* Defaults for optional settings */ |
loc->column = 0; |
+ loc->discriminator = 0; |
loc->isa_change = 0; |
loc->isa = 0; |
loc->is_stmt = IS_STMT_NOCHANGE; |
@@ -966,11 +1034,33 @@ |
loc->isa_change = 1; |
loc->isa = yasm_intnum_get_uint(intn); |
yasm_expr_destroy(e); |
+ } else if (in_discriminator) { |
+ in_discriminator = 0; |
+ if (!(e = yasm_vp_expr(vp, object->symtab, line)) || |
+ !(intn = yasm_expr_get_intnum(&e, 0))) { |
+ yasm_error_set(YASM_ERROR_NOT_CONSTANT, |
+ N_("discriminator value is not a constant")); |
+ yasm_xfree(loc); |
+ if (e) |
+ yasm_expr_destroy(e); |
+ return; |
+ } |
+ if (yasm_intnum_sign(intn) < 0) { |
+ yasm_error_set(YASM_ERROR_VALUE, |
+ N_("discriminator value less than zero")); |
+ yasm_xfree(loc); |
+ yasm_expr_destroy(e); |
+ return; |
+ } |
+ loc->discriminator = yasm_intnum_get_uint(intn); |
+ yasm_expr_destroy(e); |
} else if (!vp->val && (s = yasm_vp_id(vp))) { |
if (yasm__strcasecmp(s, "is_stmt") == 0) |
in_is_stmt = 1; |
else if (yasm__strcasecmp(s, "isa") == 0) |
in_isa = 1; |
+ else if (yasm__strcasecmp(s, "discriminator") == 0) |
+ in_discriminator = 1; |
else if (yasm__strcasecmp(s, "basic_block") == 0) |
loc->basic_block = 1; |
else if (yasm__strcasecmp(s, "prologue_end") == 0) |
@@ -989,15 +1079,19 @@ |
} else if (yasm__strcasecmp(vp->val, "isa") == 0) { |
in_isa = 1; |
goto restart; /* don't go to the next valparam */ |
+ } else if (yasm__strcasecmp(vp->val, "discriminator") == 0) { |
+ in_discriminator = 1; |
+ goto restart; /* don't go to the next valparam */ |
} else |
yasm_warn_set(YASM_WARN_GENERAL, |
N_("unrecognized loc option `%s'"), vp->val); |
vp = yasm_vps_next(vp); |
} |
- if (in_is_stmt || in_isa) { |
+ if (in_is_stmt || in_isa || in_discriminator) { |
yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"), |
- in_is_stmt ? "is_stmt" : "isa"); |
+ in_is_stmt ? "is_stmt" : |
+ (in_isa ? "isa" : "discriminator")); |
yasm_xfree(loc); |
return; |
} |