1/* 2 3 Copyright (C) 2000,2004 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#include <limits.h> 43#include "pro_incl.h" 44#include "pro_expr.h" 45 46#ifndef R_MIPS_NONE 47#define R_MIPS_NONE 0 48#endif 49 50 51 /* Indicates no relocation needed. */ 52#define NO_ELF_SYM_INDEX 0 53 54 55/* adds an attribute to a die */ 56extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, 57 Dwarf_P_Attribute attr); 58 59/* 60 This function adds an attribute whose value is 61 a target address to the given die. The attribute 62 is given the name provided by attr. The address 63 is given in pc_value. 64*/ 65/* old interface */ 66Dwarf_P_Attribute 67dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, 68 Dwarf_P_Die ownerdie, 69 Dwarf_Half attr, 70 Dwarf_Unsigned pc_value, 71 Dwarf_Signed sym_index, Dwarf_Error * error) 72{ 73 return 74 dwarf_add_AT_targ_address_b(dbg, 75 ownerdie, 76 attr, 77 pc_value, 78 (Dwarf_Unsigned) sym_index, error); 79} 80 81/* new interface */ 82Dwarf_P_Attribute 83dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, 84 Dwarf_P_Die ownerdie, 85 Dwarf_Half attr, 86 Dwarf_Unsigned pc_value, 87 Dwarf_Unsigned sym_index, 88 Dwarf_Error * error) 89{ 90 Dwarf_P_Attribute new_attr; 91 int upointer_size = dbg->de_pointer_size; 92 93 if (dbg == NULL) { 94 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 95 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 96 } 97 98 if (ownerdie == NULL) { 99 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 100 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 101 } 102 103 if (attr != DW_AT_low_pc && attr != DW_AT_high_pc && 104 attr != DW_AT_MIPS_loop_begin && 105 attr != DW_AT_MIPS_tail_loop_begin && 106 attr != DW_AT_MIPS_epilog_begin) { 107 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 108 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 109 } 110 111 new_attr = (Dwarf_P_Attribute) 112 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 113 if (new_attr == NULL) { 114 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 115 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 116 } 117 118 new_attr->ar_attribute = attr; 119 new_attr->ar_attribute_form = DW_FORM_addr; 120 new_attr->ar_nbytes = upointer_size; 121 new_attr->ar_rel_symidx = sym_index; 122 new_attr->ar_reloc_len = upointer_size; 123 new_attr->ar_next = 0; 124 if (sym_index != NO_ELF_SYM_INDEX) 125 new_attr->ar_rel_type = dbg->de_ptr_reloc; 126 else 127 new_attr->ar_rel_type = R_MIPS_NONE; 128 129 new_attr->ar_data = (char *) 130 _dwarf_p_get_alloc(dbg, upointer_size); 131 if (new_attr->ar_data == NULL) { 132 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 133 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 134 } 135 WRITE_UNALIGNED(dbg, new_attr->ar_data, 136 (const void *) &pc_value, 137 sizeof(pc_value), upointer_size); 138 139 /* add attribute to the die */ 140 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 141 return new_attr; 142} 143 144 145/* 146 This function adds attributes whose value 147 is an unsigned constant. It determines the 148 size of the value field from the value of 149 the constant. 150*/ 151Dwarf_P_Attribute 152dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, 153 Dwarf_P_Die ownerdie, 154 Dwarf_Half attr, 155 Dwarf_Unsigned value, Dwarf_Error * error) 156{ 157 Dwarf_P_Attribute new_attr; 158 Dwarf_Half attr_form; 159 Dwarf_Small size; 160 161 if (dbg == NULL) { 162 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 163 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 164 } 165 166 if (ownerdie == NULL) { 167 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 168 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 169 } 170 171 switch (attr) { 172 case DW_AT_ordering: 173 case DW_AT_byte_size: 174 case DW_AT_bit_offset: 175 case DW_AT_bit_size: 176 case DW_AT_inline: 177 case DW_AT_language: 178 case DW_AT_visibility: 179 case DW_AT_virtuality: 180 case DW_AT_accessibility: 181 case DW_AT_address_class: 182 case DW_AT_calling_convention: 183 case DW_AT_encoding: 184 case DW_AT_identifier_case: 185 case DW_AT_MIPS_loop_unroll_factor: 186 case DW_AT_MIPS_software_pipeline_depth: 187 break; 188 189 case DW_AT_decl_column: 190 case DW_AT_decl_file: 191 case DW_AT_decl_line: 192 case DW_AT_const_value: 193 case DW_AT_start_scope: 194 case DW_AT_stride_size: 195 case DW_AT_count: 196 break; 197 198 default:{ 199 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 200 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 201 } 202 } 203 204 /* 205 Compute the number of bytes needed to hold constant. */ 206 if (value <= UCHAR_MAX) { 207 attr_form = DW_FORM_data1; 208 size = 1; 209 } else if (value <= USHRT_MAX) { 210 attr_form = DW_FORM_data2; 211 size = 2; 212 } else if (value <= UINT_MAX) { 213 attr_form = DW_FORM_data4; 214 size = 4; 215 } else { 216 attr_form = DW_FORM_data8; 217 size = 8; 218 } 219 220 new_attr = (Dwarf_P_Attribute) 221 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 222 if (new_attr == NULL) { 223 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 224 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 225 } 226 227 new_attr->ar_attribute = attr; 228 new_attr->ar_attribute_form = attr_form; 229 new_attr->ar_rel_type = R_MIPS_NONE; 230 new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ 231 new_attr->ar_nbytes = size; 232 new_attr->ar_next = 0; 233 234 new_attr->ar_data = (char *) 235 _dwarf_p_get_alloc(dbg, size); 236 if (new_attr->ar_data == NULL) { 237 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 238 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 239 } 240 WRITE_UNALIGNED(dbg, new_attr->ar_data, 241 (const void *) &value, sizeof(value), size); 242 243 /* add attribute to the die */ 244 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 245 return new_attr; 246} 247 248 249/* 250 This function adds attributes whose value 251 is an signed constant. It determines the 252 size of the value field from the value of 253 the constant. 254*/ 255Dwarf_P_Attribute 256dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, 257 Dwarf_P_Die ownerdie, 258 Dwarf_Half attr, 259 Dwarf_Signed value, Dwarf_Error * error) 260{ 261 Dwarf_P_Attribute new_attr; 262 Dwarf_Half attr_form; 263 Dwarf_Small size; 264 265 if (dbg == NULL) { 266 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 267 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 268 } 269 270 if (ownerdie == NULL) { 271 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 272 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 273 } 274 275 switch (attr) { 276 case DW_AT_upper_bound: 277 case DW_AT_lower_bound: 278 break; 279 280 default:{ 281 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 282 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 283 } 284 } 285 286 /* 287 Compute the number of bytes needed to hold constant. */ 288 if (value >= SCHAR_MIN && value <= SCHAR_MAX) { 289 attr_form = DW_FORM_data1; 290 size = 1; 291 } else if (value >= SHRT_MIN && value <= SHRT_MAX) { 292 attr_form = DW_FORM_data2; 293 size = 2; 294 } else if (value >= INT_MIN && value <= INT_MAX) { 295 attr_form = DW_FORM_data4; 296 size = 4; 297 } else { 298 attr_form = DW_FORM_data8; 299 size = 8; 300 } 301 302 new_attr = (Dwarf_P_Attribute) 303 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 304 if (new_attr == NULL) { 305 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 306 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 307 } 308 309 new_attr->ar_attribute = attr; 310 new_attr->ar_attribute_form = attr_form; 311 new_attr->ar_rel_type = R_MIPS_NONE; 312 new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ 313 new_attr->ar_nbytes = size; 314 new_attr->ar_next = 0; 315 316 new_attr->ar_data = (char *) 317 _dwarf_p_get_alloc(dbg, size); 318 if (new_attr->ar_data == NULL) { 319 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 320 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 321 } 322 WRITE_UNALIGNED(dbg, new_attr->ar_data, 323 (const void *) &value, sizeof(value), size); 324 325 /* add attribute to the die */ 326 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 327 return new_attr; 328} 329 330 331/* 332 This function adds attributes whose value 333 is a location expression. 334*/ 335Dwarf_P_Attribute 336dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, 337 Dwarf_P_Die ownerdie, 338 Dwarf_Half attr, 339 Dwarf_P_Expr loc_expr, Dwarf_Error * error) 340{ 341 char encode_buffer[ENCODE_SPACE_NEEDED]; 342 int res; 343 Dwarf_P_Attribute new_attr; 344 Dwarf_Half attr_form; 345 char *len_str; 346 int len_size; 347 int block_size; 348 char *block_dest_ptr; 349 int do_len_as_int = 0; 350 351 if (dbg == NULL) { 352 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 353 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 354 } 355 356 if (ownerdie == NULL) { 357 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 358 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 359 } 360 361 if (loc_expr == NULL) { 362 _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); 363 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 364 } 365 366 if (loc_expr->ex_dbg != dbg) { 367 _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); 368 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 369 } 370 block_size = loc_expr->ex_next_byte_offset; 371 372 switch (attr) { 373 case DW_AT_location: 374 case DW_AT_string_length: 375 case DW_AT_const_value: 376 case DW_AT_use_location: 377 case DW_AT_return_addr: 378 case DW_AT_data_member_location: 379 case DW_AT_frame_base: 380 case DW_AT_static_link: 381 case DW_AT_vtable_elem_location: 382 break; 383 384 default:{ 385 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 386 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 387 } 388 } 389 390 /* 391 Compute the number of bytes needed to hold constant. */ 392 if (block_size <= UCHAR_MAX) { 393 attr_form = DW_FORM_block1; 394 len_size = 1; 395 do_len_as_int = 1; 396 } else if (block_size <= USHRT_MAX) { 397 attr_form = DW_FORM_block2; 398 len_size = 2; 399 do_len_as_int = 1; 400 } else if (block_size <= UINT_MAX) { 401 attr_form = DW_FORM_block4; 402 len_size = 4; 403 do_len_as_int = 1; 404 } else { 405 attr_form = DW_FORM_block; 406 res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, 407 encode_buffer, 408 sizeof(encode_buffer)); 409 if (res != DW_DLV_OK) { 410 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 411 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 412 } 413 len_str = (char *) encode_buffer; 414 } 415 416 new_attr = (Dwarf_P_Attribute) 417 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 418 if (new_attr == NULL) { 419 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 420 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 421 } 422 423 new_attr->ar_attribute = attr; 424 new_attr->ar_attribute_form = attr_form; 425 new_attr->ar_reloc_len = dbg->de_pointer_size; 426 if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { 427 new_attr->ar_rel_type = dbg->de_ptr_reloc; 428 } else { 429 new_attr->ar_rel_type = R_MIPS_NONE; 430 } 431 new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; 432 new_attr->ar_rel_offset = 433 (Dwarf_Word) loc_expr->ex_reloc_offset + len_size; 434 435 new_attr->ar_nbytes = block_size + len_size; 436 437 new_attr->ar_next = 0; 438 new_attr->ar_data = block_dest_ptr = 439 (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); 440 if (new_attr->ar_data == NULL) { 441 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 442 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 443 } 444 445 if (do_len_as_int) { 446 WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size, 447 sizeof(block_size), len_size); 448 } else { 449 /* is uleb number form */ 450 memcpy(block_dest_ptr, len_str, len_size); 451 } 452 block_dest_ptr += len_size; 453 memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); 454 455 /* add attribute to the die */ 456 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 457 return new_attr; 458} 459 460 461/* 462 This function adds attributes of reference class. 463 The references here are local CU references, 464 not DW_FORM_ref_addr. 465 The offset field is 4 bytes for 32-bit objects, 466 and 8-bytes for 64-bit objects. Otherdie is the 467 that is referenced by ownerdie. 468 469 For reference attributes, the ar_data and ar_nbytes 470 are not needed. Instead, the ar_ref_die points to 471 the other die, and its di_offset value is used as 472 the reference value. 473*/ 474Dwarf_P_Attribute 475dwarf_add_AT_reference(Dwarf_P_Debug dbg, 476 Dwarf_P_Die ownerdie, 477 Dwarf_Half attr, 478 Dwarf_P_Die otherdie, Dwarf_Error * error) 479{ 480 Dwarf_P_Attribute new_attr; 481 482 if (dbg == NULL) { 483 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 484 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 485 } 486 487 if (ownerdie == NULL) { 488 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 489 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 490 } 491 492 if (otherdie == NULL) { 493 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 494 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 495 } 496 497 switch (attr) { 498 case DW_AT_specification: 499 case DW_AT_discr: 500 case DW_AT_common_reference: 501 case DW_AT_import: 502 case DW_AT_containing_type: 503 case DW_AT_default_value: 504 case DW_AT_abstract_origin: 505 case DW_AT_friend: 506 case DW_AT_priority: 507 case DW_AT_type: 508 case DW_AT_lower_bound: 509 case DW_AT_upper_bound: 510 case DW_AT_count: 511 case DW_AT_sibling: 512 case DW_AT_MIPS_stride: 513 case DW_AT_MIPS_stride_byte: 514 case DW_AT_MIPS_stride_elem: 515 case DW_AT_MIPS_clone_origin: 516 case DW_AT_MIPS_ptr_dopetype: 517 case DW_AT_MIPS_allocatable_dopetype: 518 case DW_AT_MIPS_assumed_shape_dopetype: 519 break; 520 521 default:{ 522 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 523 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 524 } 525 } 526 527 new_attr = (Dwarf_P_Attribute) 528 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 529 if (new_attr == NULL) { 530 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 531 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 532 } 533 534 new_attr->ar_attribute = attr; 535 new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; 536 new_attr->ar_nbytes = dbg->de_offset_size; 537 new_attr->ar_reloc_len = dbg->de_offset_size; 538 new_attr->ar_ref_die = otherdie; 539 new_attr->ar_rel_type = R_MIPS_NONE; 540 new_attr->ar_next = 0; 541 542 /* add attribute to the die */ 543 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 544 return new_attr; 545} 546 547 548/* 549 This function adds attributes of the flag class. 550*/ 551Dwarf_P_Attribute 552dwarf_add_AT_flag(Dwarf_P_Debug dbg, 553 Dwarf_P_Die ownerdie, 554 Dwarf_Half attr, 555 Dwarf_Small flag, Dwarf_Error * error) 556{ 557 Dwarf_P_Attribute new_attr; 558 559 if (dbg == NULL) { 560 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 561 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 562 } 563 564 if (ownerdie == NULL) { 565 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 566 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 567 } 568 569 switch (attr) { 570 case DW_AT_is_optional: 571 case DW_AT_artificial: 572 case DW_AT_declaration: 573 case DW_AT_external: 574 case DW_AT_prototyped: 575 case DW_AT_variable_parameter: 576 case DW_AT_MIPS_has_inlines: 577 case DW_AT_MIPS_assumed_size: 578 break; 579 580 default:{ 581 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 582 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 583 } 584 } 585 586 new_attr = (Dwarf_P_Attribute) 587 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 588 if (new_attr == NULL) { 589 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 590 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 591 } 592 593 new_attr->ar_attribute = attr; 594 new_attr->ar_attribute_form = DW_FORM_flag; 595 new_attr->ar_nbytes = 1; 596 new_attr->ar_reloc_len = 0; /* not used */ 597 new_attr->ar_rel_type = R_MIPS_NONE; 598 new_attr->ar_next = 0; 599 600 new_attr->ar_data = (char *) 601 _dwarf_p_get_alloc(dbg, 1); 602 if (new_attr->ar_data == NULL) { 603 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 604 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 605 } 606 memcpy(new_attr->ar_data, &flag, 1); 607 608 /* add attribute to the die */ 609 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 610 return new_attr; 611} 612 613 614/* 615 This function adds values of attributes 616 belonging to the string class. 617*/ 618Dwarf_P_Attribute 619dwarf_add_AT_string(Dwarf_P_Debug dbg, 620 Dwarf_P_Die ownerdie, 621 Dwarf_Half attr, char *string, Dwarf_Error * error) 622{ 623 Dwarf_P_Attribute new_attr; 624 625 if (dbg == NULL) { 626 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 627 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 628 } 629 630 if (ownerdie == NULL) { 631 _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 632 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 633 } 634 635 new_attr = (Dwarf_P_Attribute) 636 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 637 if (new_attr == NULL) { 638 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 639 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 640 } 641 642 switch (attr) { 643 case DW_AT_name: 644 case DW_AT_comp_dir: 645 case DW_AT_const_value: 646 case DW_AT_producer: 647 case DW_AT_MIPS_linkage_name: 648 case DW_AT_MIPS_abstract_name: 649 break; 650 651 default:{ 652 _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 653 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 654 } 655 } 656 657 new_attr->ar_attribute = attr; 658 new_attr->ar_attribute_form = DW_FORM_string; 659 new_attr->ar_nbytes = strlen(string) + 1; 660 new_attr->ar_next = 0; 661 662 new_attr->ar_data = 663 (char *) _dwarf_p_get_alloc(NULL, strlen(string) + 1); 664 if (new_attr->ar_data == NULL) { 665 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 666 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 667 } 668 669 strcpy(new_attr->ar_data, string); 670 new_attr->ar_rel_type = R_MIPS_NONE; 671 new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 672 673 /* add attribute to the die */ 674 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 675 return new_attr; 676} 677 678 679Dwarf_P_Attribute 680dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, 681 char *string_value, Dwarf_Error * error) 682{ 683 Dwarf_P_Attribute new_attr; 684 685 if (ownerdie == NULL) { 686 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 687 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 688 } 689 690 new_attr = (Dwarf_P_Attribute) 691 _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); 692 if (new_attr == NULL) { 693 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 694 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 695 } 696 697 new_attr->ar_attribute = DW_AT_const_value; 698 new_attr->ar_attribute_form = DW_FORM_string; 699 new_attr->ar_nbytes = strlen(string_value) + 1; 700 new_attr->ar_next = 0; 701 702 new_attr->ar_data = 703 (char *) _dwarf_p_get_alloc(NULL, strlen(string_value) + 1); 704 if (new_attr->ar_data == NULL) { 705 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 706 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 707 } 708 709 strcpy(new_attr->ar_data, string_value); 710 new_attr->ar_rel_type = R_MIPS_NONE; 711 new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 712 713 /* add attribute to the die */ 714 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 715 return new_attr; 716} 717 718 719Dwarf_P_Attribute 720dwarf_add_AT_producer(Dwarf_P_Die ownerdie, 721 char *producer_string, Dwarf_Error * error) 722{ 723 Dwarf_P_Attribute new_attr; 724 725 if (ownerdie == NULL) { 726 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 727 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 728 } 729 730 new_attr = (Dwarf_P_Attribute) 731 _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); 732 if (new_attr == NULL) { 733 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 734 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 735 } 736 737 new_attr->ar_attribute = DW_AT_producer; 738 new_attr->ar_attribute_form = DW_FORM_string; 739 new_attr->ar_nbytes = strlen(producer_string) + 1; 740 new_attr->ar_next = 0; 741 742 new_attr->ar_data = 743 (char *) _dwarf_p_get_alloc(NULL, strlen(producer_string) + 1); 744 if (new_attr->ar_data == NULL) { 745 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 746 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 747 } 748 749 strcpy(new_attr->ar_data, producer_string); 750 new_attr->ar_rel_type = R_MIPS_NONE; 751 new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 752 753 /* add attribute to the die */ 754 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 755 return new_attr; 756} 757 758 759Dwarf_P_Attribute 760dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, 761 Dwarf_Signed signed_value, 762 Dwarf_Error * error) 763{ 764 Dwarf_P_Attribute new_attr; 765 int leb_size; 766 char encode_buffer[ENCODE_SPACE_NEEDED]; 767 int res; 768 769 if (ownerdie == NULL) { 770 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 771 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 772 } 773 774 new_attr = (Dwarf_P_Attribute) 775 _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); 776 if (new_attr == NULL) { 777 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 778 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 779 } 780 781 new_attr->ar_attribute = DW_AT_const_value; 782 new_attr->ar_attribute_form = DW_FORM_sdata; 783 new_attr->ar_rel_type = R_MIPS_NONE; 784 new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 785 new_attr->ar_next = 0; 786 787 res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, 788 encode_buffer, 789 sizeof(encode_buffer)); 790 if (res != DW_DLV_OK) { 791 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 792 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 793 } 794 new_attr->ar_data = (char *) 795 _dwarf_p_get_alloc(NULL, leb_size); 796 if (new_attr->ar_data == NULL) { 797 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 798 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 799 } 800 memcpy(new_attr->ar_data, encode_buffer, leb_size); 801 new_attr->ar_nbytes = leb_size; 802 803 /* add attribute to the die */ 804 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 805 return new_attr; 806} 807 808 809Dwarf_P_Attribute 810dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, 811 Dwarf_Unsigned unsigned_value, 812 Dwarf_Error * error) 813{ 814 Dwarf_P_Attribute new_attr; 815 int leb_size; 816 char encode_buffer[ENCODE_SPACE_NEEDED]; 817 int res; 818 819 if (ownerdie == NULL) { 820 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 821 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 822 } 823 824 new_attr = (Dwarf_P_Attribute) 825 _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); 826 if (new_attr == NULL) { 827 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 828 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 829 } 830 831 new_attr->ar_attribute = DW_AT_const_value; 832 new_attr->ar_attribute_form = DW_FORM_udata; 833 new_attr->ar_rel_type = R_MIPS_NONE; 834 new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 835 new_attr->ar_next = 0; 836 837 res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, 838 encode_buffer, 839 sizeof(encode_buffer)); 840 if (res != DW_DLV_OK) { 841 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 842 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 843 } 844 new_attr->ar_data = (char *) 845 _dwarf_p_get_alloc(NULL, leb_size); 846 if (new_attr->ar_data == NULL) { 847 _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 848 return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 849 } 850 memcpy(new_attr->ar_data, encode_buffer, leb_size); 851 new_attr->ar_nbytes = leb_size; 852 853 /* add attribute to the die */ 854 _dwarf_pro_add_at_to_die(ownerdie, new_attr); 855 return new_attr; 856} 857