1 /*- 2 * Copyright (c) 2009,2010 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include "_libdwarf.h" 28 29 ELFTC_VCSID("$Id: libdwarf_lineno.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); 30 31 static int 32 _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, 33 Dwarf_Error *error, Dwarf_Debug dbg) 34 { 35 Dwarf_LineFile lf; 36 const char *dirname; 37 uint8_t *src; 38 int slen; 39 40 src = *p; 41 42 if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { 43 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 44 return (DW_DLE_MEMORY); 45 } 46 47 lf->lf_fullpath = NULL; 48 lf->lf_fname = (char *) src; 49 src += strlen(lf->lf_fname) + 1; 50 lf->lf_dirndx = _dwarf_decode_uleb128(&src); 51 if (lf->lf_dirndx > li->li_inclen) { 52 free(lf); 53 DWARF_SET_ERROR(dbg, error, DW_DLE_DIR_INDEX_BAD); 54 return (DW_DLE_DIR_INDEX_BAD); 55 } 56 57 /* Make full pathname if need. */ 58 if (*lf->lf_fname != '/') { 59 dirname = compdir; 60 if (lf->lf_dirndx > 0) 61 dirname = li->li_incdirs[lf->lf_dirndx - 1]; 62 if (dirname != NULL) { 63 slen = strlen(dirname) + strlen(lf->lf_fname) + 2; 64 if ((lf->lf_fullpath = malloc(slen)) == NULL) { 65 free(lf); 66 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 67 return (DW_DLE_MEMORY); 68 } 69 snprintf(lf->lf_fullpath, slen, "%s/%s", dirname, 70 lf->lf_fname); 71 } 72 } 73 74 lf->lf_mtime = _dwarf_decode_uleb128(&src); 75 lf->lf_size = _dwarf_decode_uleb128(&src); 76 STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); 77 li->li_lflen++; 78 79 *p = src; 80 81 return (DW_DLE_NONE); 82 } 83 84 static int 85 _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, 86 uint8_t *pe, const char *compdir, Dwarf_Error *error) 87 { 88 Dwarf_Debug dbg; 89 Dwarf_Line ln, tln; 90 uint64_t address, file, line, column, isa, opsize; 91 int is_stmt, basic_block, end_sequence; 92 int prologue_end, epilogue_begin; 93 int ret; 94 95 #define RESET_REGISTERS \ 96 do { \ 97 address = 0; \ 98 file = 1; \ 99 line = 1; \ 100 column = 0; \ 101 is_stmt = li->li_defstmt; \ 102 basic_block = 0; \ 103 end_sequence = 0; \ 104 prologue_end = 0; \ 105 epilogue_begin = 0; \ 106 } while(0) 107 108 #define APPEND_ROW \ 109 do { \ 110 ln = malloc(sizeof(struct _Dwarf_Line)); \ 111 if (ln == NULL) { \ 112 ret = DW_DLE_MEMORY; \ 113 DWARF_SET_ERROR(dbg, error, ret); \ 114 goto prog_fail; \ 115 } \ 116 ln->ln_li = li; \ 117 ln->ln_addr = address; \ 118 ln->ln_symndx = 0; \ 119 ln->ln_fileno = file; \ 120 ln->ln_lineno = line; \ 121 ln->ln_column = column; \ 122 ln->ln_bblock = basic_block; \ 123 ln->ln_stmt = is_stmt; \ 124 ln->ln_endseq = end_sequence; \ 125 STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);\ 126 li->li_lnlen++; \ 127 } while(0) 128 129 #define LINE(x) (li->li_lbase + (((x) - li->li_opbase) % li->li_lrange)) 130 #define ADDRESS(x) ((((x) - li->li_opbase) / li->li_lrange) * li->li_minlen) 131 132 dbg = cu->cu_dbg; 133 134 /* 135 * Set registers to their default values. 136 */ 137 RESET_REGISTERS; 138 139 /* 140 * Start line number program. 141 */ 142 while (p < pe) { 143 if (*p == 0) { 144 145 /* 146 * Extended Opcodes. 147 */ 148 149 p++; 150 opsize = _dwarf_decode_uleb128(&p); 151 switch (*p) { 152 case DW_LNE_end_sequence: 153 p++; 154 end_sequence = 1; 155 APPEND_ROW; 156 RESET_REGISTERS; 157 break; 158 case DW_LNE_set_address: 159 p++; 160 address = dbg->decode(&p, cu->cu_pointer_size); 161 break; 162 case DW_LNE_define_file: 163 p++; 164 ret = _dwarf_lineno_add_file(li, &p, compdir, 165 error, dbg); 166 if (ret != DW_DLE_NONE) 167 goto prog_fail; 168 break; 169 default: 170 /* Unrecognized extened opcodes. */ 171 p += opsize; 172 } 173 174 } else if (*p > 0 && *p < li->li_opbase) { 175 176 /* 177 * Standard Opcodes. 178 */ 179 180 switch (*p++) { 181 case DW_LNS_copy: 182 APPEND_ROW; 183 basic_block = 0; 184 prologue_end = 0; 185 epilogue_begin = 0; 186 break; 187 case DW_LNS_advance_pc: 188 address += _dwarf_decode_uleb128(&p) * 189 li->li_minlen; 190 break; 191 case DW_LNS_advance_line: 192 line += _dwarf_decode_sleb128(&p); 193 break; 194 case DW_LNS_set_file: 195 file = _dwarf_decode_uleb128(&p); 196 break; 197 case DW_LNS_set_column: 198 column = _dwarf_decode_uleb128(&p); 199 break; 200 case DW_LNS_negate_stmt: 201 is_stmt = !is_stmt; 202 break; 203 case DW_LNS_set_basic_block: 204 basic_block = 1; 205 break; 206 case DW_LNS_const_add_pc: 207 address += ADDRESS(255); 208 break; 209 case DW_LNS_fixed_advance_pc: 210 address += dbg->decode(&p, 2); 211 break; 212 case DW_LNS_set_prologue_end: 213 prologue_end = 1; 214 break; 215 case DW_LNS_set_epilogue_begin: 216 epilogue_begin = 1; 217 break; 218 case DW_LNS_set_isa: 219 isa = _dwarf_decode_uleb128(&p); 220 break; 221 default: 222 /* Unrecognized extened opcodes. What to do? */ 223 break; 224 } 225 226 } else { 227 228 /* 229 * Special Opcodes. 230 */ 231 232 line += LINE(*p); 233 address += ADDRESS(*p); 234 APPEND_ROW; 235 basic_block = 0; 236 prologue_end = 0; 237 epilogue_begin = 0; 238 p++; 239 } 240 } 241 242 return (DW_DLE_NONE); 243 244 prog_fail: 245 246 STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { 247 STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); 248 free(ln); 249 } 250 251 return (ret); 252 253 #undef RESET_REGISTERS 254 #undef APPEND_ROW 255 #undef LINE 256 #undef ADDRESS 257 } 258 259 int 260 _dwarf_lineno_init(Dwarf_Die die, uint64_t offset, Dwarf_Error *error) 261 { 262 Dwarf_Debug dbg; 263 Dwarf_Section *ds; 264 Dwarf_CU cu; 265 Dwarf_Attribute at; 266 Dwarf_LineInfo li; 267 Dwarf_LineFile lf, tlf; 268 const char *compdir; 269 uint64_t length, hdroff, endoff; 270 uint8_t *p; 271 int dwarf_size, i, ret; 272 273 cu = die->die_cu; 274 assert(cu != NULL); 275 276 dbg = cu->cu_dbg; 277 assert(dbg != NULL); 278 279 if ((ds = _dwarf_find_section(dbg, ".debug_line")) == NULL) 280 return (DW_DLE_NONE); 281 282 /* 283 * Try to find out the dir where the CU was compiled. Later we 284 * will use the dir to create full pathnames, if need. 285 */ 286 compdir = NULL; 287 at = _dwarf_attr_find(die, DW_AT_comp_dir); 288 if (at != NULL) { 289 switch (at->at_form) { 290 case DW_FORM_strp: 291 compdir = at->u[1].s; 292 break; 293 case DW_FORM_string: 294 compdir = at->u[0].s; 295 break; 296 default: 297 break; 298 } 299 } 300 301 length = dbg->read(ds->ds_data, &offset, 4); 302 if (length == 0xffffffff) { 303 dwarf_size = 8; 304 length = dbg->read(ds->ds_data, &offset, 8); 305 } else 306 dwarf_size = 4; 307 308 if (length > ds->ds_size - offset) { 309 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); 310 return (DW_DLE_DEBUG_LINE_LENGTH_BAD); 311 } 312 313 if ((li = calloc(1, sizeof(struct _Dwarf_LineInfo))) == NULL) { 314 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 315 return (DW_DLE_MEMORY); 316 } 317 318 /* 319 * Read in line number program header. 320 */ 321 li->li_length = length; 322 endoff = offset + length; 323 li->li_version = dbg->read(ds->ds_data, &offset, 2); /* FIXME: verify version */ 324 li->li_hdrlen = dbg->read(ds->ds_data, &offset, dwarf_size); 325 hdroff = offset; 326 li->li_minlen = dbg->read(ds->ds_data, &offset, 1); 327 li->li_defstmt = dbg->read(ds->ds_data, &offset, 1); 328 li->li_lbase = dbg->read(ds->ds_data, &offset, 1); 329 li->li_lrange = dbg->read(ds->ds_data, &offset, 1); 330 li->li_opbase = dbg->read(ds->ds_data, &offset, 1); 331 STAILQ_INIT(&li->li_lflist); 332 STAILQ_INIT(&li->li_lnlist); 333 334 if ((int)li->li_hdrlen - 5 < li->li_opbase - 1) { 335 ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; 336 DWARF_SET_ERROR(dbg, error, ret); 337 goto fail_cleanup; 338 } 339 340 if ((li->li_oplen = malloc(li->li_opbase)) == NULL) { 341 ret = DW_DLE_MEMORY; 342 DWARF_SET_ERROR(dbg, error, ret); 343 goto fail_cleanup; 344 } 345 346 /* 347 * Read in std opcode arg length list. Note that the first 348 * element is not used. 349 */ 350 for (i = 1; i < li->li_opbase; i++) 351 li->li_oplen[i] = dbg->read(ds->ds_data, &offset, 1); 352 353 /* 354 * Check how many strings in the include dir string array. 355 */ 356 length = 0; 357 p = ds->ds_data + offset; 358 while (*p != '\0') { 359 while (*p++ != '\0') 360 ; 361 length++; 362 } 363 li->li_inclen = length; 364 365 /* Sanity check. */ 366 if (p - ds->ds_data > (int) ds->ds_size) { 367 ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; 368 DWARF_SET_ERROR(dbg, error, ret); 369 goto fail_cleanup; 370 } 371 372 if (length != 0) { 373 if ((li->li_incdirs = malloc(length * sizeof(char *))) == 374 NULL) { 375 ret = DW_DLE_MEMORY; 376 DWARF_SET_ERROR(dbg, error, ret); 377 goto fail_cleanup; 378 } 379 } 380 381 /* Fill in include dir array. */ 382 i = 0; 383 p = ds->ds_data + offset; 384 while (*p != '\0') { 385 li->li_incdirs[i++] = (char *) p; 386 while (*p++ != '\0') 387 ; 388 } 389 390 p++; 391 392 /* 393 * Process file list. 394 */ 395 while (*p != '\0') { 396 ret = _dwarf_lineno_add_file(li, &p, compdir, error, dbg); 397 if (ret != DW_DLE_NONE) 398 goto fail_cleanup; 399 if (p - ds->ds_data > (int) ds->ds_size) { 400 ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; 401 DWARF_SET_ERROR(dbg, error, ret); 402 goto fail_cleanup; 403 } 404 } 405 406 p++; 407 408 /* Sanity check. */ 409 if (p - ds->ds_data - hdroff != li->li_hdrlen) { 410 ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; 411 DWARF_SET_ERROR(dbg, error, ret); 412 goto fail_cleanup; 413 } 414 415 /* 416 * Process line number program. 417 */ 418 ret = _dwarf_lineno_run_program(cu, li, p, ds->ds_data + endoff, compdir, 419 error); 420 if (ret != DW_DLE_NONE) 421 goto fail_cleanup; 422 423 cu->cu_lineinfo = li; 424 425 return (DW_DLE_NONE); 426 427 fail_cleanup: 428 429 STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { 430 STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); 431 if (lf->lf_fullpath) 432 free(lf->lf_fullpath); 433 free(lf); 434 } 435 436 if (li->li_oplen) 437 free(li->li_oplen); 438 if (li->li_incdirs) 439 free(li->li_incdirs); 440 free(li); 441 442 return (ret); 443 } 444 445 void 446 _dwarf_lineno_cleanup(Dwarf_LineInfo li) 447 { 448 Dwarf_LineFile lf, tlf; 449 Dwarf_Line ln, tln; 450 451 if (li == NULL) 452 return; 453 STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { 454 STAILQ_REMOVE(&li->li_lflist, lf, 455 _Dwarf_LineFile, lf_next); 456 if (lf->lf_fullpath) 457 free(lf->lf_fullpath); 458 free(lf); 459 } 460 STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { 461 STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, 462 ln_next); 463 free(ln); 464 } 465 if (li->li_oplen) 466 free(li->li_oplen); 467 if (li->li_incdirs) 468 free(li->li_incdirs); 469 if (li->li_lnarray) 470 free(li->li_lnarray); 471 if (li->li_lfnarray) 472 free(li->li_lfnarray); 473 free(li); 474 } 475 476 static int 477 _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, 478 Dwarf_Rel_Section drs, Dwarf_Error * error) 479 { 480 Dwarf_LineInfo li; 481 Dwarf_Line ln; 482 Dwarf_Unsigned address, file, line, spc; 483 Dwarf_Unsigned addr0, maddr; 484 Dwarf_Signed line0, column; 485 int is_stmt, basic_block, end_sequence; 486 int need_copy; 487 int ret; 488 489 #define RESET_REGISTERS \ 490 do { \ 491 address = 0; \ 492 file = 1; \ 493 line = 1; \ 494 column = 0; \ 495 is_stmt = li->li_defstmt; \ 496 basic_block = 0; \ 497 end_sequence = 0; \ 498 } while(0) 499 500 li = dbg->dbgp_lineinfo; 501 maddr = (255 - li->li_opbase) / li->li_lrange; 502 503 RESET_REGISTERS; 504 505 STAILQ_FOREACH(ln, &li->li_lnlist, ln_next) { 506 if (ln->ln_symndx > 0) { 507 /* 508 * Generate DW_LNE_set_address extended op. 509 */ 510 RCHECK(WRITE_VALUE(0, 1)); 511 RCHECK(WRITE_ULEB128(dbg->dbg_pointer_size + 1)); 512 RCHECK(WRITE_VALUE(DW_LNE_set_address, 1)); 513 RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, 514 dwarf_drt_data_reloc, dbg->dbg_pointer_size, 515 ds->ds_size, ln->ln_symndx, ln->ln_addr, 516 NULL, error)); 517 address = ln->ln_addr; 518 continue; 519 } else if (ln->ln_endseq) { 520 addr0 = (ln->ln_addr - address) / li->li_minlen; 521 if (addr0 != 0) { 522 RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); 523 RCHECK(WRITE_ULEB128(addr0)); 524 } 525 526 /* 527 * Generate DW_LNE_end_sequence. 528 */ 529 RCHECK(WRITE_VALUE(0, 1)); 530 RCHECK(WRITE_ULEB128(1)); 531 RCHECK(WRITE_VALUE(DW_LNE_end_sequence, 1)); 532 RESET_REGISTERS; 533 continue; 534 } 535 536 /* 537 * Generate standard opcodes for file, column, is_stmt or 538 * basic_block changes. 539 */ 540 if (ln->ln_fileno != file) { 541 RCHECK(WRITE_VALUE(DW_LNS_set_file, 1)); 542 RCHECK(WRITE_ULEB128(ln->ln_fileno)); 543 file = ln->ln_fileno; 544 } 545 if (ln->ln_column != column) { 546 RCHECK(WRITE_VALUE(DW_LNS_set_column, 1)); 547 RCHECK(WRITE_ULEB128(ln->ln_column)); 548 column = ln->ln_column; 549 } 550 if (ln->ln_stmt != is_stmt) { 551 RCHECK(WRITE_VALUE(DW_LNS_negate_stmt, 1)); 552 is_stmt = ln->ln_stmt; 553 } 554 if (ln->ln_bblock && !basic_block) { 555 RCHECK(WRITE_VALUE(DW_LNS_set_basic_block, 1)); 556 basic_block = 1; 557 } 558 559 /* 560 * Calculate address and line number change. 561 */ 562 addr0 = (ln->ln_addr - address) / li->li_minlen; 563 line0 = ln->ln_lineno - line; 564 565 if (addr0 == 0 && line0 == 0) 566 continue; 567 568 /* 569 * Check if line delta is with the range and if the special 570 * opcode can be used. 571 */ 572 assert(li->li_lbase <= 0); 573 if (line0 >= li->li_lbase && 574 line0 <= li->li_lbase + li->li_lrange - 1) { 575 spc = (line0 - li->li_lbase) + 576 (li->li_lrange * addr0) + li->li_opbase; 577 if (spc <= 255) { 578 RCHECK(WRITE_VALUE(spc, 1)); 579 basic_block = 0; 580 goto next_line; 581 } 582 } 583 584 /* Generate DW_LNS_advance_line for line number change. */ 585 if (line0 != 0) { 586 RCHECK(WRITE_VALUE(DW_LNS_advance_line, 1)); 587 RCHECK(WRITE_SLEB128(line0)); 588 line0 = 0; 589 need_copy = 1; 590 } else 591 need_copy = basic_block; 592 593 if (addr0 != 0) { 594 /* See if it can be handled by DW_LNS_const_add_pc. */ 595 spc = (line0 - li->li_lbase) + 596 (li->li_lrange * (addr0 - maddr)) + li->li_opbase; 597 if (addr0 >= maddr && spc <= 255) { 598 RCHECK(WRITE_VALUE(DW_LNS_const_add_pc, 1)); 599 RCHECK(WRITE_VALUE(spc, 1)); 600 } else { 601 /* Otherwise we use DW_LNS_advance_pc. */ 602 RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); 603 RCHECK(WRITE_ULEB128(addr0)); 604 } 605 } 606 607 if (need_copy) { 608 RCHECK(WRITE_VALUE(DW_LNS_copy, 1)); 609 basic_block = 0; 610 } 611 612 next_line: 613 address = ln->ln_addr; 614 line = ln->ln_lineno; 615 } 616 617 return (DW_DLE_NONE); 618 619 gen_fail: 620 return (ret); 621 622 #undef RESET_REGISTERS 623 } 624 625 static uint8_t 626 _dwarf_get_minlen(Dwarf_P_Debug dbg) 627 { 628 629 assert(dbg != NULL); 630 631 switch (dbg->dbgp_isa) { 632 case DW_ISA_ARM: 633 return (2); 634 case DW_ISA_X86: 635 case DW_ISA_X86_64: 636 return (1); 637 default: 638 return (4); 639 } 640 } 641 642 static uint8_t oplen[] = {0, 1, 1, 1, 1, 0, 0, 0, 1}; 643 644 int 645 _dwarf_lineno_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) 646 { 647 Dwarf_LineInfo li; 648 Dwarf_LineFile lf; 649 Dwarf_P_Section ds; 650 Dwarf_Rel_Section drs; 651 Dwarf_Unsigned offset; 652 int i, ret; 653 654 assert(dbg != NULL && dbg->dbgp_lineinfo != NULL); 655 656 li = dbg->dbgp_lineinfo; 657 if (STAILQ_EMPTY(&li->li_lnlist)) 658 return (DW_DLE_NONE); 659 660 li->li_length = 0; 661 li->li_version = 2; 662 li->li_hdrlen = 0; 663 li->li_minlen = _dwarf_get_minlen(dbg); 664 li->li_defstmt = 1; 665 li->li_lbase = -5; 666 li->li_lrange = 14; 667 li->li_opbase = 10; 668 669 /* Create .debug_line section. */ 670 if ((ret = _dwarf_section_init(dbg, &ds, ".debug_line", 0, error)) != 671 DW_DLE_NONE) 672 return (ret); 673 674 /* Create relocation section for .debug_line */ 675 if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != 676 DW_DLE_NONE) 677 goto gen_fail1; 678 679 /* Length placeholder. (We only use 32-bit DWARF format) */ 680 RCHECK(WRITE_VALUE(0, 4)); 681 682 /* Write line number dwarf version. (DWARF2) */ 683 RCHECK(WRITE_VALUE(li->li_version, 2)); 684 685 /* Header length placeholder. */ 686 offset = ds->ds_size; 687 RCHECK(WRITE_VALUE(li->li_hdrlen, 4)); 688 689 /* Write minimum instruction length. */ 690 RCHECK(WRITE_VALUE(li->li_minlen, 1)); 691 692 /* 693 * Write initial value for is_stmt. XXX Which default value we 694 * should use? 695 */ 696 RCHECK(WRITE_VALUE(li->li_defstmt, 1)); 697 698 /* 699 * Write line_base and line_range. FIXME These value needs to be 700 * fine tuned. 701 */ 702 RCHECK(WRITE_VALUE(li->li_lbase, 1)); 703 RCHECK(WRITE_VALUE(li->li_lrange, 1)); 704 705 /* Write opcode_base. (DWARF2) */ 706 RCHECK(WRITE_VALUE(li->li_opbase, 1)); 707 708 /* Write standard op length array. */ 709 RCHECK(WRITE_BLOCK(oplen, sizeof(oplen) / sizeof(oplen[0]))); 710 711 /* Write the list of include directories. */ 712 for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) 713 RCHECK(WRITE_STRING(li->li_incdirs[i])); 714 RCHECK(WRITE_VALUE(0, 1)); 715 716 /* Write the list of filenames. */ 717 STAILQ_FOREACH(lf, &li->li_lflist, lf_next) { 718 RCHECK(WRITE_STRING(lf->lf_fname)); 719 RCHECK(WRITE_ULEB128(lf->lf_dirndx)); 720 RCHECK(WRITE_ULEB128(lf->lf_mtime)); 721 RCHECK(WRITE_ULEB128(lf->lf_size)); 722 } 723 RCHECK(WRITE_VALUE(0, 1)); 724 725 /* Fill in the header length. */ 726 li->li_hdrlen = ds->ds_size - offset - 4; 727 dbg->write(ds->ds_data, &offset, li->li_hdrlen, 4); 728 729 /* Generate the line number program. */ 730 RCHECK(_dwarf_lineno_gen_program(dbg, ds, drs, error)); 731 732 /* Fill in the length of this line info. */ 733 li->li_length = ds->ds_size - 4; 734 offset = 0; 735 dbg->write(ds->ds_data, &offset, li->li_length, 4); 736 737 /* Notify the creation of .debug_line ELF section. */ 738 RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); 739 740 /* Finalize relocation section for .debug_line. */ 741 RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); 742 743 return (DW_DLE_NONE); 744 745 gen_fail: 746 _dwarf_reloc_section_free(dbg, &drs); 747 748 gen_fail1: 749 _dwarf_section_free(dbg, &ds); 750 751 return (ret); 752 } 753 754 void 755 _dwarf_lineno_pro_cleanup(Dwarf_P_Debug dbg) 756 { 757 Dwarf_LineInfo li; 758 Dwarf_LineFile lf, tlf; 759 Dwarf_Line ln, tln; 760 int i; 761 762 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 763 if (dbg->dbgp_lineinfo == NULL) 764 return; 765 766 li = dbg->dbgp_lineinfo; 767 STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { 768 STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, 769 lf_next); 770 if (lf->lf_fname) 771 free(lf->lf_fname); 772 free(lf); 773 } 774 STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { 775 STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); 776 free(ln); 777 } 778 if (li->li_incdirs) { 779 for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) 780 free(li->li_incdirs[i]); 781 free(li->li_incdirs); 782 } 783 free(li); 784 dbg->dbgp_lineinfo = NULL; 785 } 786