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