1 /* 2 * DWARF2 debugging format - line information 3 * 4 * Copyright (C) 2006-2007 Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the author nor the names of other contributors 15 * may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 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 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 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include <util.h> 31 32 #include <libyasm.h> 33 34 #include "dwarf2-dbgfmt.h" 35 36 /* DWARF line number opcodes */ 37 typedef enum { 38 DW_LNS_extended_op = 0, 39 DW_LNS_copy, 40 DW_LNS_advance_pc, 41 DW_LNS_advance_line, 42 DW_LNS_set_file, 43 DW_LNS_set_column, 44 DW_LNS_negate_stmt, 45 DW_LNS_set_basic_block, 46 DW_LNS_const_add_pc, 47 DW_LNS_fixed_advance_pc, 48 #ifdef WITH_DWARF3 49 /* DWARF 3 extensions */ 50 DW_LNS_set_prologue_end, 51 DW_LNS_set_epilogue_begin, 52 DW_LNS_set_isa, 53 #endif 54 DWARF2_LINE_OPCODE_BASE 55 } dwarf_line_number_op; 56 57 /* # of LEB128 operands needed for each of the above opcodes */ 58 static unsigned char line_opcode_num_operands[DWARF2_LINE_OPCODE_BASE-1] = { 59 0, /* DW_LNS_copy */ 60 1, /* DW_LNS_advance_pc */ 61 1, /* DW_LNS_advance_line */ 62 1, /* DW_LNS_set_file */ 63 1, /* DW_LNS_set_column */ 64 0, /* DW_LNS_negate_stmt */ 65 0, /* DW_LNS_set_basic_block */ 66 0, /* DW_LNS_const_add_pc */ 67 1, /* DW_LNS_fixed_advance_pc */ 68 #ifdef WITH_DWARF3 69 0, /* DW_LNS_set_prologue_end */ 70 0, /* DW_LNS_set_epilogue_begin */ 71 1 /* DW_LNS_set_isa */ 72 #endif 73 }; 74 75 /* Line number extended opcodes */ 76 typedef enum { 77 DW_LNE_end_sequence = 1, 78 DW_LNE_set_address, 79 DW_LNE_define_file, 80 DW_LNE_set_discriminator 81 } dwarf_line_number_ext_op; 82 83 /* Base and range for line offsets in special opcodes */ 84 #define DWARF2_LINE_BASE -5 85 #define DWARF2_LINE_RANGE 14 86 87 #define DWARF2_MAX_SPECIAL_ADDR_DELTA \ 88 (((255-DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)*\ 89 dbgfmt_dwarf2->min_insn_len) 90 91 /* Initial value of is_stmt register */ 92 #define DWARF2_LINE_DEFAULT_IS_STMT 1 93 94 /* Line number state machine register state */ 95 typedef struct dwarf2_line_state { 96 /* static configuration */ 97 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; 98 99 /* DWARF2 state machine registers */ 100 unsigned long address; 101 unsigned long file; 102 unsigned long line; 103 unsigned long column; 104 unsigned long isa; 105 int is_stmt; 106 107 /* other state information */ 108 /*@null@*/ yasm_bytecode *precbc; 109 } dwarf2_line_state; 110 111 typedef struct dwarf2_spp { 112 yasm_bytecode *line_start_prevbc; 113 yasm_bytecode *line_end_prevbc; 114 } dwarf2_spp; 115 116 typedef struct dwarf2_line_op { 117 dwarf_line_number_op opcode; 118 /*@owned@*/ /*@null@*/ yasm_intnum *operand; 119 120 /* extended opcode */ 121 dwarf_line_number_ext_op ext_opcode; 122 /*@null@*/ /*@dependent@*/ yasm_symrec *ext_operand; /* unsigned */ 123 /*@null@*/ /*@dependent@*/ yasm_intnum *ext_operand_int; /* unsigned */ 124 unsigned long ext_operandsize; 125 } dwarf2_line_op; 126 127 /* Bytecode callback function prototypes */ 128 static void dwarf2_spp_bc_destroy(void *contents); 129 static void dwarf2_spp_bc_print(const void *contents, FILE *f, 130 int indent_level); 131 static int dwarf2_spp_bc_calc_len 132 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); 133 static int dwarf2_spp_bc_tobytes 134 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, 135 yasm_output_value_func output_value, 136 /*@null@*/ yasm_output_reloc_func output_reloc); 137 138 static void dwarf2_line_op_bc_destroy(void *contents); 139 static void dwarf2_line_op_bc_print(const void *contents, FILE *f, 140 int indent_level); 141 static int dwarf2_line_op_bc_calc_len 142 (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data); 143 static int dwarf2_line_op_bc_tobytes 144 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, 145 yasm_output_value_func output_value, 146 /*@null@*/ yasm_output_reloc_func output_reloc); 147 148 /* Bytecode callback structures */ 149 static const yasm_bytecode_callback dwarf2_spp_bc_callback = { 150 dwarf2_spp_bc_destroy, 151 dwarf2_spp_bc_print, 152 yasm_bc_finalize_common, 153 NULL, 154 dwarf2_spp_bc_calc_len, 155 yasm_bc_expand_common, 156 dwarf2_spp_bc_tobytes, 157 0 158 }; 159 160 static const yasm_bytecode_callback dwarf2_line_op_bc_callback = { 161 dwarf2_line_op_bc_destroy, 162 dwarf2_line_op_bc_print, 163 yasm_bc_finalize_common, 164 NULL, 165 dwarf2_line_op_bc_calc_len, 166 yasm_bc_expand_common, 167 dwarf2_line_op_bc_tobytes, 168 0 169 }; 170 171 172 static size_t 173 dwarf2_dbgfmt_add_file(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, unsigned long filenum, 174 const char *pathname) 175 { 176 size_t dirlen; 177 const char *filename; 178 unsigned long i, dir; 179 180 /* Put the directory into the directory table */ 181 dir = 0; 182 dirlen = yasm__splitpath(pathname, &filename); 183 if (dirlen > 0) { 184 /* Look to see if we already have that dir in the table */ 185 for (dir=1; dir<dbgfmt_dwarf2->dirs_size+1; dir++) { 186 if (strncmp(dbgfmt_dwarf2->dirs[dir-1], pathname, dirlen) == 0 187 && dbgfmt_dwarf2->dirs[dir-1][dirlen] == '\0') 188 break; 189 } 190 if (dir >= dbgfmt_dwarf2->dirs_size+1) { 191 /* Not found in table, add to end, reallocing if necessary */ 192 if (dir >= dbgfmt_dwarf2->dirs_allocated+1) { 193 dbgfmt_dwarf2->dirs_allocated = dir+32; 194 dbgfmt_dwarf2->dirs = yasm_xrealloc(dbgfmt_dwarf2->dirs, 195 sizeof(char *)*dbgfmt_dwarf2->dirs_allocated); 196 } 197 dbgfmt_dwarf2->dirs[dir-1] = yasm__xstrndup(pathname, dirlen); 198 dbgfmt_dwarf2->dirs_size = dir; 199 } 200 } 201 202 /* Put the filename into the filename table */ 203 if (filenum == 0) { 204 /* Look to see if we already have that filename in the table */ 205 for (; filenum<dbgfmt_dwarf2->filenames_size; filenum++) { 206 if (!dbgfmt_dwarf2->filenames[filenum].filename || 207 (dbgfmt_dwarf2->filenames[filenum].dir == dir 208 && strcmp(dbgfmt_dwarf2->filenames[filenum].filename, 209 filename) == 0)) 210 break; 211 } 212 } else 213 filenum--; /* array index is 0-based */ 214 215 /* Realloc table if necessary */ 216 if (filenum >= dbgfmt_dwarf2->filenames_allocated) { 217 unsigned long old_allocated = dbgfmt_dwarf2->filenames_allocated; 218 dbgfmt_dwarf2->filenames_allocated = filenum+32; 219 dbgfmt_dwarf2->filenames = yasm_xrealloc(dbgfmt_dwarf2->filenames, 220 sizeof(dwarf2_filename)*dbgfmt_dwarf2->filenames_allocated); 221 for (i=old_allocated; i<dbgfmt_dwarf2->filenames_allocated; i++) { 222 dbgfmt_dwarf2->filenames[i].pathname = NULL; 223 dbgfmt_dwarf2->filenames[i].filename = NULL; 224 dbgfmt_dwarf2->filenames[i].dir = 0; 225 } 226 } 227 228 /* Actually save in table */ 229 if (dbgfmt_dwarf2->filenames[filenum].pathname) 230 yasm_xfree(dbgfmt_dwarf2->filenames[filenum].pathname); 231 if (dbgfmt_dwarf2->filenames[filenum].filename) 232 yasm_xfree(dbgfmt_dwarf2->filenames[filenum].filename); 233 dbgfmt_dwarf2->filenames[filenum].pathname = yasm__xstrdup(pathname); 234 dbgfmt_dwarf2->filenames[filenum].filename = yasm__xstrdup(filename); 235 dbgfmt_dwarf2->filenames[filenum].dir = dir; 236 237 /* Update table size */ 238 if (filenum >= dbgfmt_dwarf2->filenames_size) 239 dbgfmt_dwarf2->filenames_size = filenum + 1; 240 241 return filenum; 242 } 243 244 /* Create and add a new line opcode to a section, updating offset on insertion; 245 * no optimization necessary. 246 */ 247 static yasm_bytecode * 248 dwarf2_dbgfmt_append_line_op(yasm_section *sect, dwarf_line_number_op opcode, 249 /*@only@*/ /*@null@*/ yasm_intnum *operand) 250 { 251 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); 252 yasm_bytecode *bc; 253 254 line_op->opcode = opcode; 255 line_op->operand = operand; 256 line_op->ext_opcode = 0; 257 line_op->ext_operand = NULL; 258 line_op->ext_operand_int = NULL; 259 line_op->ext_operandsize = 0; 260 261 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); 262 bc->len = 1; 263 if (operand) 264 bc->len += yasm_intnum_size_leb128(operand, 265 opcode == DW_LNS_advance_line); 266 267 yasm_dwarf2__append_bc(sect, bc); 268 return bc; 269 } 270 271 /* Create and add a new extended line opcode to a section, updating offset on 272 * insertion; no optimization necessary. 273 */ 274 static yasm_bytecode * 275 dwarf2_dbgfmt_append_line_ext_op(yasm_section *sect, 276 dwarf_line_number_ext_op ext_opcode, 277 unsigned long ext_operandsize, 278 /*@null@*/ yasm_symrec *ext_operand) 279 { 280 dwarf2_line_op *line_op = yasm_xmalloc(sizeof(dwarf2_line_op)); 281 yasm_bytecode *bc; 282 283 line_op->opcode = DW_LNS_extended_op; 284 line_op->operand = yasm_intnum_create_uint(ext_operandsize+1); 285 line_op->ext_opcode = ext_opcode; 286 line_op->ext_operand = ext_operand; 287 line_op->ext_operand_int = NULL; 288 line_op->ext_operandsize = ext_operandsize; 289 290 bc = yasm_bc_create_common(&dwarf2_line_op_bc_callback, line_op, 0); 291 bc->len = 2 + yasm_intnum_size_leb128(line_op->operand, 0) + 292 ext_operandsize; 293 294 yasm_dwarf2__append_bc(sect, bc); 295 return bc; 296 } 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 322 static void 323 dwarf2_dbgfmt_finalize_locs(yasm_section *sect, dwarf2_section_data *dsd) 324 { 325 /*@dependent@*/ yasm_symrec *lastsym = NULL; 326 /*@null@*/ yasm_bytecode *bc; 327 /*@null@*/ dwarf2_loc *loc; 328 329 bc = yasm_section_bcs_first(sect); 330 STAILQ_FOREACH(loc, &dsd->locs, link) { 331 /* Find the first bytecode following this loc by looking at 332 * the virtual line numbers. XXX: this assumes the source file 333 * order will be the same as the actual section order. If we ever 334 * implement subsegs this will NOT necessarily be true and this logic 335 * will need to be fixed to handle it! 336 * 337 * Keep track of last symbol seen prior to the loc. 338 */ 339 while (bc && bc->line <= loc->vline) { 340 if (bc->symrecs) { 341 int i = 0; 342 while (bc->symrecs[i]) { 343 lastsym = bc->symrecs[i]; 344 i++; 345 } 346 } 347 bc = yasm_bc__next(bc); 348 } 349 loc->sym = lastsym; 350 loc->bc = bc; 351 } 352 } 353 354 static int 355 dwarf2_dbgfmt_gen_line_op(yasm_section *debug_line, dwarf2_line_state *state, 356 const dwarf2_loc *loc, 357 /*@null@*/ const dwarf2_loc *nextloc) 358 { 359 unsigned long addr_delta; 360 long line_delta; 361 int opcode1, opcode2; 362 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = state->dbgfmt_dwarf2; 363 364 if (state->file != loc->file) { 365 state->file = loc->file; 366 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_file, 367 yasm_intnum_create_uint(state->file)); 368 } 369 if (state->column != loc->column) { 370 state->column = loc->column; 371 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_column, 372 yasm_intnum_create_uint(state->column)); 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 } 379 #ifdef WITH_DWARF3 380 if (loc->isa_change) { 381 state->isa = loc->isa; 382 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_isa, 383 yasm_intnum_create_uint(state->isa)); 384 } 385 #endif 386 if (state->is_stmt == 0 && loc->is_stmt == IS_STMT_SET) { 387 state->is_stmt = 1; 388 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); 389 } else if (state->is_stmt == 1 && loc->is_stmt == IS_STMT_CLEAR) { 390 state->is_stmt = 0; 391 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_negate_stmt, NULL); 392 } 393 if (loc->basic_block) { 394 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_basic_block, NULL); 395 } 396 #ifdef WITH_DWARF3 397 if (loc->prologue_end) { 398 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_prologue_end, NULL); 399 } 400 if (loc->epilogue_begin) { 401 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_set_epilogue_begin, 402 NULL); 403 } 404 #endif 405 406 /* If multiple loc for the same location, use last */ 407 if (nextloc && nextloc->bc->offset == loc->bc->offset) 408 return 0; 409 410 if (!state->precbc) { 411 /* Set the starting address for the section */ 412 if (!loc->sym) { 413 /* shouldn't happen! */ 414 yasm_error_set(YASM_ERROR_GENERAL, 415 N_("could not find label prior to loc")); 416 return 1; 417 } 418 dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address, 419 dbgfmt_dwarf2->sizeof_address, loc->sym); 420 addr_delta = 0; 421 } else if (loc->bc) { 422 if (state->precbc->offset > loc->bc->offset) 423 yasm_internal_error(N_("dwarf2 address went backwards?")); 424 addr_delta = loc->bc->offset - state->precbc->offset; 425 } else 426 return 0; /* ran out of bytecodes! XXX: do something? */ 427 428 /* Generate appropriate opcode(s). Address can only increment, 429 * whereas line number can go backwards. 430 */ 431 line_delta = loc->line - state->line; 432 state->line = loc->line; 433 434 /* First handle the line delta */ 435 if (line_delta < DWARF2_LINE_BASE 436 || line_delta >= DWARF2_LINE_BASE+DWARF2_LINE_RANGE) { 437 /* Won't fit in special opcode, use (signed) line advance */ 438 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_line, 439 yasm_intnum_create_int(line_delta)); 440 line_delta = 0; 441 } 442 443 /* Next handle the address delta */ 444 opcode1 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + 445 DWARF2_LINE_RANGE * (addr_delta / dbgfmt_dwarf2->min_insn_len); 446 opcode2 = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE + 447 DWARF2_LINE_RANGE * ((addr_delta - DWARF2_MAX_SPECIAL_ADDR_DELTA) / 448 dbgfmt_dwarf2->min_insn_len); 449 if (line_delta == 0 && addr_delta == 0) { 450 /* Both line and addr deltas are 0: do DW_LNS_copy */ 451 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL); 452 } else if (addr_delta <= DWARF2_MAX_SPECIAL_ADDR_DELTA && opcode1 <= 255) { 453 /* Addr delta in range of special opcode */ 454 dwarf2_dbgfmt_append_line_op(debug_line, opcode1, NULL); 455 } else if (addr_delta <= 2*DWARF2_MAX_SPECIAL_ADDR_DELTA 456 && opcode2 <= 255) { 457 /* Addr delta in range of const_add_pc + special */ 458 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_const_add_pc, NULL); 459 dwarf2_dbgfmt_append_line_op(debug_line, opcode2, NULL); 460 } else { 461 /* Need advance_pc */ 462 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_advance_pc, 463 yasm_intnum_create_uint(addr_delta)); 464 /* Take care of any remaining line_delta and add entry to matrix */ 465 if (line_delta == 0) 466 dwarf2_dbgfmt_append_line_op(debug_line, DW_LNS_copy, NULL); 467 else { 468 unsigned int opcode; 469 opcode = DWARF2_LINE_OPCODE_BASE + line_delta - DWARF2_LINE_BASE; 470 dwarf2_dbgfmt_append_line_op(debug_line, opcode, NULL); 471 } 472 } 473 state->precbc = loc->bc; 474 return 0; 475 } 476 477 typedef struct dwarf2_line_bc_info { 478 yasm_section *debug_line; 479 yasm_object *object; 480 yasm_linemap *linemap; 481 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; 482 dwarf2_line_state *state; 483 dwarf2_loc loc; 484 unsigned long lastfile; 485 } dwarf2_line_bc_info; 486 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 509 dwarf2_generate_line_bc(yasm_bytecode *bc, /*@null@*/ void *d) 510 { 511 dwarf2_line_bc_info *info = (dwarf2_line_bc_info *)d; 512 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; 513 unsigned long i; 514 size_t dirlen; 515 const char *pathname, *filename; 516 /*@null@*/ yasm_bytecode *nextbc = yasm_bc__next(bc); 517 518 if (nextbc && bc->offset == nextbc->offset) 519 return 0; 520 521 info->loc.vline = bc->line; 522 info->loc.bc = bc; 523 524 /* Keep track of last symbol seen */ 525 if (bc->symrecs) { 526 i = 0; 527 while (bc->symrecs[i]) { 528 info->loc.sym = bc->symrecs[i]; 529 i++; 530 } 531 } 532 533 yasm_linemap_lookup(info->linemap, bc->line, &pathname, &info->loc.line); 534 dirlen = yasm__splitpath(pathname, &filename); 535 536 /* Find file index; just linear search it unless it was the last used */ 537 if (info->lastfile > 0 538 && dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[info->lastfile-1], 539 dbgfmt_dwarf2->dirs, pathname, dirlen, 540 filename)) 541 info->loc.file = info->lastfile; 542 else { 543 for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { 544 if (dwarf2_filename_equals(&dbgfmt_dwarf2->filenames[i], 545 dbgfmt_dwarf2->dirs, pathname, dirlen, 546 filename)) 547 break; 548 } 549 if (i >= dbgfmt_dwarf2->filenames_size) 550 yasm_internal_error(N_("could not find filename in table")); 551 info->loc.file = i+1; 552 info->lastfile = i+1; 553 } 554 if (dwarf2_dbgfmt_gen_line_op(info->debug_line, info->state, &info->loc, 555 NULL)) 556 return 1; 557 return 0; 558 } 559 560 typedef struct dwarf2_line_info { 561 yasm_section *debug_line; /* section to which line number info goes */ 562 yasm_object *object; 563 yasm_linemap *linemap; 564 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2; 565 yasm_errwarns *errwarns; 566 567 /* Generate based on bytecodes (1) or locs (0)? Use bytecodes if we're 568 * generating line numbers for the actual assembly source file. 569 */ 570 int asm_source; 571 572 /* number of sections line number info generated for */ 573 size_t num_sections; 574 /* last section line number info generated for */ 575 /*@null@*/ yasm_section *last_code; 576 } dwarf2_line_info; 577 578 static int 579 dwarf2_generate_line_section(yasm_section *sect, /*@null@*/ void *d) 580 { 581 dwarf2_line_info *info = (dwarf2_line_info *)d; 582 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; 583 /*@null@*/ dwarf2_section_data *dsd; 584 /*@null@*/ yasm_bytecode *bc; 585 dwarf2_line_state state; 586 unsigned long addr_delta; 587 588 dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb); 589 if (!dsd) { 590 if (info->asm_source && yasm_section_is_code(sect)) { 591 /* Create line data for asm code sections */ 592 dsd = yasm_xmalloc(sizeof(dwarf2_section_data)); 593 STAILQ_INIT(&dsd->locs); 594 yasm_section_add_data(sect, &yasm_dwarf2__section_data_cb, dsd); 595 } else 596 return 0; /* no line data for this section */ 597 } 598 599 info->num_sections++; 600 info->last_code = sect; 601 602 /* initialize state machine registers for each sequence */ 603 state.dbgfmt_dwarf2 = dbgfmt_dwarf2; 604 state.address = 0; 605 state.file = 1; 606 state.line = 1; 607 state.column = 0; 608 state.isa = 0; 609 state.is_stmt = DWARF2_LINE_DEFAULT_IS_STMT; 610 state.precbc = NULL; 611 612 if (info->asm_source) { 613 dwarf2_line_bc_info bcinfo; 614 615 bcinfo.debug_line = info->debug_line; 616 bcinfo.object = info->object; 617 bcinfo.linemap = info->linemap; 618 bcinfo.dbgfmt_dwarf2 = dbgfmt_dwarf2; 619 bcinfo.state = &state; 620 bcinfo.lastfile = 0; 621 bcinfo.loc.isa_change = 0; 622 bcinfo.loc.column = 0; 623 bcinfo.loc.discriminator = 0; 624 bcinfo.loc.is_stmt = IS_STMT_NOCHANGE; 625 bcinfo.loc.basic_block = 0; 626 bcinfo.loc.prologue_end = 0; 627 bcinfo.loc.epilogue_begin = 0; 628 bcinfo.loc.sym = NULL; 629 630 /* bcs_traverse() skips first "dummy" bytecode, so look at it 631 * separately to determine the initial symrec. 632 */ 633 bc = yasm_section_bcs_first(sect); 634 if (bc->symrecs) { 635 size_t i = 0; 636 while (bc->symrecs[i]) { 637 bcinfo.loc.sym = bc->symrecs[i]; 638 i++; 639 } 640 } 641 642 yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo, 643 dwarf2_generate_line_bc); 644 } else { 645 /*@null@*/ dwarf2_loc *loc; 646 647 dwarf2_dbgfmt_finalize_locs(sect, dsd); 648 649 STAILQ_FOREACH(loc, &dsd->locs, link) { 650 if (dwarf2_dbgfmt_gen_line_op(info->debug_line, &state, loc, 651 STAILQ_NEXT(loc, link))) 652 return 1; 653 } 654 } 655 656 /* End sequence: bring address to end of section, then output end 657 * sequence opcode. Don't use a special opcode to do this as we don't 658 * want an extra entry in the line matrix. 659 */ 660 if (!state.precbc) 661 state.precbc = yasm_section_bcs_first(sect); 662 bc = yasm_section_bcs_last(sect); 663 addr_delta = yasm_bc_next_offset(bc) - state.precbc->offset; 664 if (addr_delta == DWARF2_MAX_SPECIAL_ADDR_DELTA) 665 dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_const_add_pc, 666 NULL); 667 else if (addr_delta > 0) 668 dwarf2_dbgfmt_append_line_op(info->debug_line, DW_LNS_advance_pc, 669 yasm_intnum_create_uint(addr_delta)); 670 dwarf2_dbgfmt_append_line_ext_op(info->debug_line, DW_LNE_end_sequence, 0, 671 NULL); 672 673 return 0; 674 } 675 676 static int 677 dwarf2_generate_filename(const char *filename, void *d) 678 { 679 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)d; 680 dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, 0, filename); 681 return 0; 682 } 683 684 yasm_section * 685 yasm_dwarf2__generate_line(yasm_object *object, yasm_linemap *linemap, 686 yasm_errwarns *errwarns, int asm_source, 687 /*@out@*/ yasm_section **main_code, 688 /*@out@*/ size_t *num_line_sections) 689 { 690 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; 691 dwarf2_line_info info; 692 int new; 693 size_t i; 694 yasm_bytecode *last, *sppbc; 695 dwarf2_spp *spp; 696 dwarf2_head *head; 697 698 if (asm_source) { 699 /* Generate dirs and filenames based on linemap */ 700 yasm_linemap_traverse_filenames(linemap, dbgfmt_dwarf2, 701 dwarf2_generate_filename); 702 } 703 704 info.num_sections = 0; 705 info.last_code = NULL; 706 info.asm_source = asm_source; 707 info.object = object; 708 info.linemap = linemap; 709 info.dbgfmt_dwarf2 = dbgfmt_dwarf2; 710 info.debug_line = yasm_object_get_general(object, ".debug_line", 1, 0, 0, 711 &new, 0); 712 last = yasm_section_bcs_last(info.debug_line); 713 714 /* header */ 715 head = yasm_dwarf2__add_head(dbgfmt_dwarf2, info.debug_line, NULL, 0, 0); 716 717 /* statement program prologue */ 718 spp = yasm_xmalloc(sizeof(dwarf2_spp)); 719 sppbc = yasm_bc_create_common(&dwarf2_spp_bc_callback, spp, 0); 720 sppbc->len = dbgfmt_dwarf2->sizeof_offset + 5 + 721 NELEMS(line_opcode_num_operands); 722 723 /* directory list */ 724 for (i=0; i<dbgfmt_dwarf2->dirs_size; i++) 725 sppbc->len += (unsigned long)strlen(dbgfmt_dwarf2->dirs[i])+1; 726 sppbc->len++; 727 728 /* filename list */ 729 for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { 730 if (!dbgfmt_dwarf2->filenames[i].filename) { 731 yasm_error_set(YASM_ERROR_GENERAL, 732 N_("dwarf2 file number %d unassigned"), i+1); 733 yasm_errwarn_propagate(errwarns, 0); 734 continue; 735 } 736 sppbc->len += 737 (unsigned long)strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 + 738 yasm_size_uleb128(dbgfmt_dwarf2->filenames[i].dir) + 2; 739 } 740 sppbc->len++; 741 yasm_dwarf2__append_bc(info.debug_line, sppbc); 742 743 /* statement program */ 744 yasm_object_sections_traverse(object, (void *)&info, 745 dwarf2_generate_line_section); 746 747 /* mark end of line information */ 748 yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(info.debug_line)); 749 750 *num_line_sections = info.num_sections; 751 if (info.num_sections == 1) 752 *main_code = info.last_code; 753 else 754 *main_code = NULL; 755 return info.debug_line; 756 } 757 758 static void 759 dwarf2_spp_bc_destroy(void *contents) 760 { 761 yasm_xfree(contents); 762 } 763 764 static void 765 dwarf2_spp_bc_print(const void *contents, FILE *f, int indent_level) 766 { 767 /* TODO */ 768 } 769 770 static int 771 dwarf2_spp_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 772 void *add_span_data) 773 { 774 yasm_internal_error(N_("tried to calc_len a dwarf2 spp bytecode")); 775 /*@notreached@*/ 776 return 0; 777 } 778 779 static int 780 dwarf2_spp_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, 781 unsigned char *bufstart, void *d, 782 yasm_output_value_func output_value, 783 yasm_output_reloc_func output_reloc) 784 { 785 yasm_object *object = yasm_section_get_object(bc->section); 786 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; 787 unsigned char *buf = *bufp; 788 yasm_intnum *cval; 789 size_t i, len; 790 791 /* Prologue length (following this field) */ 792 cval = yasm_intnum_create_uint(bc->len - (unsigned long)(buf-*bufp) - 793 dbgfmt_dwarf2->sizeof_offset); 794 yasm_arch_intnum_tobytes(object->arch, cval, buf, 795 dbgfmt_dwarf2->sizeof_offset, 796 dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0); 797 buf += dbgfmt_dwarf2->sizeof_offset; 798 799 YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len); /* minimum_instr_len */ 800 YASM_WRITE_8(buf, DWARF2_LINE_DEFAULT_IS_STMT); /* default_is_stmt */ 801 YASM_WRITE_8(buf, DWARF2_LINE_BASE); /* line_base */ 802 YASM_WRITE_8(buf, DWARF2_LINE_RANGE); /* line_range */ 803 YASM_WRITE_8(buf, DWARF2_LINE_OPCODE_BASE); /* opcode_base */ 804 805 /* Standard opcode # operands array */ 806 for (i=0; i<NELEMS(line_opcode_num_operands); i++) 807 YASM_WRITE_8(buf, line_opcode_num_operands[i]); 808 809 /* directory list */ 810 for (i=0; i<dbgfmt_dwarf2->dirs_size; i++) { 811 len = strlen(dbgfmt_dwarf2->dirs[i])+1; 812 memcpy(buf, dbgfmt_dwarf2->dirs[i], len); 813 buf += len; 814 } 815 /* finish with single 0 byte */ 816 YASM_WRITE_8(buf, 0); 817 818 /* filename list */ 819 for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) { 820 len = strlen(dbgfmt_dwarf2->filenames[i].filename)+1; 821 memcpy(buf, dbgfmt_dwarf2->filenames[i].filename, len); 822 buf += len; 823 824 /* dir */ 825 buf += yasm_get_uleb128(dbgfmt_dwarf2->filenames[i].dir, buf); 826 YASM_WRITE_8(buf, 0); /* time */ 827 YASM_WRITE_8(buf, 0); /* length */ 828 } 829 /* finish with single 0 byte */ 830 YASM_WRITE_8(buf, 0); 831 832 *bufp = buf; 833 834 yasm_intnum_destroy(cval); 835 return 0; 836 } 837 838 static void 839 dwarf2_line_op_bc_destroy(void *contents) 840 { 841 dwarf2_line_op *line_op = (dwarf2_line_op *)contents; 842 if (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); 846 yasm_xfree(contents); 847 } 848 849 static void 850 dwarf2_line_op_bc_print(const void *contents, FILE *f, int indent_level) 851 { 852 /* TODO */ 853 } 854 855 static int 856 dwarf2_line_op_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 857 void *add_span_data) 858 { 859 yasm_internal_error(N_("tried to calc_len a dwarf2 line_op bytecode")); 860 /*@notreached@*/ 861 return 0; 862 } 863 864 static int 865 dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, 866 unsigned char *bufstart, void *d, 867 yasm_output_value_func output_value, 868 yasm_output_reloc_func output_reloc) 869 { 870 dwarf2_line_op *line_op = (dwarf2_line_op *)bc->contents; 871 unsigned char *buf = *bufp; 872 873 YASM_WRITE_8(buf, line_op->opcode); 874 if (line_op->operand) 875 buf += yasm_intnum_get_leb128(line_op->operand, buf, 876 line_op->opcode == DW_LNS_advance_line); 877 if (line_op->ext_opcode > 0) { 878 YASM_WRITE_8(buf, line_op->ext_opcode); 879 if (line_op->ext_operand) { 880 yasm_value value; 881 yasm_value_init_sym(&value, line_op->ext_operand, 882 line_op->ext_operandsize*8); 883 output_value(&value, buf, line_op->ext_operandsize, 884 (unsigned long)(buf-bufstart), bc, 0, d); 885 buf += line_op->ext_operandsize; 886 } 887 if (line_op->ext_operand_int) { 888 buf += yasm_intnum_get_leb128(line_op->ext_operand_int, buf, 0); 889 } 890 } 891 892 *bufp = buf; 893 return 0; 894 } 895 896 void 897 yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams, 898 yasm_valparamhead *objext_valparams, unsigned long line) 899 { 900 yasm_valparam *vp; 901 int in_is_stmt = 0, in_isa = 0, in_discriminator = 0; 902 903 /*@dependent@*/ /*@null@*/ const yasm_intnum *intn; 904 dwarf2_section_data *dsd; 905 dwarf2_loc *loc = yasm_xmalloc(sizeof(dwarf2_loc)); 906 907 /* File number (required) */ 908 if (!valparams || !(vp = yasm_vps_first(valparams)) || 909 vp->val || vp->type != YASM_PARAM_EXPR) { 910 yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required")); 911 yasm_xfree(loc); 912 return; 913 } 914 intn = yasm_expr_get_intnum(&vp->param.e, 0); 915 if (!intn) { 916 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 917 N_("file number is not a constant")); 918 yasm_xfree(loc); 919 return; 920 } 921 if (yasm_intnum_sign(intn) != 1) { 922 yasm_error_set(YASM_ERROR_VALUE, N_("file number less than one")); 923 yasm_xfree(loc); 924 return; 925 } 926 loc->file = yasm_intnum_get_uint(intn); 927 928 /* Line number (required) */ 929 vp = yasm_vps_next(vp); 930 if (!vp || vp->val || vp->type != YASM_PARAM_EXPR) { 931 yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required")); 932 yasm_xfree(loc); 933 return; 934 } 935 intn = yasm_expr_get_intnum(&vp->param.e, 0); 936 if (!intn) { 937 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 938 N_("line number is not a constant")); 939 yasm_xfree(loc); 940 return; 941 } 942 loc->line = yasm_intnum_get_uint(intn); 943 944 /* Generate new section data if it doesn't already exist */ 945 if (!object->cur_section) { 946 yasm_error_set(YASM_ERROR_SYNTAX, 947 N_("[%s] can only be used inside of a section"), "loc"); 948 yasm_xfree(loc); 949 return; 950 } 951 dsd = yasm_section_get_data(object->cur_section, 952 &yasm_dwarf2__section_data_cb); 953 if (!dsd) { 954 dsd = yasm_xmalloc(sizeof(dwarf2_section_data)); 955 STAILQ_INIT(&dsd->locs); 956 yasm_section_add_data(object->cur_section, 957 &yasm_dwarf2__section_data_cb, dsd); 958 } 959 960 /* Defaults for optional settings */ 961 loc->column = 0; 962 loc->discriminator = 0; 963 loc->isa_change = 0; 964 loc->isa = 0; 965 loc->is_stmt = IS_STMT_NOCHANGE; 966 loc->basic_block = 0; 967 loc->prologue_end = 0; 968 loc->epilogue_begin = 0; 969 970 /* Optional column number */ 971 vp = yasm_vps_next(vp); 972 if (vp && !vp->val && vp->type == YASM_PARAM_EXPR) { 973 intn = yasm_expr_get_intnum(&vp->param.e, 0); 974 if (!intn) { 975 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 976 N_("column number is not a constant")); 977 yasm_xfree(loc); 978 return; 979 } 980 loc->column = yasm_intnum_get_uint(intn); 981 vp = yasm_vps_next(vp); 982 } 983 984 /* Other options; note for GAS compatibility we need to support both: 985 * is_stmt=1 (NASM) and 986 * is_stmt 1 (GAS) 987 */ 988 while (vp) { 989 /*@null@*/ /*@dependent@*/ const char *s; 990 /*@null@*/ /*@only@*/ yasm_expr *e; 991 992 restart: 993 if (in_is_stmt) { 994 in_is_stmt = 0; 995 if (!(e = yasm_vp_expr(vp, object->symtab, line)) || 996 !(intn = yasm_expr_get_intnum(&e, 0))) { 997 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 998 N_("is_stmt value is not a constant")); 999 yasm_xfree(loc); 1000 if (e) 1001 yasm_expr_destroy(e); 1002 return; 1003 } 1004 if (yasm_intnum_is_zero(intn)) 1005 loc->is_stmt = IS_STMT_SET; 1006 else if (yasm_intnum_is_pos1(intn)) 1007 loc->is_stmt = IS_STMT_CLEAR; 1008 else { 1009 yasm_error_set(YASM_ERROR_VALUE, 1010 N_("is_stmt value not 0 or 1")); 1011 yasm_xfree(loc); 1012 yasm_expr_destroy(e); 1013 return; 1014 } 1015 yasm_expr_destroy(e); 1016 } else if (in_isa) { 1017 in_isa = 0; 1018 if (!(e = yasm_vp_expr(vp, object->symtab, line)) || 1019 !(intn = yasm_expr_get_intnum(&e, 0))) { 1020 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 1021 N_("isa value is not a constant")); 1022 yasm_xfree(loc); 1023 if (e) 1024 yasm_expr_destroy(e); 1025 return; 1026 } 1027 if (yasm_intnum_sign(intn) < 0) { 1028 yasm_error_set(YASM_ERROR_VALUE, 1029 N_("isa value less than zero")); 1030 yasm_xfree(loc); 1031 yasm_expr_destroy(e); 1032 return; 1033 } 1034 loc->isa_change = 1; 1035 loc->isa = yasm_intnum_get_uint(intn); 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); 1057 } else if (!vp->val && (s = yasm_vp_id(vp))) { 1058 if (yasm__strcasecmp(s, "is_stmt") == 0) 1059 in_is_stmt = 1; 1060 else if (yasm__strcasecmp(s, "isa") == 0) 1061 in_isa = 1; 1062 else if (yasm__strcasecmp(s, "discriminator") == 0) 1063 in_discriminator = 1; 1064 else if (yasm__strcasecmp(s, "basic_block") == 0) 1065 loc->basic_block = 1; 1066 else if (yasm__strcasecmp(s, "prologue_end") == 0) 1067 loc->prologue_end = 1; 1068 else if (yasm__strcasecmp(s, "epilogue_begin") == 0) 1069 loc->epilogue_begin = 1; 1070 else 1071 yasm_warn_set(YASM_WARN_GENERAL, 1072 N_("unrecognized loc option `%s'"), s); 1073 } else if (!vp->val) { 1074 yasm_warn_set(YASM_WARN_GENERAL, 1075 N_("unrecognized numeric qualifier")); 1076 } else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) { 1077 in_is_stmt = 1; 1078 goto restart; /* don't go to the next valparam */ 1079 } else if (yasm__strcasecmp(vp->val, "isa") == 0) { 1080 in_isa = 1; 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 */ 1085 } else 1086 yasm_warn_set(YASM_WARN_GENERAL, 1087 N_("unrecognized loc option `%s'"), vp->val); 1088 vp = yasm_vps_next(vp); 1089 } 1090 1091 if (in_is_stmt || in_isa || in_discriminator) { 1092 yasm_error_set(YASM_ERROR_SYNTAX, N_("%s requires value"), 1093 in_is_stmt ? "is_stmt" : 1094 (in_isa ? "isa" : "discriminator")); 1095 yasm_xfree(loc); 1096 return; 1097 } 1098 1099 /* Append new location */ 1100 loc->vline = line; 1101 loc->bc = NULL; 1102 loc->sym = NULL; 1103 STAILQ_INSERT_TAIL(&dsd->locs, loc, link); 1104 } 1105 1106 void 1107 yasm_dwarf2__dir_file(yasm_object *object, yasm_valparamhead *valparams, 1108 yasm_valparamhead *objext_valparams, unsigned long line) 1109 { 1110 yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; 1111 yasm_valparam *vp; 1112 /*@dependent@*/ /*@null@*/ const yasm_intnum *file_intn; 1113 unsigned long filenum; 1114 1115 if (!valparams) { 1116 yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires an argument"), 1117 "FILE"); 1118 return; 1119 } 1120 1121 vp = yasm_vps_first(valparams); 1122 if (yasm_vp_string(vp)) { 1123 /* Just a bare filename */ 1124 yasm_object_set_source_fn(object, yasm_vp_string(vp)); 1125 return; 1126 } 1127 1128 /* Otherwise.. first vp is the file number */ 1129 if (vp->type != YASM_PARAM_EXPR || 1130 !(file_intn = yasm_expr_get_intnum(&vp->param.e, 0))) { 1131 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 1132 N_("file number is not a constant")); 1133 return; 1134 } 1135 filenum = yasm_intnum_get_uint(file_intn); 1136 1137 vp = yasm_vps_next(vp); 1138 if (!yasm_vp_string(vp)) { 1139 yasm_error_set(YASM_ERROR_SYNTAX, 1140 N_("file number given but no filename")); 1141 return; 1142 } 1143 1144 dwarf2_dbgfmt_add_file(dbgfmt_dwarf2, filenum, yasm_vp_string(vp)); 1145 } 1146