| 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;
|
| }
|
|
|