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