1 /* 2 3 Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2.1 of the GNU Lesser General Public License 7 as published by the Free Software Foundation. 8 9 This program is distributed in the hope that it would be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 Further, this software is distributed without any warranty that it is 14 free of the rightful claim of any third person regarding infringement 15 or the like. Any license provided herein, whether implied or 16 otherwise, applies only to this software file. Patent licenses, if 17 any, provided herein do not apply to combinations of this program with 18 other software, or any other product whatsoever. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this program; if not, write the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "libdwarfdefs.h" 40 #include <stdio.h> 41 #include <string.h> 42 #ifdef HAVE_ELFACCESS_H 43 #include <elfaccess.h> 44 #endif 45 #include "pro_incl.h" 46 #include "pro_section.h" 47 #include "pro_line.h" 48 #include "pro_frame.h" 49 #include "pro_die.h" 50 #include "pro_macinfo.h" 51 #include "pro_types.h" 52 53 #ifndef SHF_MIPS_NOSTRIP 54 /* if this is not defined, we probably don't need it: just use 0 */ 55 #define SHF_MIPS_NOSTRIP 0 56 #endif 57 #ifndef R_MIPS_NONE 58 #define R_MIPS_NONE 0 59 #endif 60 61 #ifndef TRUE 62 #define TRUE 1 63 #endif 64 #ifndef FALSE 65 #define FALSE 0 66 #endif 67 68 /* must match up with pro_section.h defines of DEBUG_INFO etc 69 and sectnames (below) 70 */ 71 char *_dwarf_rel_section_names[] = { 72 ".rel.debug_info", 73 ".rel.debug_line", 74 ".rel.debug_abbrev", /* no relocations on this, really */ 75 ".rel.debug_frame", 76 ".rel.debug_aranges", 77 ".rel.debug_pubnames", 78 ".rel.debug_str", 79 ".rel.debug_funcnames", /* sgi extension */ 80 ".rel.debug_typenames", /* sgi extension */ 81 ".rel.debug_varnames", /* sgi extension */ 82 ".rel.debug_weaknames", /* sgi extension */ 83 ".rel.debug_macinfo", 84 ".rel.debug_loc" 85 }; 86 87 /* names of sections. Ensure that it matches the defines 88 in pro_section.h, in the same order 89 Must match also _dwarf_rel_section_names above 90 */ 91 char *_dwarf_sectnames[] = { 92 ".debug_info", 93 ".debug_line", 94 ".debug_abbrev", 95 ".debug_frame", 96 ".debug_aranges", 97 ".debug_pubnames", 98 ".debug_str", 99 ".debug_funcnames", /* sgi extension */ 100 ".debug_typenames", /* sgi extension */ 101 ".debug_varnames", /* sgi extension */ 102 ".debug_weaknames", /* sgi extension */ 103 ".debug_macinfo", 104 ".debug_loc" 105 }; 106 107 108 109 110 static Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */ 111 1, /* DW_LNS_advance_pc */ 112 1, /* DW_LNS_advance_line */ 113 1, /* DW_LNS_set_file */ 114 1, /* DW_LNS_set_column */ 115 0, /* DW_LNS_negate_stmt */ 116 0, /* DW_LNS_set_basic_block */ 117 0, /* DW_LNS_const_add_pc */ 118 1, /* DW_LNS_fixed_advance_pc */ 119 }; 120 121 /* struct to hold relocation entries. Its mantained as a linked 122 list of relocation structs, and will then be written at as a 123 whole into the relocation section. Whether its 32 bit or 124 64 bit will be obtained from Dwarf_Debug pointer. 125 */ 126 127 typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; 128 struct Dwarf_P_Rel_s { 129 Dwarf_P_Rel dr_next; 130 void *dr_rel_datap; 131 }; 132 typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; 133 struct Dwarf_P_Rel_Head_s { 134 struct Dwarf_P_Rel_s *drh_head; 135 struct Dwarf_P_Rel_s *drh_tail; 136 }; 137 138 static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, 139 Dwarf_Error * error); 140 static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, 141 Dwarf_Error * error); 142 static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, 143 Dwarf_Error * error); 144 static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev); 145 static int _dwarf_pro_match_attr 146 (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr); 147 148 /* these macros used as return value for below functions */ 149 #define OPC_INCS_ZERO -1 150 #define OPC_OUT_OF_RANGE -2 151 #define LINE_OUT_OF_RANGE -3 152 static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv); 153 154 155 156 /* 157 Return TRUE if we need the section, FALSE otherwise 158 159 If any of the 'line-data-related' calls were made 160 including file or directory entries, 161 produce .debug_line . 162 163 */ 164 static int 165 dwarf_need_debug_line_section(Dwarf_P_Debug dbg) 166 { 167 if (dbg->de_lines == NULL && dbg->de_file_entries == NULL 168 && dbg->de_inc_dirs == NULL) { 169 return FALSE; 170 } 171 return TRUE; 172 } 173 174 /* 175 Convert debug information to a format such that 176 it can be written on disk. 177 Called exactly once per execution. 178 */ 179 Dwarf_Signed 180 dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) 181 { 182 /* 183 Section data in written out in a number of buffers. Each 184 _generate_*() function returns a cumulative count of buffers for 185 all the sections. get_section_bytes() returns pointers to these 186 buffers one at a time. */ 187 int nbufs; 188 int sect; 189 int name_idx; 190 int err; 191 Dwarf_Unsigned du; 192 193 if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { 194 DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); 195 } 196 197 /* Create dwarf section headers */ 198 for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) { 199 long flags = 0; 200 201 switch (sect) { 202 203 case DEBUG_INFO: 204 if (dbg->de_dies == NULL) 205 continue; 206 break; 207 208 case DEBUG_LINE: 209 if (dwarf_need_debug_line_section(dbg) == FALSE) { 210 continue; 211 } 212 break; 213 214 case DEBUG_ABBREV: 215 if (dbg->de_dies == NULL) 216 continue; 217 break; 218 219 case DEBUG_FRAME: 220 if (dbg->de_frame_cies == NULL) 221 continue; 222 flags = SHF_MIPS_NOSTRIP; 223 break; 224 225 case DEBUG_ARANGES: 226 if (dbg->de_arange == NULL) 227 continue; 228 break; 229 230 case DEBUG_PUBNAMES: 231 if (dbg->de_simple_name_headers[dwarf_snk_pubname]. 232 sn_head == NULL) 233 continue; 234 break; 235 236 case DEBUG_STR: 237 if (dbg->de_strings == NULL) 238 continue; 239 break; 240 241 case DEBUG_FUNCNAMES: 242 if (dbg->de_simple_name_headers[dwarf_snk_funcname]. 243 sn_head == NULL) 244 continue; 245 break; 246 247 case DEBUG_TYPENAMES: 248 if (dbg->de_simple_name_headers[dwarf_snk_typename]. 249 sn_head == NULL) 250 continue; 251 break; 252 253 case DEBUG_VARNAMES: 254 if (dbg->de_simple_name_headers[dwarf_snk_varname]. 255 sn_head == NULL) 256 continue; 257 break; 258 259 case DEBUG_WEAKNAMES: 260 if (dbg->de_simple_name_headers[dwarf_snk_weakname]. 261 sn_head == NULL) 262 continue; 263 break; 264 265 case DEBUG_MACINFO: 266 if (dbg->de_first_macinfo == NULL) 267 continue; 268 break; 269 case DEBUG_LOC: 270 /* not handled yet */ 271 continue; 272 default: 273 /* logic error: missing a case */ 274 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT); 275 } 276 { 277 int new_base_elf_sect; 278 279 if (dbg->de_func_b) { 280 new_base_elf_sect = 281 dbg->de_func_b(_dwarf_sectnames[sect], 282 /* rec size */ 1, 283 SECTION_TYPE, 284 flags, SHN_UNDEF, 0, &du, &err); 285 286 } else { 287 new_base_elf_sect = dbg->de_func(_dwarf_sectnames[sect], 288 dbg-> 289 de_relocation_record_size, 290 SECTION_TYPE, flags, 291 SHN_UNDEF, 0, 292 &name_idx, &err); 293 du = name_idx; 294 } 295 if (new_base_elf_sect == -1) { 296 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, 297 DW_DLV_NOCOUNT); 298 } 299 dbg->de_elf_sects[sect] = new_base_elf_sect; 300 301 dbg->de_sect_name_idx[sect] = du; 302 } 303 } 304 305 nbufs = 0; 306 307 /* 308 Changing the order in which the sections are generated may 309 cause problems because of relocations. */ 310 311 if (dwarf_need_debug_line_section(dbg) == TRUE) { 312 nbufs = _dwarf_pro_generate_debugline(dbg, error); 313 if (nbufs < 0) { 314 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR, 315 DW_DLV_NOCOUNT); 316 } 317 } 318 319 if (dbg->de_frame_cies) { 320 nbufs = _dwarf_pro_generate_debugframe(dbg, error); 321 if (nbufs < 0) { 322 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR, 323 DW_DLV_NOCOUNT); 324 } 325 } 326 if (dbg->de_first_macinfo) { 327 nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error); 328 if (nbufs < 0) { 329 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR, 330 DW_DLV_NOCOUNT); 331 } 332 } 333 334 if (dbg->de_dies) { 335 nbufs = _dwarf_pro_generate_debuginfo(dbg, error); 336 if (nbufs < 0) { 337 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 338 DW_DLV_NOCOUNT); 339 } 340 } 341 342 if (dbg->de_arange) { 343 nbufs = _dwarf_transform_arange_to_disk(dbg, error); 344 if (nbufs < 0) { 345 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 346 DW_DLV_NOCOUNT); 347 } 348 } 349 350 if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { 351 nbufs = _dwarf_transform_simplename_to_disk(dbg, 352 dwarf_snk_pubname, 353 DEBUG_PUBNAMES, 354 error); 355 356 357 if (nbufs < 0) { 358 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 359 DW_DLV_NOCOUNT); 360 } 361 } 362 363 if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { 364 nbufs = _dwarf_transform_simplename_to_disk(dbg, 365 dwarf_snk_funcname, 366 DEBUG_FUNCNAMES, 367 error); 368 if (nbufs < 0) { 369 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 370 DW_DLV_NOCOUNT); 371 } 372 } 373 374 if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { 375 nbufs = _dwarf_transform_simplename_to_disk(dbg, 376 dwarf_snk_typename, 377 DEBUG_TYPENAMES, 378 error); 379 if (nbufs < 0) { 380 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 381 DW_DLV_NOCOUNT); 382 } 383 } 384 385 if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { 386 nbufs = _dwarf_transform_simplename_to_disk(dbg, 387 dwarf_snk_varname, 388 DEBUG_VARNAMES, 389 error); 390 391 if (nbufs < 0) { 392 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 393 DW_DLV_NOCOUNT); 394 } 395 } 396 397 if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { 398 nbufs = _dwarf_transform_simplename_to_disk(dbg, 399 dwarf_snk_weakname, 400 DEBUG_WEAKNAMES, 401 error); 402 403 if (nbufs < 0) { 404 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 405 DW_DLV_NOCOUNT); 406 } 407 } 408 409 { 410 Dwarf_Signed new_secs; 411 int res; 412 413 res = dbg->de_transform_relocs_to_disk(dbg, &new_secs); 414 if (res != DW_DLV_OK) { 415 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 416 DW_DLV_NOCOUNT); 417 } 418 nbufs += new_secs; 419 } 420 return nbufs; 421 } 422 423 424 /*--------------------------------------------------------------- 425 Generate debug_line section 426 ---------------------------------------------------------------*/ 427 static int 428 _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) 429 { 430 Dwarf_P_Inc_Dir curdir; 431 Dwarf_P_F_Entry curentry; 432 Dwarf_P_Line curline, prevline; 433 434 /* all data named cur* are used to loop thru linked lists */ 435 436 int sum_bytes; 437 int prolog_size; 438 unsigned char *data; /* holds disk form data */ 439 int elfsectno; 440 unsigned char *start_line_sec; /* pointer to the buffer at 441 section start */ 442 /* temps for memcpy */ 443 Dwarf_Unsigned du; 444 Dwarf_Ubyte db; 445 Dwarf_Half dh; 446 int res; 447 int uwordb_size = dbg->de_offset_size; 448 int extension_size = dbg->de_64bit_extension ? 4 : 0; 449 int upointer_size = dbg->de_pointer_size; 450 char buff1[ENCODE_SPACE_NEEDED]; 451 452 453 sum_bytes = 0; 454 455 elfsectno = dbg->de_elf_sects[DEBUG_LINE]; 456 457 /* statement prologue information */ 458 prolog_size = 0; 459 /* include directories */ 460 curdir = dbg->de_inc_dirs; 461 while (curdir) { 462 prolog_size += strlen(curdir->did_name) + 1; 463 curdir = curdir->did_next; 464 } 465 prolog_size++; /* last null following last directory 466 entry. */ 467 468 /* file entries */ 469 curentry = dbg->de_file_entries; 470 while (curentry) { 471 prolog_size += 472 strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; 473 curentry = curentry->dfe_next; 474 } 475 prolog_size++; /* last null byte */ 476 477 478 prolog_size += extension_size + /* DISTINGUISHED VALUE */ 479 sizeof_uhalf(dbg) + /* version # */ 480 uwordb_size + /* prologue length */ 481 sizeof_ubyte(dbg) + /* min_instr length */ 482 sizeof_ubyte(dbg) + /* default is_stmt */ 483 sizeof_ubyte(dbg) + /* linebase */ 484 sizeof_ubyte(dbg) + /* linerange */ 485 sizeof_ubyte(dbg); /* opcode base */ 486 487 /* length of table specifying # of opnds */ 488 prolog_size += sizeof(std_opcode_len); 489 prolog_size += uwordb_size; /* for total length field */ 490 491 GET_CHUNK(dbg, elfsectno, data, prolog_size, error); 492 start_line_sec = data; 493 494 /* copy over the data */ 495 /* total_length */ 496 du = 0; 497 if (extension_size) { 498 Dwarf_Word x = DISTINGUISHED_VALUE; 499 500 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x, 501 sizeof(x), extension_size); 502 data += extension_size; 503 } 504 505 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 506 sizeof(du), uwordb_size); 507 data += uwordb_size; 508 509 dh = VERSION; 510 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, 511 sizeof(dh), sizeof(Dwarf_Half)); 512 data += sizeof(Dwarf_Half); 513 514 /* prologue length */ 515 du = prolog_size - (uwordb_size + sizeof(Dwarf_Half) + uwordb_size); 516 { 517 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 518 sizeof(du), uwordb_size); 519 data += uwordb_size; 520 } 521 db = MIN_INST_LENGTH; 522 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 523 sizeof(db), sizeof(Dwarf_Ubyte)); 524 data += sizeof(Dwarf_Ubyte); 525 db = DEFAULT_IS_STMT; 526 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 527 sizeof(db), sizeof(Dwarf_Ubyte)); 528 data += sizeof(Dwarf_Ubyte); 529 db = (Dwarf_Ubyte) LINE_BASE; 530 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 531 sizeof(db), sizeof(Dwarf_Ubyte)); 532 data += sizeof(Dwarf_Ubyte); 533 db = LINE_RANGE; 534 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 535 sizeof(db), sizeof(Dwarf_Ubyte)); 536 data += sizeof(Dwarf_Ubyte); 537 db = OPCODE_BASE; 538 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 539 sizeof(db), sizeof(Dwarf_Ubyte)); 540 data += sizeof(Dwarf_Ubyte); 541 WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, 542 sizeof(std_opcode_len), sizeof(std_opcode_len)); 543 data += sizeof(std_opcode_len); 544 545 /* copy over include directories */ 546 curdir = dbg->de_inc_dirs; 547 while (curdir) { 548 strcpy((char *) data, curdir->did_name); 549 data += strlen(curdir->did_name) + 1; 550 curdir = curdir->did_next; 551 } 552 *data = '\0'; /* last null */ 553 data++; 554 555 /* copy file entries */ 556 curentry = dbg->de_file_entries; 557 while (curentry) { 558 strcpy((char *) data, curentry->dfe_name); 559 data += strlen(curentry->dfe_name) + 1; 560 /* copies of leb numbers, no endian issues */ 561 memcpy((void *) data, 562 (const void *) curentry->dfe_args, curentry->dfe_nbytes); 563 data += curentry->dfe_nbytes; 564 curentry = curentry->dfe_next; 565 } 566 *data = '\0'; 567 data++; 568 569 sum_bytes += prolog_size; 570 571 curline = dbg->de_lines; 572 prevline = (Dwarf_P_Line) 573 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); 574 if (prevline == NULL) { 575 DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1); 576 } 577 _dwarf_pro_reg_init(prevline); 578 /* generate opcodes for line numbers */ 579 while (curline) { 580 int nbytes; 581 char *arg; 582 int opc; 583 int no_lns_copy; /* if lns copy opcode doesnt need to be 584 generated, if special opcode or end 585 sequence */ 586 Dwarf_Unsigned addr_adv; 587 int line_adv; /* supposed to be a reasonably small 588 number, so the size should not be a 589 problem. ? */ 590 591 no_lns_copy = 0; 592 if (curline->dpl_opc != 0) { 593 int inst_bytes; /* no of bytes in extended opcode */ 594 char *str; /* hold leb encoded inst_bytes */ 595 int str_nbytes; /* no of bytes in str */ 596 597 switch (curline->dpl_opc) { 598 case DW_LNE_end_sequence: 599 600 /* Advance pc to end of text section. */ 601 addr_adv = curline->dpl_address - prevline->dpl_address; 602 if (addr_adv > 0) { 603 db = DW_LNS_advance_pc; 604 res = 605 _dwarf_pro_encode_leb128_nm(addr_adv / 606 MIN_INST_LENGTH, 607 &nbytes, buff1, 608 sizeof(buff1)); 609 if (res != DW_DLV_OK) { 610 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 611 } 612 GET_CHUNK(dbg, elfsectno, data, 613 nbytes + sizeof(Dwarf_Ubyte), error); 614 WRITE_UNALIGNED(dbg, (void *) data, 615 (const void *) &db, sizeof(db), 616 sizeof(Dwarf_Ubyte)); 617 data += sizeof(Dwarf_Ubyte); 618 /* leb, no endianness issue */ 619 memcpy((void *) data, (const void *) buff1, nbytes); 620 data += nbytes + sizeof(Dwarf_Ubyte); 621 sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 622 prevline->dpl_address = curline->dpl_address; 623 } 624 625 /* first null byte */ 626 db = 0; 627 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 628 error); 629 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 630 sizeof(db), sizeof(Dwarf_Ubyte)); 631 data += sizeof(Dwarf_Ubyte); 632 sum_bytes += sizeof(Dwarf_Ubyte); 633 634 /* write length of extended opcode */ 635 inst_bytes = sizeof(Dwarf_Ubyte); 636 res = 637 _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, 638 buff1, sizeof(buff1)); 639 if (res != DW_DLV_OK) { 640 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 641 } 642 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); 643 memcpy((void *) data, (const void *) buff1, str_nbytes); 644 data += str_nbytes; 645 sum_bytes += str_nbytes; 646 647 /* write extended opcode */ 648 db = DW_LNE_end_sequence; 649 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 650 error); 651 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 652 sizeof(db), sizeof(Dwarf_Ubyte)); 653 data += sizeof(Dwarf_Ubyte); 654 sum_bytes += sizeof(Dwarf_Ubyte); 655 /* reset value to original values */ 656 _dwarf_pro_reg_init(prevline); 657 no_lns_copy = 1; 658 /* this is set only for end_sequence, so that a 659 dw_lns_copy is not generated */ 660 break; 661 662 case DW_LNE_set_address: 663 664 /* first null byte */ 665 db = 0; 666 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 667 error); 668 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 669 sizeof(db), sizeof(Dwarf_Ubyte)); 670 data += sizeof(Dwarf_Ubyte); 671 sum_bytes += sizeof(Dwarf_Ubyte); 672 673 /* write length of extended opcode */ 674 inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size; 675 res = 676 _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, 677 buff1, sizeof(buff1)); 678 if (res != DW_DLV_OK) { 679 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 680 } 681 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); 682 str = buff1; 683 /* leb number, no endian issue */ 684 memcpy((void *) data, (const void *) str, str_nbytes); 685 data += str_nbytes; 686 sum_bytes += str_nbytes; 687 688 /* write extended opcode */ 689 db = DW_LNE_set_address; 690 GET_CHUNK(dbg, elfsectno, data, upointer_size + 691 sizeof(Dwarf_Ubyte), error); 692 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 693 sizeof(db), sizeof(Dwarf_Ubyte)); 694 data += sizeof(Dwarf_Ubyte); 695 sum_bytes += sizeof(Dwarf_Ubyte); 696 697 /* reloc for address */ 698 res = dbg->de_reloc_name(dbg, DEBUG_LINE, sum_bytes, /* r_offset 699 */ 700 curline->dpl_r_symidx, 701 dwarf_drt_data_reloc, 702 uwordb_size); 703 if (res != DW_DLV_OK) { 704 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 705 } 706 707 /* write offset (address) */ 708 du = curline->dpl_address; 709 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 710 sizeof(du), upointer_size); 711 data += upointer_size; 712 sum_bytes += upointer_size; 713 prevline->dpl_address = curline->dpl_address; 714 no_lns_copy = 1; 715 break; 716 } 717 } else { 718 if (curline->dpl_file != prevline->dpl_file) { 719 db = DW_LNS_set_file; 720 res = 721 _dwarf_pro_encode_leb128_nm(curline->dpl_file, 722 &nbytes, buff1, 723 sizeof(buff1)); 724 if (res != DW_DLV_OK) { 725 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 726 } 727 arg = buff1; 728 GET_CHUNK(dbg, elfsectno, data, 729 nbytes + sizeof(Dwarf_Ubyte), error); 730 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 731 sizeof(db), sizeof(Dwarf_Ubyte)); 732 data += sizeof(Dwarf_Ubyte); 733 memcpy((void *) data, (const void *) arg, nbytes); 734 data += nbytes; 735 sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 736 prevline->dpl_file = curline->dpl_file; 737 } 738 if (curline->dpl_column != prevline->dpl_column) { 739 db = DW_LNS_set_column; 740 res = _dwarf_pro_encode_leb128_nm(curline->dpl_column, 741 &nbytes, 742 buff1, sizeof(buff1)); 743 if (res != DW_DLV_OK) { 744 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 745 } 746 747 arg = buff1; 748 GET_CHUNK(dbg, elfsectno, data, 749 nbytes + sizeof(Dwarf_Ubyte), error); 750 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 751 sizeof(db), sizeof(Dwarf_Ubyte)); 752 data += sizeof(Dwarf_Ubyte); 753 memcpy((void *) data, (const void *) arg, nbytes); 754 data += nbytes; 755 sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 756 prevline->dpl_column = curline->dpl_column; 757 } 758 if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { 759 db = DW_LNS_negate_stmt; 760 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 761 error); 762 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 763 sizeof(db), sizeof(Dwarf_Ubyte)); 764 data += sizeof(Dwarf_Ubyte); 765 sum_bytes += sizeof(Dwarf_Ubyte); 766 prevline->dpl_is_stmt = curline->dpl_is_stmt; 767 } 768 if (curline->dpl_basic_block == true && 769 prevline->dpl_basic_block == false) { 770 db = DW_LNS_set_basic_block; 771 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 772 error); 773 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 774 sizeof(db), sizeof(Dwarf_Ubyte)); 775 data += sizeof(Dwarf_Ubyte); 776 sum_bytes += sizeof(Dwarf_Ubyte); 777 prevline->dpl_basic_block = curline->dpl_basic_block; 778 } 779 addr_adv = curline->dpl_address - prevline->dpl_address; 780 781 line_adv = (int) (curline->dpl_line - prevline->dpl_line); 782 if ((addr_adv % MIN_INST_LENGTH) != 0) { 783 DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1); 784 } 785 if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) { 786 no_lns_copy = 1; 787 db = opc; 788 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 789 error); 790 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 791 sizeof(db), sizeof(Dwarf_Ubyte)); 792 data += sizeof(Dwarf_Ubyte); 793 sum_bytes += sizeof(Dwarf_Ubyte); 794 prevline->dpl_basic_block = false; 795 prevline->dpl_address = curline->dpl_address; 796 prevline->dpl_line = curline->dpl_line; 797 } else { 798 if (addr_adv > 0) { 799 db = DW_LNS_advance_pc; 800 res = 801 _dwarf_pro_encode_leb128_nm(addr_adv / 802 MIN_INST_LENGTH, 803 &nbytes, buff1, 804 sizeof(buff1)); 805 if (res != DW_DLV_OK) { 806 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 807 } 808 809 arg = buff1; 810 GET_CHUNK(dbg, elfsectno, data, 811 nbytes + sizeof(Dwarf_Ubyte), error); 812 WRITE_UNALIGNED(dbg, (void *) data, 813 (const void *) &db, 814 sizeof(db), sizeof(Dwarf_Ubyte)); 815 data += sizeof(Dwarf_Ubyte); 816 memcpy((void *) data, (const void *) arg, nbytes); 817 data += nbytes + sizeof(Dwarf_Ubyte); 818 sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 819 prevline->dpl_basic_block = false; 820 prevline->dpl_address = curline->dpl_address; 821 } 822 if (line_adv != 0) { 823 db = DW_LNS_advance_line; 824 res = _dwarf_pro_encode_signed_leb128_nm(line_adv, 825 &nbytes, 826 buff1, 827 sizeof 828 (buff1)); 829 if (res != DW_DLV_OK) { 830 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 831 } 832 833 arg = buff1; 834 GET_CHUNK(dbg, elfsectno, data, 835 nbytes + sizeof(Dwarf_Ubyte), error); 836 WRITE_UNALIGNED(dbg, (void *) data, 837 (const void *) &db, sizeof(db), 838 sizeof(Dwarf_Ubyte)); 839 data += sizeof(Dwarf_Ubyte); 840 memcpy((void *) data, (const void *) arg, nbytes); 841 data += nbytes + sizeof(Dwarf_Ubyte); 842 sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 843 prevline->dpl_basic_block = false; 844 prevline->dpl_line = curline->dpl_line; 845 } 846 } 847 } /* ends else for opc != 0 */ 848 if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq 849 generate a matrix line */ 850 db = DW_LNS_copy; 851 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error); 852 WRITE_UNALIGNED(dbg, (void *) data, 853 (const void *) &db, 854 sizeof(db), sizeof(Dwarf_Ubyte)); 855 data += sizeof(Dwarf_Ubyte); 856 sum_bytes += sizeof(Dwarf_Ubyte); 857 prevline->dpl_basic_block = false; 858 } 859 curline = curline->dpl_next; 860 } 861 862 /* write total length field */ 863 du = sum_bytes - uwordb_size - extension_size; /* subtract 864 length field 865 */ 866 { 867 start_line_sec += extension_size; 868 WRITE_UNALIGNED(dbg, (void *) start_line_sec, 869 (const void *) &du, sizeof(du), uwordb_size); 870 } 871 872 return (int) dbg->de_n_debug_sect; 873 } 874 875 /*--------------------------------------------------------------- 876 Generate debug_frame section 877 ---------------------------------------------------------------*/ 878 static int 879 _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) 880 { 881 int elfsectno; 882 int i; 883 int firsttime = 1; 884 int pad; /* pad for padding to align cies and 885 fdes */ 886 Dwarf_P_Cie curcie; 887 Dwarf_P_Fde curfde; 888 unsigned char *data; 889 Dwarf_sfixed dsw; 890 Dwarf_Unsigned du; 891 Dwarf_Ubyte db; 892 long *cie_offs; /* holds byte offsets for links to 893 fde's */ 894 unsigned long cie_length; 895 int cie_no; 896 int uwordb_size = dbg->de_offset_size; 897 int extension_size = dbg->de_64bit_extension ? 4 : 0; 898 int upointer_size = dbg->de_pointer_size; 899 Dwarf_Unsigned cur_off; /* current offset of written data, 900 held for relocation info */ 901 902 elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; 903 904 curcie = dbg->de_frame_cies; 905 cie_length = 0; 906 cur_off = 0; 907 cie_offs = (long *) 908 _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); 909 if (cie_offs == NULL) { 910 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 911 } 912 /* generate cie number as we go along */ 913 cie_no = 1; 914 while (curcie) { 915 char *code_al; 916 int c_bytes; 917 char *data_al; 918 int d_bytes; 919 int res; 920 char buff1[ENCODE_SPACE_NEEDED]; 921 char buff2[ENCODE_SPACE_NEEDED]; 922 char buff3[ENCODE_SPACE_NEEDED]; 923 char *augmentation; 924 char *augmented_al; 925 long augmented_fields_length; 926 int a_bytes; 927 928 res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, 929 &c_bytes, 930 buff1, sizeof(buff1)); 931 if (res != DW_DLV_OK) { 932 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 933 } 934 /* Before April 1999, the following was using an unsigned 935 encode. That worked ok even though the decoder used the 936 correct signed leb read, but doing the encode correctly 937 (according to the dwarf spec) saves space in the output file 938 and is completely compatible. 939 940 Note the actual stored amount on MIPS was 10 bytes (!) to 941 store the value -4. (hex)fc ffffffff ffffffff 01 The 942 libdwarf consumer consumed all 10 bytes too! 943 944 old version res = 945 _dwarf_pro_encode_leb128_nm(curcie->cie_data_align, 946 947 below is corrected signed version. */ 948 res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align, 949 &d_bytes, 950 buff2, sizeof(buff2)); 951 if (res != DW_DLV_OK) { 952 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 953 } 954 code_al = buff1; 955 data_al = buff2; 956 957 /* get the correct offset */ 958 if (firsttime) { 959 cie_offs[cie_no - 1] = 0; 960 firsttime = 0; 961 } else { 962 cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + 963 (long) cie_length + uwordb_size + extension_size; 964 } 965 cie_no++; 966 augmentation = curcie->cie_aug; 967 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { 968 augmented_fields_length = 0; 969 res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, 970 &a_bytes, buff3, 971 sizeof(buff3)); 972 augmented_al = buff3; 973 if (res != DW_DLV_OK) { 974 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 975 } 976 cie_length = uwordb_size + /* cie_id */ 977 sizeof(Dwarf_Ubyte) + /* cie version */ 978 strlen(curcie->cie_aug) + 1 + /* augmentation */ 979 c_bytes + /* code alignment factor */ 980 d_bytes + /* data alignment factor */ 981 sizeof(Dwarf_Ubyte) + /* return reg address */ 982 a_bytes + /* augmentation length */ 983 curcie->cie_inst_bytes; 984 } else { 985 cie_length = uwordb_size + /* cie_id */ 986 sizeof(Dwarf_Ubyte) + /* cie version */ 987 strlen(curcie->cie_aug) + 1 + /* augmentation */ 988 c_bytes + d_bytes + sizeof(Dwarf_Ubyte) + /* return 989 reg 990 address 991 */ 992 curcie->cie_inst_bytes; 993 } 994 pad = (int) PADDING(cie_length, upointer_size); 995 cie_length += pad; 996 GET_CHUNK(dbg, elfsectno, data, cie_length + uwordb_size 997 + extension_size, error); 998 if (extension_size) { 999 Dwarf_Unsigned x = DISTINGUISHED_VALUE; 1000 1001 WRITE_UNALIGNED(dbg, (void *) data, 1002 (const void *) &x, 1003 sizeof(x), extension_size); 1004 data += extension_size; 1005 1006 } 1007 du = cie_length; 1008 /* total length of cie */ 1009 WRITE_UNALIGNED(dbg, (void *) data, 1010 (const void *) &du, sizeof(du), uwordb_size); 1011 data += uwordb_size; 1012 1013 /* cie-id is a special value. */ 1014 du = DW_CIE_ID; 1015 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 1016 sizeof(du), uwordb_size); 1017 data += uwordb_size; 1018 1019 db = curcie->cie_version; 1020 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1021 sizeof(db), sizeof(Dwarf_Ubyte)); 1022 data += sizeof(Dwarf_Ubyte); 1023 strcpy((char *) data, curcie->cie_aug); 1024 data += strlen(curcie->cie_aug) + 1; 1025 memcpy((void *) data, (const void *) code_al, c_bytes); 1026 data += c_bytes; 1027 memcpy((void *) data, (const void *) data_al, d_bytes); 1028 data += d_bytes; 1029 db = curcie->cie_ret_reg; 1030 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1031 sizeof(db), sizeof(Dwarf_Ubyte)); 1032 data += sizeof(Dwarf_Ubyte); 1033 1034 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { 1035 memcpy((void *) data, (const void *) augmented_al, a_bytes); 1036 data += a_bytes; 1037 } 1038 memcpy((void *) data, (const void *) curcie->cie_inst, 1039 curcie->cie_inst_bytes); 1040 data += curcie->cie_inst_bytes; 1041 for (i = 0; i < pad; i++) { 1042 *data = DW_CFA_nop; 1043 data++; 1044 } 1045 curcie = curcie->cie_next; 1046 } 1047 /* calculate current offset */ 1048 cur_off = cie_offs[cie_no - 2] + cie_length + uwordb_size 1049 + extension_size; 1050 1051 /* write out fde's */ 1052 curfde = dbg->de_frame_fdes; 1053 while (curfde) { 1054 Dwarf_P_Frame_Pgm curinst; 1055 long fde_length; 1056 int pad; 1057 Dwarf_P_Cie cie_ptr; 1058 Dwarf_Word cie_index, index; 1059 int oet_length, afl_length, res; 1060 int v0_augmentation = 0; 1061 1062 #if 0 1063 unsigned char *fde_start_point; 1064 #endif 1065 1066 char afl_buff[ENCODE_SPACE_NEEDED]; 1067 1068 /* Find the CIE associated with this fde. */ 1069 cie_ptr = dbg->de_frame_cies; 1070 cie_index = curfde->fde_cie; 1071 index = 1; /* The cie_index of the first cie is 1, 1072 not 0. */ 1073 while (cie_ptr && index < cie_index) { 1074 cie_ptr = cie_ptr->cie_next; 1075 index++; 1076 } 1077 if (cie_ptr == NULL) { 1078 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1); 1079 } 1080 1081 if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { 1082 v0_augmentation = 1; 1083 oet_length = sizeof(Dwarf_sfixed); 1084 /* encode the length of augmented fields. */ 1085 res = _dwarf_pro_encode_leb128_nm(oet_length, 1086 &afl_length, afl_buff, 1087 sizeof(afl_buff)); 1088 if (res != DW_DLV_OK) { 1089 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 1090 } 1091 1092 fde_length = curfde->fde_n_bytes + uwordb_size + /* cie 1093 pointer 1094 */ 1095 upointer_size + /* initial loc */ 1096 upointer_size + /* address range */ 1097 afl_length + /* augmented field length */ 1098 oet_length; /* exception_table offset */ 1099 } else { 1100 fde_length = curfde->fde_n_bytes + uwordb_size + /* cie 1101 pointer 1102 */ 1103 upointer_size + /* initial loc */ 1104 upointer_size; /* address range */ 1105 } 1106 1107 /* using fde offset, generate DW_AT_MIPS_fde attribute for the 1108 die corresponding to this fde */ 1109 if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error) 1110 < 0) 1111 return -1; 1112 1113 /* store relocation for cie pointer */ 1114 res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + uwordb_size, /* r_offset 1115 */ 1116 dbg->de_sect_name_idx[DEBUG_FRAME], 1117 dwarf_drt_data_reloc, uwordb_size); 1118 if (res != DW_DLV_OK) { 1119 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1120 } 1121 1122 /* store relocation information for initial location */ 1123 res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + uwordb_size + upointer_size, /* r_offset 1124 */ 1125 curfde->fde_r_symidx, 1126 dwarf_drt_data_reloc, upointer_size); 1127 if (res != DW_DLV_OK) { 1128 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1129 } 1130 /* Store the relocation information for the 1131 offset_into_exception_info field, if the offset is valid (0 1132 is a valid offset). */ 1133 if (v0_augmentation && 1134 curfde->fde_offset_into_exception_tables >= 0) { 1135 1136 res = dbg->de_reloc_name(dbg, DEBUG_FRAME, 1137 /* r_offset, where in cie this 1138 field starts */ 1139 cur_off + 2 * uwordb_size + 1140 2 * upointer_size + afl_length, 1141 curfde->fde_exception_table_symbol, 1142 dwarf_drt_segment_rel, 1143 sizeof(Dwarf_sfixed)); 1144 if (res != DW_DLV_OK) { 1145 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1146 } 1147 } 1148 1149 /* adjust for padding */ 1150 pad = (int) PADDING(fde_length, upointer_size); 1151 fde_length += pad; 1152 1153 1154 /* write out fde */ 1155 GET_CHUNK(dbg, elfsectno, data, fde_length + uwordb_size + 1156 extension_size, error); 1157 #if 0 1158 fde_start_point = data; 1159 #endif 1160 du = fde_length; 1161 { 1162 if (extension_size) { 1163 Dwarf_Word x = DISTINGUISHED_VALUE; 1164 1165 WRITE_UNALIGNED(dbg, (void *) data, 1166 (const void *) &x, 1167 sizeof(x), extension_size); 1168 data += extension_size; 1169 } 1170 /* length */ 1171 WRITE_UNALIGNED(dbg, (void *) data, 1172 (const void *) &du, 1173 sizeof(du), uwordb_size); 1174 data += uwordb_size; 1175 1176 /* offset to cie */ 1177 du = cie_offs[curfde->fde_cie - 1]; 1178 WRITE_UNALIGNED(dbg, (void *) data, 1179 (const void *) &du, 1180 sizeof(du), uwordb_size); 1181 data += uwordb_size; 1182 1183 du = curfde->fde_initloc; 1184 WRITE_UNALIGNED(dbg, (void *) data, 1185 (const void *) &du, 1186 sizeof(du), upointer_size); 1187 data += upointer_size; 1188 1189 if (dbg->de_reloc_pair && 1190 curfde->fde_end_symbol != 0 && 1191 curfde->fde_addr_range == 0) { 1192 /* symbolic reloc, need reloc for length What if we 1193 really know the length? If so, should use the other 1194 part of 'if'. */ 1195 Dwarf_Unsigned val; 1196 1197 res = dbg->de_reloc_pair(dbg, 1198 /* DEBUG_ARANGES, */ 1199 DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size, /* r_offset 1200 */ 1201 curfde->fde_r_symidx, 1202 curfde->fde_end_symbol, 1203 dwarf_drt_first_of_length_pair, 1204 upointer_size); 1205 if (res != DW_DLV_OK) { 1206 { 1207 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 1208 return (0); 1209 } 1210 } 1211 1212 /* arrange pre-calc so assem text can do .word end - 1213 begin + val (gets val from stream) */ 1214 val = curfde->fde_end_symbol_offset - 1215 curfde->fde_initloc; 1216 WRITE_UNALIGNED(dbg, data, 1217 (const void *) &val, 1218 sizeof(val), upointer_size); 1219 data += upointer_size; 1220 } else { 1221 1222 du = curfde->fde_addr_range; 1223 WRITE_UNALIGNED(dbg, (void *) data, 1224 (const void *) &du, 1225 sizeof(du), upointer_size); 1226 data += upointer_size; 1227 } 1228 } 1229 1230 if (v0_augmentation) { 1231 /* write the encoded augmented field length. */ 1232 memcpy((void *) data, (const void *) afl_buff, afl_length); 1233 data += afl_length; 1234 /* write the offset_into_exception_tables field. */ 1235 dsw = 1236 (Dwarf_sfixed) curfde->fde_offset_into_exception_tables; 1237 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, 1238 sizeof(dsw), sizeof(Dwarf_sfixed)); 1239 data += sizeof(Dwarf_sfixed); 1240 } 1241 1242 curinst = curfde->fde_inst; 1243 while (curinst) { 1244 db = curinst->dfp_opcode; 1245 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1246 sizeof(db), sizeof(Dwarf_Ubyte)); 1247 data += sizeof(Dwarf_Ubyte); 1248 #if 0 1249 if (curinst->dfp_sym_index) { 1250 int res; 1251 1252 res = dbg->de_reloc_name(dbg, 1253 DEBUG_FRAME, 1254 (data - fde_start_point) 1255 + cur_off + uwordb_size, /* r_offset 1256 */ 1257 curinst->dfp_sym_index, 1258 dwarf_drt_data_reloc, 1259 upointer_size); 1260 if (res != DW_DLV_OK) { 1261 { 1262 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 1263 return (0); 1264 } 1265 } 1266 } 1267 #endif 1268 memcpy((void *) data, 1269 (const void *) curinst->dfp_args, 1270 curinst->dfp_nbytes); 1271 data += curinst->dfp_nbytes; 1272 curinst = curinst->dfp_next; 1273 } 1274 /* padding */ 1275 for (i = 0; i < pad; i++) { 1276 *data = DW_CFA_nop; 1277 data++; 1278 } 1279 cur_off += fde_length + uwordb_size; 1280 curfde = curfde->fde_next; 1281 } 1282 1283 1284 return (int) dbg->de_n_debug_sect; 1285 } 1286 1287 1288 1289 /*--------------------------------------------------------------- 1290 Generate debug_info and debug_abbrev sections 1291 ---------------------------------------------------------------*/ 1292 static int 1293 _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) 1294 { 1295 int elfsectno_of_debug_info; 1296 int abbrevsectno; 1297 unsigned char *data; 1298 int cu_header_size; 1299 Dwarf_P_Abbrev curabbrev, abbrev_head, abbrev_tail; 1300 Dwarf_P_Die curdie; 1301 Dwarf_P_Die first_child; 1302 Dwarf_Word dw; 1303 Dwarf_Unsigned du; 1304 Dwarf_Half dh; 1305 Dwarf_Ubyte db; 1306 Dwarf_Half version; /* need 2 byte quantity */ 1307 Dwarf_Unsigned die_off; /* offset of die in debug_info */ 1308 int n_abbrevs; 1309 int res; 1310 1311 Dwarf_Small *start_info_sec; 1312 1313 int uword_size = dbg->de_offset_size; 1314 int extension_size = dbg->de_64bit_extension ? 4 : 0; 1315 1316 abbrev_head = abbrev_tail = NULL; 1317 elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; 1318 1319 /* write cu header */ 1320 cu_header_size = extension_size + uword_size + /* length of 1321 info section 1322 */ 1323 sizeof(Dwarf_Half) + /* version stamp */ 1324 uword_size + /* offset into abbrev table */ 1325 sizeof(Dwarf_Ubyte); /* size of target address */ 1326 GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size, 1327 error); 1328 start_info_sec = data; 1329 if (extension_size) { 1330 du = DISTINGUISHED_VALUE; 1331 WRITE_UNALIGNED(dbg, (void *) data, 1332 (const void *) &du, sizeof(du), extension_size); 1333 data += extension_size; 1334 } 1335 du = 0; /* length of debug_info, not counting 1336 this field itself (unknown at this 1337 point). */ 1338 WRITE_UNALIGNED(dbg, (void *) data, 1339 (const void *) &du, sizeof(du), uword_size); 1340 data += uword_size; 1341 1342 version = CURRENT_VERSION_STAMP; /* assume this length will not 1343 change */ 1344 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, 1345 sizeof(version), sizeof(Dwarf_Half)); 1346 data += sizeof(Dwarf_Half); 1347 1348 du = 0; /* offset into abbrev table, not yet 1349 known. */ 1350 WRITE_UNALIGNED(dbg, (void *) data, 1351 (const void *) &du, sizeof(du), uword_size); 1352 data += uword_size; 1353 1354 1355 db = dbg->de_pointer_size; 1356 1357 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1358 sizeof(db), 1); 1359 1360 /* We have filled the chunk we got with GET_CHUNK. At this point we 1361 no longer dare use "data" or "start_info_sec" as a pointer any 1362 longer except to refer to that first small chunk for the cu 1363 header. */ 1364 1365 curdie = dbg->de_dies; 1366 1367 /* create AT_macro_info if appropriate */ 1368 if (dbg->de_first_macinfo != NULL) { 1369 if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0) 1370 return -1; 1371 } 1372 1373 /* create AT_stmt_list attribute if necessary */ 1374 if (dwarf_need_debug_line_section(dbg) == TRUE) 1375 if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0) 1376 return -1; 1377 1378 die_off = cu_header_size; 1379 1380 /* 1381 Relocation for abbrev offset in cu header store relocation 1382 record in linked list */ 1383 res = dbg->de_reloc_name(dbg, DEBUG_INFO, extension_size + uword_size + sizeof(Dwarf_Half), /* r_offset 1384 */ 1385 dbg->de_sect_name_idx[DEBUG_ABBREV], 1386 dwarf_drt_data_reloc, uword_size); 1387 if (res != DW_DLV_OK) { 1388 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1389 } 1390 1391 /* pass 0: only top level dies, add at_sibling attribute to those 1392 dies with children */ 1393 first_child = curdie->di_child; 1394 while (first_child && first_child->di_right) { 1395 if (first_child->di_child) 1396 dwarf_add_AT_reference(dbg, 1397 first_child, 1398 DW_AT_sibling, 1399 first_child->di_right, error); 1400 first_child = first_child->di_right; 1401 } 1402 1403 /* pass 1: create abbrev info, get die offsets, calc relocations */ 1404 while (curdie != NULL) { 1405 int nbytes; 1406 Dwarf_P_Attribute curattr; 1407 char *space; 1408 int res; 1409 char buff1[ENCODE_SPACE_NEEDED]; 1410 1411 curdie->di_offset = die_off; 1412 curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head); 1413 if (curabbrev == NULL) { 1414 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1415 } 1416 if (abbrev_head == NULL) { 1417 n_abbrevs = 1; 1418 curabbrev->abb_idx = n_abbrevs; 1419 abbrev_tail = abbrev_head = curabbrev; 1420 } else { 1421 /* check if its a new abbreviation, if yes, add to tail */ 1422 if (curabbrev->abb_idx == 0) { 1423 n_abbrevs++; 1424 curabbrev->abb_idx = n_abbrevs; 1425 abbrev_tail->abb_next = curabbrev; 1426 abbrev_tail = curabbrev; 1427 } 1428 } 1429 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, 1430 &nbytes, 1431 buff1, sizeof(buff1)); 1432 if (res != DW_DLV_OK) { 1433 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1434 } 1435 space = _dwarf_p_get_alloc(dbg, nbytes); 1436 if (space == NULL) { 1437 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1438 } 1439 memcpy(space, buff1, nbytes); 1440 curdie->di_abbrev = space; 1441 curdie->di_abbrev_nbytes = nbytes; 1442 die_off += nbytes; 1443 curattr = curdie->di_attrs; 1444 while (curattr) { 1445 if (curattr->ar_rel_type != R_MIPS_NONE) { 1446 switch (curattr->ar_attribute) { 1447 case DW_AT_stmt_list: 1448 curattr->ar_rel_symidx = 1449 dbg->de_sect_name_idx[DEBUG_LINE]; 1450 break; 1451 case DW_AT_MIPS_fde: 1452 curattr->ar_rel_symidx = 1453 dbg->de_sect_name_idx[DEBUG_FRAME]; 1454 break; 1455 case DW_AT_macro_info: 1456 curattr->ar_rel_symidx = 1457 dbg->de_sect_name_idx[DEBUG_MACINFO]; 1458 break; 1459 default: 1460 break; 1461 } 1462 res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset, /* r_offset 1463 */ 1464 curattr->ar_rel_symidx, 1465 dwarf_drt_data_reloc, 1466 curattr->ar_reloc_len); 1467 1468 if (res != DW_DLV_OK) { 1469 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1470 } 1471 1472 } 1473 die_off += curattr->ar_nbytes; 1474 curattr = curattr->ar_next; 1475 } 1476 /* depth first search */ 1477 if (curdie->di_child) 1478 curdie = curdie->di_child; 1479 else { 1480 while (curdie != NULL && curdie->di_right == NULL) { 1481 curdie = curdie->di_parent; 1482 die_off++; /* since we are writing a null die at 1483 the end of each sibling chain */ 1484 } 1485 if (curdie != NULL) 1486 curdie = curdie->di_right; 1487 } 1488 } 1489 1490 /* Pass 2: Write out the die information Here 'data' is a 1491 temporary, one block for each GET_CHUNK. 'data' is overused. */ 1492 curdie = dbg->de_dies; 1493 while (curdie != NULL) { 1494 Dwarf_P_Attribute curattr; 1495 1496 /* index to abbreviation table */ 1497 GET_CHUNK(dbg, elfsectno_of_debug_info, 1498 data, curdie->di_abbrev_nbytes, error); 1499 1500 memcpy((void *) data, 1501 (const void *) curdie->di_abbrev, 1502 curdie->di_abbrev_nbytes); 1503 1504 /* Attribute values - need to fill in all form attributes */ 1505 curattr = curdie->di_attrs; 1506 while (curattr) { 1507 GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1508 (unsigned long) curattr->ar_nbytes, error); 1509 switch (curattr->ar_attribute_form) { 1510 case DW_FORM_ref1: 1511 { 1512 if (curattr->ar_ref_die->di_offset > 1513 (unsigned) 0xff) { 1514 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1515 } 1516 db = curattr->ar_ref_die->di_offset; 1517 WRITE_UNALIGNED(dbg, (void *) data, 1518 (const void *) &db, 1519 sizeof(db), sizeof(Dwarf_Ubyte)); 1520 break; 1521 } 1522 case DW_FORM_ref2: 1523 { 1524 if (curattr->ar_ref_die->di_offset > 1525 (unsigned) 0xffff) { 1526 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1527 } 1528 dh = curattr->ar_ref_die->di_offset; 1529 WRITE_UNALIGNED(dbg, (void *) data, 1530 (const void *) &dh, 1531 sizeof(dh), sizeof(Dwarf_Half)); 1532 break; 1533 } 1534 case DW_FORM_ref_addr: 1535 { 1536 du = curattr->ar_ref_die->di_offset; 1537 { 1538 /* ref to offset of die */ 1539 WRITE_UNALIGNED(dbg, (void *) data, 1540 (const void *) &du, 1541 sizeof(du), uword_size); 1542 } 1543 break; 1544 1545 } 1546 case DW_FORM_ref4: 1547 { 1548 if (curattr->ar_ref_die->di_offset > 1549 (unsigned) 0xffffffff) { 1550 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1551 } 1552 dw = (Dwarf_Word) curattr->ar_ref_die->di_offset; 1553 WRITE_UNALIGNED(dbg, (void *) data, 1554 (const void *) &dw, 1555 sizeof(dw), sizeof(Dwarf_ufixed)); 1556 break; 1557 } 1558 case DW_FORM_ref8: 1559 du = curattr->ar_ref_die->di_offset; 1560 WRITE_UNALIGNED(dbg, (void *) data, 1561 (const void *) &du, 1562 sizeof(du), sizeof(Dwarf_Unsigned)); 1563 break; 1564 case DW_FORM_ref_udata: 1565 { /* unsigned leb128 offset */ 1566 1567 int nbytes; 1568 char buff1[ENCODE_SPACE_NEEDED]; 1569 1570 res = 1571 _dwarf_pro_encode_leb128_nm(curattr-> 1572 ar_ref_die-> 1573 di_offset, &nbytes, 1574 buff1, 1575 sizeof(buff1)); 1576 if (res != DW_DLV_OK) { 1577 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1578 } 1579 1580 memcpy(data, buff1, nbytes); 1581 break; 1582 } 1583 default: 1584 memcpy((void *) data, 1585 (const void *) curattr->ar_data, 1586 curattr->ar_nbytes); 1587 break; 1588 } 1589 curattr = curattr->ar_next; 1590 } 1591 1592 /* depth first search */ 1593 if (curdie->di_child) 1594 curdie = curdie->di_child; 1595 else { 1596 while (curdie != NULL && curdie->di_right == NULL) { 1597 GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error); 1598 *data = '\0'; 1599 curdie = curdie->di_parent; 1600 } 1601 if (curdie != NULL) 1602 curdie = curdie->di_right; 1603 } 1604 } 1605 1606 /* Write out debug_info size */ 1607 /* Dont include length field or extension bytes */ 1608 du = die_off - uword_size - extension_size; 1609 WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size), 1610 (const void *) &du, sizeof(du), uword_size); 1611 1612 1613 data = 0; /* Emphasise not usable now */ 1614 1615 /* Write out debug_abbrev section */ 1616 abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; 1617 1618 curabbrev = abbrev_head; 1619 while (curabbrev) { 1620 char *val; 1621 int nbytes; 1622 int idx; 1623 int res; 1624 char buff1[ENCODE_SPACE_NEEDED]; 1625 1626 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, 1627 buff1, sizeof(buff1)); 1628 if (res != DW_DLV_OK) { 1629 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1630 } 1631 1632 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1633 val = buff1; 1634 memcpy((void *) data, (const void *) val, nbytes); 1635 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes, 1636 buff1, sizeof(buff1)); 1637 if (res != DW_DLV_OK) { 1638 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1639 } 1640 val = buff1; 1641 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1642 memcpy((void *) data, (const void *) val, nbytes); 1643 db = curabbrev->abb_children; 1644 GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error); 1645 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1646 sizeof(db), sizeof(Dwarf_Ubyte)); 1647 1648 /* add attributes and forms */ 1649 for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { 1650 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx], 1651 &nbytes, 1652 buff1, sizeof(buff1)); 1653 if (res != DW_DLV_OK) { 1654 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1655 } 1656 val = buff1; 1657 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1658 memcpy((void *) data, (const void *) val, nbytes); 1659 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx], 1660 &nbytes, 1661 buff1, sizeof(buff1)); 1662 if (res != DW_DLV_OK) { 1663 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1664 } 1665 val = buff1; 1666 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1667 memcpy((void *) data, (const void *) val, nbytes); 1668 } 1669 GET_CHUNK(dbg, abbrevsectno, data, 2, error); /* two zeros, 1670 for last 1671 entry, see dwarf2 sec 7.5.3 */ 1672 *data = 0; 1673 data++; 1674 *data = 0; 1675 1676 curabbrev = curabbrev->abb_next; 1677 } 1678 1679 GET_CHUNK(dbg,abbrevsectno,data,1,error); /* one zero, 1680 for end of cu, see dwarf2 sec 7.5.3 */ 1681 *data = 0; 1682 1683 1684 return (int) dbg->de_n_debug_sect; 1685 } 1686 1687 1688 /*--------------------------------------------------------------------- 1689 Get a buffer of section data. 1690 section_idx is the elf-section number that this data applies to. 1691 length shows length of returned data 1692 ----------------------------------------------------------------------*/ 1693 /*ARGSUSED*/ /* pretend all args used */ 1694 Dwarf_Ptr 1695 dwarf_get_section_bytes(Dwarf_P_Debug dbg, 1696 Dwarf_Signed dwarf_section, 1697 Dwarf_Signed * section_idx, 1698 Dwarf_Unsigned * length, Dwarf_Error * error) 1699 { 1700 Dwarf_Ptr buf; 1701 1702 if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { 1703 DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL); 1704 } 1705 1706 if (dbg->de_debug_sects == 0) { 1707 /* no more data !! */ 1708 return NULL; 1709 } 1710 if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { 1711 /* no data ever entered !! */ 1712 return NULL; 1713 } 1714 *section_idx = dbg->de_debug_sects->ds_elf_sect_no; 1715 *length = dbg->de_debug_sects->ds_nbytes; 1716 1717 buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; 1718 1719 dbg->de_debug_sects = dbg->de_debug_sects->ds_next; 1720 1721 /* We may want to call the section stuff more than once: see 1722 dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ 1723 1724 return buf; 1725 } 1726 1727 /* 1728 No errors possible. 1729 */ 1730 void 1731 dwarf_reset_section_bytes(Dwarf_P_Debug dbg) 1732 { 1733 dbg->de_debug_sects = dbg->de_first_debug_sect; 1734 /* No need to reset; commented out decrement. dbg->de_n_debug_sect 1735 = ???; */ 1736 dbg->de_reloc_next_to_return = 0; 1737 } 1738 1739 /* 1740 Storage handler. Gets either a new chunk of memory, or 1741 a pointer in existing memory, from the linked list attached 1742 to dbg at de_debug_sects, depending on size of nbytes 1743 1744 Assume dbg not null, checked in top level routine 1745 1746 Returns a pointer to the allocated buffer space for the 1747 lib to fill in, predincrements next-to-use count so the 1748 space requested is already counted 'used' 1749 when this returns (ie, reserved). 1750 1751 */ 1752 Dwarf_Small * 1753 _dwarf_pro_buffer(Dwarf_P_Debug dbg, 1754 int elfsectno, unsigned long nbytes) 1755 { 1756 Dwarf_P_Section_Data cursect; 1757 1758 1759 cursect = dbg->de_current_active_section; 1760 /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must 1761 not match any legit section number. test to have just two 1762 clauses (no NULL pointer test) See dwarf_producer_init(). */ 1763 if ((cursect->ds_elf_sect_no != elfsectno) || 1764 ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc) 1765 ) { 1766 1767 /* Either the elf section has changed or there is not enough 1768 space in the current section. 1769 1770 Create a new Dwarf_P_Section_Data_s for the chunk. and have 1771 space 'on the end' for the buffer itself so we just do one 1772 malloc (not two). 1773 1774 */ 1775 unsigned long space = nbytes; 1776 1777 if (nbytes < CHUNK_SIZE) 1778 space = CHUNK_SIZE; 1779 1780 cursect = (Dwarf_P_Section_Data) 1781 _dwarf_p_get_alloc(dbg, 1782 sizeof(struct Dwarf_P_Section_Data_s) 1783 + space); 1784 1785 1786 if (cursect == NULL) 1787 return (NULL); 1788 1789 /* _dwarf_p_get_alloc zeroes the space... */ 1790 1791 cursect->ds_data = (char *) cursect + 1792 sizeof(struct Dwarf_P_Section_Data_s); 1793 cursect->ds_orig_alloc = space; 1794 cursect->ds_elf_sect_no = elfsectno; 1795 cursect->ds_nbytes = nbytes; /* reserve this number of bytes 1796 of space for caller to fill 1797 in */ 1798 1799 /* Now link on the end of the list, and mark this one as the 1800 current one */ 1801 1802 if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { 1803 /* the only entry is the special one for 'no entry' so 1804 delete that phony one while adding this initial real 1805 one. */ 1806 dbg->de_debug_sects = cursect; 1807 dbg->de_current_active_section = cursect; 1808 dbg->de_first_debug_sect = cursect; 1809 } else { 1810 dbg->de_current_active_section->ds_next = cursect; 1811 dbg->de_current_active_section = cursect; 1812 } 1813 dbg->de_n_debug_sect++; 1814 1815 return ((Dwarf_Small *) cursect->ds_data); 1816 } 1817 1818 /* There is enough space in the current buffer */ 1819 { 1820 Dwarf_Small *space_for_caller = (Dwarf_Small *) 1821 (cursect->ds_data + cursect->ds_nbytes); 1822 1823 cursect->ds_nbytes += nbytes; 1824 return space_for_caller; 1825 } 1826 } 1827 1828 1829 /*------------------------------------------------------------ 1830 Given address advance and line advance, it gives 1831 either special opcode, or a number < 0 1832 ------------------------------------------------------------*/ 1833 static int 1834 _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv) 1835 { 1836 int opc; 1837 1838 addr_adv = addr_adv / MIN_INST_LENGTH; 1839 if (line_adv == 0 && addr_adv == 0) 1840 return OPC_INCS_ZERO; 1841 if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) { 1842 opc = 1843 (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) + 1844 OPCODE_BASE; 1845 if (opc > 255) 1846 return OPC_OUT_OF_RANGE; 1847 return opc; 1848 } else 1849 return LINE_OUT_OF_RANGE; 1850 } 1851 1852 /*----------------------------------------------------------------------- 1853 Handles abbreviations. It takes a die, searches through 1854 current list of abbreviations for matching one. If it 1855 finds one, it returns a pointer to it, and if it doesnt, 1856 it returns a new one. Upto the user of this function to 1857 link it up to the abbreviation head. If its a new one, 1858 abb_idx has 0. 1859 -----------------------------------------------------------------------*/ 1860 static Dwarf_P_Abbrev 1861 _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head) 1862 { 1863 Dwarf_P_Abbrev curabbrev; 1864 Dwarf_P_Attribute curattr; 1865 int res1; 1866 int nattrs; 1867 int match; 1868 Dwarf_ufixed *forms = 0; 1869 Dwarf_ufixed *attrs = 0; 1870 1871 curabbrev = head; 1872 while (curabbrev) { 1873 if ((die->di_tag == curabbrev->abb_tag) && 1874 ((die->di_child != NULL && 1875 curabbrev->abb_children == DW_CHILDREN_yes) || 1876 (die->di_child == NULL && 1877 curabbrev->abb_children == DW_CHILDREN_no)) && 1878 (die->di_n_attr == curabbrev->abb_n_attr)) { 1879 1880 /* There is a chance of a match. */ 1881 curattr = die->di_attrs; 1882 match = 1; /* Assume match found. */ 1883 while (match && curattr) { 1884 res1 = _dwarf_pro_match_attr(curattr, 1885 curabbrev, 1886 (int) curabbrev-> 1887 abb_n_attr); 1888 if (res1 == 0) 1889 match = 0; 1890 curattr = curattr->ar_next; 1891 } 1892 if (match == 1) 1893 return curabbrev; 1894 } 1895 curabbrev = curabbrev->abb_next; 1896 } 1897 1898 /* no match, create new abbreviation */ 1899 if (die->di_n_attr != 0) { 1900 forms = (Dwarf_ufixed *) 1901 _dwarf_p_get_alloc(NULL, 1902 sizeof(Dwarf_ufixed) * die->di_n_attr); 1903 if (forms == NULL) 1904 return NULL; 1905 attrs = (Dwarf_ufixed *) 1906 _dwarf_p_get_alloc(NULL, 1907 sizeof(Dwarf_ufixed) * die->di_n_attr); 1908 if (attrs == NULL) 1909 return NULL; 1910 } 1911 nattrs = 0; 1912 curattr = die->di_attrs; 1913 while (curattr) { 1914 attrs[nattrs] = curattr->ar_attribute; 1915 forms[nattrs] = curattr->ar_attribute_form; 1916 nattrs++; 1917 curattr = curattr->ar_next; 1918 } 1919 1920 curabbrev = (Dwarf_P_Abbrev) 1921 _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Abbrev_s)); 1922 if (curabbrev == NULL) 1923 return NULL; 1924 1925 if (die->di_child == NULL) 1926 curabbrev->abb_children = DW_CHILDREN_no; 1927 else 1928 curabbrev->abb_children = DW_CHILDREN_yes; 1929 curabbrev->abb_tag = die->di_tag; 1930 curabbrev->abb_attrs = attrs; 1931 curabbrev->abb_forms = forms; 1932 curabbrev->abb_n_attr = die->di_n_attr; 1933 curabbrev->abb_idx = 0; 1934 curabbrev->abb_next = NULL; 1935 1936 return curabbrev; 1937 } 1938 1939 /*------------------------------------------------------------------ 1940 Tries to see if given attribute and form combination 1941 exists in the given abbreviation 1942 -------------------------------------------------------------------*/ 1943 static int 1944 _dwarf_pro_match_attr(Dwarf_P_Attribute attr, 1945 Dwarf_P_Abbrev abbrev, int no_attr) 1946 { 1947 int i; 1948 int found = 0; 1949 1950 for (i = 0; i < no_attr; i++) { 1951 if (attr->ar_attribute == abbrev->abb_attrs[i] && 1952 attr->ar_attribute_form == abbrev->abb_forms[i]) { 1953 found = 1; 1954 break; 1955 } 1956 } 1957 return found; 1958 } 1959