OLD | NEW |
1 /* | 1 /* |
2 * DWARF2 debugging format - line information | 2 * DWARF2 debugging format - line information |
3 * | 3 * |
4 * Copyright (C) 2006-2007 Peter Johnson | 4 * Copyright (C) 2006-2007 Peter Johnson |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 10 matching lines...) Expand all Loading... |
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
28 * POSSIBILITY OF SUCH DAMAGE. | 28 * POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 #include <util.h> | 30 #include <util.h> |
31 /*@unused@*/ RCSID("$Id: dwarf2-line.c 2130 2008-10-07 05:38:11Z peter $"); | |
32 | 31 |
33 #include <libyasm.h> | 32 #include <libyasm.h> |
34 | 33 |
35 #include "dwarf2-dbgfmt.h" | 34 #include "dwarf2-dbgfmt.h" |
36 | 35 |
37 /* DWARF line number opcodes */ | 36 /* DWARF line number opcodes */ |
38 typedef enum { | 37 typedef enum { |
39 DW_LNS_extended_op = 0, | 38 DW_LNS_extended_op = 0, |
40 DW_LNS_copy, | 39 DW_LNS_copy, |
41 DW_LNS_advance_pc, | 40 DW_LNS_advance_pc, |
(...skipping 28 matching lines...) Expand all Loading... |
70 0, /* DW_LNS_set_prologue_end */ | 69 0, /* DW_LNS_set_prologue_end */ |
71 0, /* DW_LNS_set_epilogue_begin */ | 70 0, /* DW_LNS_set_epilogue_begin */ |
72 1 /* DW_LNS_set_isa */ | 71 1 /* DW_LNS_set_isa */ |
73 #endif | 72 #endif |
74 }; | 73 }; |
75 | 74 |
76 /* Line number extended opcodes */ | 75 /* Line number extended opcodes */ |
77 typedef enum { | 76 typedef enum { |
78 DW_LNE_end_sequence = 1, | 77 DW_LNE_end_sequence = 1, |
79 DW_LNE_set_address, | 78 DW_LNE_set_address, |
80 DW_LNE_define_file | 79 DW_LNE_define_file, |
| 80 DW_LNE_set_discriminator |
81 } dwarf_line_number_ext_op; | 81 } dwarf_line_number_ext_op; |
82 | 82 |
83 /* Base and range for line offsets in special opcodes */ | 83 /* Base and range for line offsets in special opcodes */ |
84 #define DWARF2_LINE_BASE -5 | 84 #define DWARF2_LINE_BASE -5 |
85 #define DWARF2_LINE_RANGE 14 | 85 #define DWARF2_LINE_RANGE 14 |
86 | 86 |
87 #define DWARF2_MAX_SPECIAL_ADDR_DELTA \ | 87 #define DWARF2_MAX_SPECIAL_ADDR_DELTA \ |
88 (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\ | 88 (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\ |
89 dbgfmt_dwarf2->min_insn_len) | 89 dbgfmt_dwarf2->min_insn_len) |
90 | 90 |
(...skipping 22 matching lines...) Expand all Loading... |
113 yasm_bytecode *line_end_prevbc; | 113 yasm_bytecode *line_end_prevbc; |
114 } dwarf2_spp; | 114 } dwarf2_spp; |
115 | 115 |
116 typedef struct dwarf2_line_op { | 116 typedef struct dwarf2_line_op { |
117 dwarf_line_number_op opcode; | 117 dwarf_line_number_op opcode; |
118 /*@owned@*/ /*@null@*/ yasm_intnum *operand; | 118 /*@owned@*/ /*@null@*/ yasm_intnum *operand; |
119 | 119 |
120 /* extended opcode */ | 120 /* extended opcode */ |
121 dwarf_line_number_ext_op ext_opcode; | 121 dwarf_line_number_ext_op ext_opcode; |
122 /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */ | 122 /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */ |
| 123 /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */ |
123 unsigned long ext_operandsize; | 124 unsigned long ext_operandsize; |
124 } dwarf2_line_op; | 125 } dwarf2_line_op; |
125 | 126 |
126 /* Bytecode callback function prototypes */ | 127 /* Bytecode callback function prototypes */ |
127 static void dwarf2_spp_bc_destroy(void *contents); | 128 static void dwarf2_spp_bc_destroy(void *contents); |
128 static void dwarf2_spp_bc_print(const void *contents, FILE *f, | 129 static void dwarf2_spp_bc_print(const void *contents, FILE *f, |
129 int indent_level); | 130 int indent_level); |
130 static int dwarf2_spp_bc_calc_len | 131 static int dwarf2_spp_bc_calc_len |
131 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); | 132 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); |
132 static int dwarf2_spp_bc_tobytes | 133 static int dwarf2_spp_bc_tobytes |
133 (yasm_bytecode *bc, unsigned char **bufp, void *d, | 134 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
134 yasm_output_value_func output_value, | 135 yasm_output_value_func output_value, |
135 /*@null@*/ yasm_output_reloc_func output_reloc); | 136 /*@null@*/ yasm_output_reloc_func output_reloc); |
136 | 137 |
137 static void dwarf2_line_op_bc_destroy(void *contents); | 138 static void dwarf2_line_op_bc_destroy(void *contents); |
138 static void dwarf2_line_op_bc_print(const void *contents, FILE *f, | 139 static void dwarf2_line_op_bc_print(const void *contents, FILE *f, |
139 int indent_level); | 140 int indent_level); |
140 static int dwarf2_line_op_bc_calc_len | 141 static int dwarf2_line_op_bc_calc_len |
141 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); | 142 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); |
142 static int dwarf2_line_op_bc_tobytes | 143 static int dwarf2_line_op_bc_tobytes |
143 (yasm_bytecode *bc, unsigned char **bufp, void *d, | 144 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
144 yasm_output_value_func output_value, | 145 yasm_output_value_func output_value, |
145 /*@null@*/ yasm_output_reloc_func output_reloc); | 146 /*@null@*/ yasm_output_reloc_func output_reloc); |
146 | 147 |
147 /* Bytecode callback structures */ | 148 /* Bytecode callback structures */ |
148 static const yasm_bytecode_callback dwarf2_spp_bc_callback = { | 149 static const yasm_bytecode_callback dwarf2_spp_bc_callback = { |
149 dwarf2_spp_bc_destroy, | 150 dwarf2_spp_bc_destroy, |
150 dwarf2_spp_bc_print, | 151 dwarf2_spp_bc_print, |
151 yasm_bc_finalize_common, | 152 yasm_bc_finalize_common, |
152 NULL, | 153 NULL, |
153 dwarf2_spp_bc_calc_len, | 154 dwarf2_spp_bc_calc_len, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode, | 248 dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode, |
248 /*@only@*/ /*@null@*/ yasm_intnum *operand) | 249 /*@only@*/ /*@null@*/ yasm_intnum *operand) |
249 { | 250 { |
250 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); | 251 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); |
251 yasm_bytecode *bc; | 252 yasm_bytecode *bc; |
252 | 253 |
253 line_op->opcode = opcode; | 254 line_op->opcode = opcode; |
254 line_op->operand = operand; | 255 line_op->operand = operand; |
255 line_op->ext_opcode = 0; | 256 line_op->ext_opcode = 0; |
256 line_op->ext_operand = NULL; | 257 line_op->ext_operand = NULL; |
| 258 line_op->ext_operand_int = NULL; |
257 line_op->ext_operandsize = 0; | 259 line_op->ext_operandsize = 0; |
258 | 260 |
259 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); | 261 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
260 bc->len = 1; | 262 bc->len = 1; |
261 if (operand) | 263 if (operand) |
262 bc->len += yasm_intnum_size_leb128(operand, | 264 bc->len += yasm_intnum_size_leb128(operand, |
263 opcode == DW_LNS_advance_line); | 265 opcode == DW_LNS_advance_line); |
264 | 266 |
265 yasm_dwarf2__append_bc(sect, bc); | 267 yasm_dwarf2__append_bc(sect, bc); |
266 return bc; | 268 return bc; |
267 } | 269 } |
268 | 270 |
269 /* Create and add a new extended line opcode to a section, updating offset on | 271 /* Create and add a new extended line opcode to a section, updating offset on |
270 * insertion; no optimization necessary. | 272 * insertion; no optimization necessary. |
271 */ | 273 */ |
272 static yasm_bytecode * | 274 static yasm_bytecode * |
273 dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect, | 275 dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect, |
274 dwarf_line_number_ext_op ext_opcode, | 276 dwarf_line_number_ext_op ext_opcode, |
275 unsigned long ext_operandsize, | 277 unsigned long ext_operandsize, |
276 /*@null@*/ yasm_symrec *ext_operand) | 278 /*@null@*/ yasm_symrec *ext_operand) |
277 { | 279 { |
278 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); | 280 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); |
279 yasm_bytecode *bc; | 281 yasm_bytecode *bc; |
280 | 282 |
281 line_op->opcode = DW_LNS_extended_op; | 283 line_op->opcode = DW_LNS_extended_op; |
282 line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); | 284 line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); |
283 line_op->ext_opcode = ext_opcode; | 285 line_op->ext_opcode = ext_opcode; |
284 line_op->ext_operand = ext_operand; | 286 line_op->ext_operand = ext_operand; |
| 287 line_op->ext_operand_int = NULL; |
285 line_op->ext_operandsize = ext_operandsize; | 288 line_op->ext_operandsize = ext_operandsize; |
286 | 289 |
287 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); | 290 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
288 bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) + | 291 bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) + |
289 ext_operandsize; | 292 ext_operandsize; |
290 | 293 |
291 yasm_dwarf2__append_bc(sect, bc); | 294 yasm_dwarf2__append_bc(sect, bc); |
292 return bc; | 295 return bc; |
293 } | 296 } |
294 | 297 |
| 298 static yasm_bytecode * |
| 299 dwarf2_dbgfmt_append_line_ext_op_int(yasm_section *sect, |
| 300 dwarf_line_number_ext_op ext_opcode, |
| 301 /*@only@*/ yasm_intnum *ext_operand) |
| 302 { |
| 303 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); |
| 304 unsigned long ext_operandsize = yasm_intnum_size_leb128(ext_operand, 0); |
| 305 yasm_bytecode *bc; |
| 306 |
| 307 line_op->opcode = DW_LNS_extended_op; |
| 308 line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); |
| 309 line_op->ext_opcode = ext_opcode; |
| 310 line_op->ext_operand = NULL; |
| 311 line_op->ext_operand_int = ext_operand; |
| 312 line_op->ext_operandsize = ext_operandsize; |
| 313 |
| 314 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); |
| 315 bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) + |
| 316 ext_operandsize; |
| 317 |
| 318 yasm_dwarf2__append_bc(sect, bc); |
| 319 return bc; |
| 320 } |
| 321 |
295 static void | 322 static void |
296 dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd) | 323 dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd) |
297 { | 324 { |
298 /*@dependent@*/ yasm_symrec *lastsym = NULL; | 325 /*@dependent@*/ yasm_symrec *lastsym = NULL; |
299 /*@null@*/ yasm_bytecode *bc; | 326 /*@null@*/ yasm_bytecode *bc; |
300 /*@null@*/ dwarf2_loc *loc; | 327 /*@null@*/ dwarf2_loc *loc; |
301 | 328 |
302 bc = yasm_section_bcs_first(sect); | 329 bc = yasm_section_bcs_first(sect); |
303 STAILQ_FOREACH(loc, &dsd->locs, link) { | 330 STAILQ_FOREACH(loc, &dsd->locs, link) { |
304 /* Find the first bytecode following this loc by looking at | 331 /* Find the first bytecode following this loc by looking at |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 if (state->file != loc->file) { | 364 if (state->file != loc->file) { |
338 state->file = loc->file; | 365 state->file = loc->file; |
339 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file, | 366 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file, |
340 yasm_intnum_create_uint(state->file)); | 367 yasm_intnum_create_uint(state->file)); |
341 } | 368 } |
342 if (state->column != loc->column) { | 369 if (state->column != loc->column) { |
343 state->column = loc->column; | 370 state->column = loc->column; |
344 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column, | 371 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column, |
345 yasm_intnum_create_uint(state->column)); | 372 yasm_intnum_create_uint(state->column)); |
346 } | 373 } |
| 374 if (loc->discriminator != 0) { |
| 375 dwarf2_dbgfmt_append_line_ext_op_int(debug_line, |
| 376 DW_LNE_set_discriminator, |
| 377 yasm_intnum_create_uint(loc->discriminator)); |
| 378 } |
347 #ifdef WITH_DWARF3 | 379 #ifdef WITH_DWARF3 |
348 if (loc->isa_change) { | 380 if (loc->isa_change) { |
349 state->isa = loc->isa; | 381 state->isa = loc->isa; |
350 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa, | 382 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa, |
351 yasm_intnum_create_uint(state->isa)); | 383 yasm_intnum_create_uint(state->isa)); |
352 } | 384 } |
353 #endif | 385 #endif |
354 if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) { | 386 if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) { |
355 state->is_stmt = 1; | 387 state->is_stmt = 1; |
356 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); | 388 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 yasm_section *debug_line; | 478 yasm_section *debug_line; |
447 yasm_object *object; | 479 yasm_object *object; |
448 yasm_linemap *linemap; | 480 yasm_linemap *linemap; |
449 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; | 481 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; |
450 dwarf2_line_state *state; | 482 dwarf2_line_state *state; |
451 dwarf2_loc loc; | 483 dwarf2_loc loc; |
452 unsigned long lastfile; | 484 unsigned long lastfile; |
453 } dwarf2_line_bc_info; | 485 } dwarf2_line_bc_info; |
454 | 486 |
455 static int | 487 static int |
| 488 dwarf2_filename_equals(const dwarf2_filename *fn, |
| 489 char **dirs, |
| 490 const char *pathname, |
| 491 unsigned long dirlen, |
| 492 const char *filename) |
| 493 { |
| 494 /* check directory */ |
| 495 if (fn->dir == 0) { |
| 496 if (dirlen != 0) |
| 497 return 0; |
| 498 } else { |
| 499 if (strncmp(dirs[fn->dir-1], pathname, dirlen) != 0 || |
| 500 dirs[fn->dir-1][dirlen] != '\0') |
| 501 return 0; |
| 502 } |
| 503 |
| 504 /* check filename */ |
| 505 return strcmp(fn->filename, filename) == 0; |
| 506 } |
| 507 |
| 508 static int |
456 dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d) | 509 dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d) |
457 { | 510 { |
458 dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d; | 511 dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d; |
459 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; | 512 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; |
460 unsigned long i; | 513 unsigned long i; |
461 const char *filename; | 514 size_t dirlen; |
| 515 const char *pathname, *filename; |
462 /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc); | 516 /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc); |
463 | 517 |
464 if (nextbc && bc->offset == nextbc->offset) | 518 if (nextbc && bc->offset == nextbc->offset) |
465 return 0; | 519 return 0; |
466 | 520 |
467 info->loc.vline = bc->line; | 521 info->loc.vline = bc->line; |
468 info->loc.bc = bc; | 522 info->loc.bc = bc; |
469 | 523 |
470 /* Keep track of last symbol seen */ | 524 /* Keep track of last symbol seen */ |
471 if (bc->symrecs) { | 525 if (bc->symrecs) { |
472 i = 0; | 526 i = 0; |
473 while (bc->symrecs[i]) { | 527 while (bc->symrecs[i]) { |
474 info->loc.sym = bc->symrecs[i]; | 528 info->loc.sym = bc->symrecs[i]; |
475 i++; | 529 i++; |
476 } | 530 } |
477 } | 531 } |
478 | 532 |
479 yasm_linemap_lookup(info->linemap, bc->line, &filename, &info->loc.line); | 533 yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line); |
| 534 dirlen = yasm__splitpath(pathname, &filename); |
| 535 |
480 /* Find file index; just linear search it unless it was the last used */ | 536 /* Find file index; just linear search it unless it was the last used */ |
481 if (info->lastfile > 0 | 537 if (info->lastfile > 0 |
482 && strcmp(filename, dbgfmt_dwarf2->filenames[info->lastfile-1].pathname) | 538 && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1], |
483 == 0) | 539 dbgfmt_dwarf2->dirs, pathname, dirlen, |
| 540 filename)) |
484 info->loc.file = info->lastfile; | 541 info->loc.file = info->lastfile; |
485 else { | 542 else { |
486 for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { | 543 for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { |
487 if (strcmp(filename, dbgfmt_dwarf2->filenames[i].pathname) == 0) | 544 if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i], |
| 545 dbgfmt_dwarf2->dirs, pathname, dirlen, |
| 546 filename)) |
488 break; | 547 break; |
489 } | 548 } |
490 if (i >= dbgfmt_dwarf2->filenames_size) | 549 if (i >= dbgfmt_dwarf2->filenames_size) |
491 yasm_internal_error(N_("could not find filename in table")); | 550 yasm_internal_error(N_("could not find filename in table")); |
492 info->loc.file = i+1; | 551 info->loc.file = i+1; |
493 info->lastfile = i+1; | 552 info->lastfile = i+1; |
494 } | 553 } |
495 if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc, | 554 if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc, |
496 NULL)) | 555 NULL)) |
497 return 1; | 556 return 1; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 dwarf2_line_bc_info bcinfo; | 613 dwarf2_line_bc_info bcinfo; |
555 | 614 |
556 bcinfo.debug_line = info->debug_line; | 615 bcinfo.debug_line = info->debug_line; |
557 bcinfo.object = info->object; | 616 bcinfo.object = info->object; |
558 bcinfo.linemap = info->linemap; | 617 bcinfo.linemap = info->linemap; |
559 bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2; | 618 bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2; |
560 bcinfo.state = &state; | 619 bcinfo.state = &state; |
561 bcinfo.lastfile = 0; | 620 bcinfo.lastfile = 0; |
562 bcinfo.loc.isa_change = 0; | 621 bcinfo.loc.isa_change = 0; |
563 bcinfo.loc.column = 0; | 622 bcinfo.loc.column = 0; |
| 623 bcinfo.loc.discriminator = 0; |
564 bcinfo.loc.is_stmt = IS_STMT_NOCHANGE; | 624 bcinfo.loc.is_stmt = IS_STMT_NOCHANGE; |
565 bcinfo.loc.basic_block = 0; | 625 bcinfo.loc.basic_block = 0; |
566 bcinfo.loc.prologue_end = 0; | 626 bcinfo.loc.prologue_end = 0; |
567 bcinfo.loc.epilogue_begin = 0; | 627 bcinfo.loc.epilogue_begin = 0; |
568 bcinfo.loc.sym = NULL; | 628 bcinfo.loc.sym = NULL; |
569 | 629 |
570 /* bcs_traverse() skips first "dummy" bytecode, so look at it | 630 /* bcs_traverse() skips first "dummy" bytecode, so look at it |
571 * separately to determine the initial symrec. | 631 * separately to determine the initial symrec. |
572 */ | 632 */ |
573 bc = yasm_section_bcs_first(sect); | 633 bc = yasm_section_bcs_first(sect); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 static int | 770 static int |
711 dwarf2_spp_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, | 771 dwarf2_spp_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, |
712 void *add_span_data) | 772 void *add_span_data) |
713 { | 773 { |
714 yasm_internal_error(N_("tried to calc_len a dwarf2 spp bytecode")); | 774 yasm_internal_error(N_("tried to calc_len a dwarf2 spp bytecode")); |
715 /*@notreached@*/ | 775 /*@notreached@*/ |
716 return 0; | 776 return 0; |
717 } | 777 } |
718 | 778 |
719 static int | 779 static int |
720 dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 780 dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 781 unsigned char *bufstart, void *d, |
721 yasm_output_value_func output_value, | 782 yasm_output_value_func output_value, |
722 yasm_output_reloc_func output_reloc) | 783 yasm_output_reloc_func output_reloc) |
723 { | 784 { |
724 yasm_object *object = yasm_section_get_object(bc->section); | 785 yasm_object *object = yasm_section_get_object(bc->section); |
725 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; | 786 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; |
726 unsigned char *buf = *bufp; | 787 unsigned char *buf = *bufp; |
727 yasm_intnum *cval; | 788 yasm_intnum *cval; |
728 size_t i, len; | 789 size_t i, len; |
729 | 790 |
730 /* Prologue length (following this field) */ | 791 /* Prologue length (following this field) */ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 yasm_intnum_destroy(cval); | 834 yasm_intnum_destroy(cval); |
774 return 0; | 835 return 0; |
775 } | 836 } |
776 | 837 |
777 static void | 838 static void |
778 dwarf2_line_op_bc_destroy(void *contents) | 839 dwarf2_line_op_bc_destroy(void *contents) |
779 { | 840 { |
780 dwarf2_line_op *line_op = (dwarf2_line_op *)contents; | 841 dwarf2_line_op *line_op = (dwarf2_line_op *)contents; |
781 if (line_op->operand) | 842 if (line_op->operand) |
782 yasm_intnum_destroy(line_op->operand); | 843 yasm_intnum_destroy(line_op->operand); |
| 844 if (line_op->ext_operand_int) |
| 845 yasm_intnum_destroy(line_op->ext_operand_int); |
783 yasm_xfree(contents); | 846 yasm_xfree(contents); |
784 } | 847 } |
785 | 848 |
786 static void | 849 static void |
787 dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level) | 850 dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level) |
788 { | 851 { |
789 /* TODO */ | 852 /* TODO */ |
790 } | 853 } |
791 | 854 |
792 static int | 855 static int |
793 dwarf2_line_op_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, | 856 dwarf2_line_op_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, |
794 void *add_span_data) | 857 void *add_span_data) |
795 { | 858 { |
796 yasm_internal_error(N_("tried to calc_len a dwarf2 line_op bytecode")); | 859 yasm_internal_error(N_("tried to calc_len a dwarf2 line_op bytecode")); |
797 /*@notreached@*/ | 860 /*@notreached@*/ |
798 return 0; | 861 return 0; |
799 } | 862 } |
800 | 863 |
801 static int | 864 static int |
802 dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 865 dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 866 unsigned char *bufstart, void *d, |
803 yasm_output_value_func output_value, | 867 yasm_output_value_func output_value, |
804 yasm_output_reloc_func output_reloc) | 868 yasm_output_reloc_func output_reloc) |
805 { | 869 { |
806 dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents; | 870 dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents; |
807 unsigned char *buf = *bufp; | 871 unsigned char *buf = *bufp; |
808 | 872 |
809 YASM_WRITE_8(buf, line_op->opcode); | 873 YASM_WRITE_8(buf, line_op->opcode); |
810 if (line_op->operand) | 874 if (line_op->operand) |
811 buf += yasm_intnum_get_leb128(line_op->operand, buf, | 875 buf += yasm_intnum_get_leb128(line_op->operand, buf, |
812 line_op->opcode == DW_LNS_advance_line); | 876 line_op->opcode == DW_LNS_advance_line); |
813 if (line_op->ext_opcode > 0) { | 877 if (line_op->ext_opcode > 0) { |
814 YASM_WRITE_8(buf, line_op->ext_opcode); | 878 YASM_WRITE_8(buf, line_op->ext_opcode); |
815 if (line_op->ext_operand) { | 879 if (line_op->ext_operand) { |
816 yasm_value value; | 880 yasm_value value; |
817 yasm_value_init_sym(&value, line_op->ext_operand, | 881 yasm_value_init_sym(&value, line_op->ext_operand, |
818 line_op->ext_operandsize*8); | 882 line_op->ext_operandsize*8); |
819 output_value(&value, buf, line_op->ext_operandsize, | 883 output_value(&value, buf, line_op->ext_operandsize, |
820 (unsigned long)(buf-*bufp), bc, 0, d); | 884 (unsigned long)(buf-bufstart), bc, 0, d); |
821 buf += line_op->ext_operandsize; | 885 buf += line_op->ext_operandsize; |
822 } | 886 } |
| 887 if (line_op->ext_operand_int) { |
| 888 buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0); |
| 889 } |
823 } | 890 } |
824 | 891 |
825 *bufp = buf; | 892 *bufp = buf; |
826 return 0; | 893 return 0; |
827 } | 894 } |
828 | 895 |
829 void | 896 void |
830 yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams, | 897 yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams, |
831 yasm_valparamhead *objext_valparams, unsigned long line) | 898 yasm_valparamhead *objext_valparams, unsigned long line) |
832 { | 899 { |
833 yasm_valparam *vp; | 900 yasm_valparam *vp; |
834 int in_is_stmt = 0, in_isa = 0; | 901 int in_is_stmt = 0, in_isa = 0, in_discriminator = 0; |
835 | 902 |
836 /*@dependent@*/ /*@null@*/ const yasm_intnum *intn; | 903 /*@dependent@*/ /*@null@*/ const yasm_intnum *intn; |
837 dwarf2_section_data *dsd; | 904 dwarf2_section_data *dsd; |
838 dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc)); | 905 dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc)); |
839 | 906 |
840 /* File number (required) */ | 907 /* File number (required) */ |
841 if (!valparams || !(vp = yasm_vps_first(valparams)) || | 908 if (!valparams || !(vp = yasm_vps_first(valparams)) || |
842 vp->val || vp->type != YASM_PARAM_EXPR) { | 909 vp->val || vp->type != YASM_PARAM_EXPR) { |
843 yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required")); | 910 yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required")); |
844 yasm_xfree(loc); | 911 yasm_xfree(loc); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 &yasm_dwarf2__section_data_cb); | 952 &yasm_dwarf2__section_data_cb); |
886 if (!dsd) { | 953 if (!dsd) { |
887 dsd = yasm_xmalloc(sizeof(dwarf2_section_data)); | 954 dsd = yasm_xmalloc(sizeof(dwarf2_section_data)); |
888 STAILQ_INIT(&dsd->locs); | 955 STAILQ_INIT(&dsd->locs); |
889 yasm_section_add_data(object->cur_section, | 956 yasm_section_add_data(object->cur_section, |
890 &yasm_dwarf2__section_data_cb, dsd); | 957 &yasm_dwarf2__section_data_cb, dsd); |
891 } | 958 } |
892 | 959 |
893 /* Defaults for optional settings */ | 960 /* Defaults for optional settings */ |
894 loc->column = 0; | 961 loc->column = 0; |
| 962 loc->discriminator = 0; |
895 loc->isa_change = 0; | 963 loc->isa_change = 0; |
896 loc->isa = 0; | 964 loc->isa = 0; |
897 loc->is_stmt = IS_STMT_NOCHANGE; | 965 loc->is_stmt = IS_STMT_NOCHANGE; |
898 loc->basic_block = 0; | 966 loc->basic_block = 0; |
899 loc->prologue_end = 0; | 967 loc->prologue_end = 0; |
900 loc->epilogue_begin = 0; | 968 loc->epilogue_begin = 0; |
901 | 969 |
902 /* Optional column number */ | 970 /* Optional column number */ |
903 vp = yasm_vps_next(vp); | 971 vp = yasm_vps_next(vp); |
904 if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) { | 972 if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 if (yasm_intnum_sign(intn) < 0) { | 1027 if (yasm_intnum_sign(intn) < 0) { |
960 yasm_error_set(YASM_ERROR_VALUE, | 1028 yasm_error_set(YASM_ERROR_VALUE, |
961 N_("isa value less than zero")); | 1029 N_("isa value less than zero")); |
962 yasm_xfree(loc); | 1030 yasm_xfree(loc); |
963 yasm_expr_destroy(e); | 1031 yasm_expr_destroy(e); |
964 return; | 1032 return; |
965 } | 1033 } |
966 loc->isa_change = 1; | 1034 loc->isa_change = 1; |
967 loc->isa = yasm_intnum_get_uint(intn); | 1035 loc->isa = yasm_intnum_get_uint(intn); |
968 yasm_expr_destroy(e); | 1036 yasm_expr_destroy(e); |
| 1037 } else if (in_discriminator) { |
| 1038 in_discriminator = 0; |
| 1039 if (!(e = yasm_vp_expr(vp, object->symtab, line)) || |
| 1040 !(intn = yasm_expr_get_intnum(&e, 0))) { |
| 1041 yasm_error_set(YASM_ERROR_NOT_CONSTANT, |
| 1042 N_("discriminator value is not a constant")); |
| 1043 yasm_xfree(loc); |
| 1044 if (e) |
| 1045 yasm_expr_destroy(e); |
| 1046 return; |
| 1047 } |
| 1048 if (yasm_intnum_sign(intn) < 0) { |
| 1049 yasm_error_set(YASM_ERROR_VALUE, |
| 1050 N_("discriminator value less than zero")); |
| 1051 yasm_xfree(loc); |
| 1052 yasm_expr_destroy(e); |
| 1053 return; |
| 1054 } |
| 1055 loc->discriminator = yasm_intnum_get_uint(intn); |
| 1056 yasm_expr_destroy(e); |
969 } else if (!vp->val && (s = yasm_vp_id(vp))) { | 1057 } else if (!vp->val && (s = yasm_vp_id(vp))) { |
970 if (yasm__strcasecmp(s, "is_stmt") == 0) | 1058 if (yasm__strcasecmp(s, "is_stmt") == 0) |
971 in_is_stmt = 1; | 1059 in_is_stmt = 1; |
972 else if (yasm__strcasecmp(s, "isa") == 0) | 1060 else if (yasm__strcasecmp(s, "isa") == 0) |
973 in_isa = 1; | 1061 in_isa = 1; |
| 1062 else if (yasm__strcasecmp(s, "discriminator") == 0) |
| 1063 in_discriminator = 1; |
974 else if (yasm__strcasecmp(s, "basic_block") == 0) | 1064 else if (yasm__strcasecmp(s, "basic_block") == 0) |
975 loc->basic_block = 1; | 1065 loc->basic_block = 1; |
976 else if (yasm__strcasecmp(s, "prologue_end") == 0) | 1066 else if (yasm__strcasecmp(s, "prologue_end") == 0) |
977 loc->prologue_end = 1; | 1067 loc->prologue_end = 1; |
978 else if (yasm__strcasecmp(s, "epilogue_begin") == 0) | 1068 else if (yasm__strcasecmp(s, "epilogue_begin") == 0) |
979 loc->epilogue_begin = 1; | 1069 loc->epilogue_begin = 1; |
980 else | 1070 else |
981 yasm_warn_set(YASM_WARN_GENERAL, | 1071 yasm_warn_set(YASM_WARN_GENERAL, |
982 N_("unrecognized loc option `%s'"), s); | 1072 N_("unrecognized loc option `%s'"), s); |
983 } else if (!vp->val) { | 1073 } else if (!vp->val) { |
984 yasm_warn_set(YASM_WARN_GENERAL, | 1074 yasm_warn_set(YASM_WARN_GENERAL, |
985 N_("unrecognized numeric qualifier")); | 1075 N_("unrecognized numeric qualifier")); |
986 } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) { | 1076 } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) { |
987 in_is_stmt = 1; | 1077 in_is_stmt = 1; |
988 goto restart; /* don't go to the next valparam */ | 1078 goto restart; /* don't go to the next valparam */ |
989 } else if (yasm__strcasecmp(vp->val, "isa") == 0) { | 1079 } else if (yasm__strcasecmp(vp->val, "isa") == 0) { |
990 in_isa = 1; | 1080 in_isa = 1; |
991 goto restart; /* don't go to the next valparam */ | 1081 goto restart; /* don't go to the next valparam */ |
| 1082 } else if (yasm__strcasecmp(vp->val, "discriminator") == 0) { |
| 1083 in_discriminator = 1; |
| 1084 goto restart; /* don't go to the next valparam */ |
992 } else | 1085 } else |
993 yasm_warn_set(YASM_WARN_GENERAL, | 1086 yasm_warn_set(YASM_WARN_GENERAL, |
994 N_("unrecognized loc option `%s'"), vp->val); | 1087 N_("unrecognized loc option `%s'"), vp->val); |
995 vp = yasm_vps_next(vp); | 1088 vp = yasm_vps_next(vp); |
996 } | 1089 } |
997 | 1090 |
998 if (in_is_stmt || in_isa) { | 1091 if (in_is_stmt || in_isa || in_discriminator) { |
999 yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"), | 1092 yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"), |
1000 in_is_stmt ? "is_stmt" : "isa"); | 1093 in_is_stmt ? "is_stmt" : |
| 1094 (in_isa ? "isa" : "discriminator")); |
1001 yasm_xfree(loc); | 1095 yasm_xfree(loc); |
1002 return; | 1096 return; |
1003 } | 1097 } |
1004 | 1098 |
1005 /* Append new location */ | 1099 /* Append new location */ |
1006 loc->vline = line; | 1100 loc->vline = line; |
1007 loc->bc = NULL; | 1101 loc->bc = NULL; |
1008 loc->sym = NULL; | 1102 loc->sym = NULL; |
1009 STAILQ_INSERT_TAIL(&dsd->locs, loc, link); | 1103 STAILQ_INSERT_TAIL(&dsd->locs, loc, link); |
1010 } | 1104 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 | 1136 |
1043 vp = yasm_vps_next(vp); | 1137 vp = yasm_vps_next(vp); |
1044 if (!yasm_vp_string(vp)) { | 1138 if (!yasm_vp_string(vp)) { |
1045 yasm_error_set(YASM_ERROR_SYNTAX, | 1139 yasm_error_set(YASM_ERROR_SYNTAX, |
1046 N_("file number given but no filename")); | 1140 N_("file number given but no filename")); |
1047 return; | 1141 return; |
1048 } | 1142 } |
1049 | 1143 |
1050 dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp)); | 1144 dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp)); |
1051 } | 1145 } |
OLD | NEW |