1 /* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and 2 EVAX (openVMS/Alpha) files. 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 4 Free Software Foundation, Inc. 5 6 Written by Klaus K"ampf (kkaempf@rmi.de) 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22 #if __STDC__ 23 #include <stdarg.h> 24 #endif 25 26 #include "bfd.h" 27 #include "sysdep.h" 28 #include "bfdlink.h" 29 #include "libbfd.h" 30 31 #include "vms.h" 32 33 #if VMS_DEBUG 34 /* Debug functions. */ 35 36 /* Debug function for all vms extensions 37 evaluates environment variable VMS_DEBUG for a 38 numerical value on the first call 39 all error levels below this value are printed 40 41 levels: 42 1 toplevel bfd calls (functions from the bfd vector) 43 2 functions called by bfd calls 44 ... 45 9 almost everything 46 47 level is also indentation level. Indentation is performed 48 if level > 0. */ 49 50 void 51 _bfd_vms_debug (int level, char *format, ...) 52 { 53 static int min_level = -1; 54 static FILE *output = NULL; 55 char *eptr; 56 va_list args; 57 int abslvl = (level > 0) ? level : - level; 58 59 if (min_level == -1) 60 { 61 if ((eptr = getenv ("VMS_DEBUG")) != NULL) 62 { 63 min_level = atoi (eptr); 64 output = stderr; 65 } 66 else 67 min_level = 0; 68 } 69 if (output == NULL) 70 return; 71 if (abslvl > min_level) 72 return; 73 74 while (--level>0) 75 fprintf (output, " "); 76 va_start (args, format); 77 vfprintf (output, format, args); 78 fflush (output); 79 va_end (args); 80 } 81 82 /* A debug function 83 hex dump 'size' bytes starting at 'ptr'. */ 84 85 void 86 _bfd_hexdump (int level, 87 unsigned char *ptr, 88 int size, 89 int offset) 90 { 91 unsigned char *lptr = ptr; 92 int count = 0; 93 long start = offset; 94 95 while (size-- > 0) 96 { 97 if ((count%16) == 0) 98 vms_debug (level, "%08lx:", start); 99 vms_debug (-level, " %02x", *ptr++); 100 count++; 101 start++; 102 if (size == 0) 103 { 104 while ((count%16) != 0) 105 { 106 vms_debug (-level, " "); 107 count++; 108 } 109 } 110 if ((count%16) == 0) 111 { 112 vms_debug (-level, " "); 113 while (lptr < ptr) 114 { 115 vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr); 116 lptr++; 117 } 118 vms_debug (-level, "\n"); 119 } 120 } 121 if ((count%16) != 0) 122 vms_debug (-level, "\n"); 123 } 124 #endif 125 126 /* Hash functions 127 128 These are needed when reading an object file. */ 129 130 /* Allocate new vms_hash_entry 131 keep the symbol name and a pointer to the bfd symbol in the table. */ 132 133 struct bfd_hash_entry * 134 _bfd_vms_hash_newfunc (struct bfd_hash_entry *entry, 135 struct bfd_hash_table *table, 136 const char *string) 137 { 138 vms_symbol_entry *ret; 139 140 #if VMS_DEBUG 141 vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string); 142 #endif 143 144 if (entry == NULL) 145 { 146 ret = (vms_symbol_entry *) 147 bfd_hash_allocate (table, sizeof (vms_symbol_entry)); 148 if (ret == NULL) 149 { 150 bfd_set_error (bfd_error_no_memory); 151 return NULL; 152 } 153 entry = (struct bfd_hash_entry *) ret; 154 } 155 156 /* Call the allocation method of the base class. */ 157 ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string); 158 #if VMS_DEBUG 159 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret); 160 #endif 161 162 ret->symbol = NULL; 163 164 return (struct bfd_hash_entry *)ret; 165 } 166 167 /* Object file input functions. */ 168 169 /* Return type and length from record header (buf) on Alpha. */ 170 171 void 172 _bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED, 173 unsigned char *buf, 174 int *type, 175 int *length) 176 { 177 if (type != 0) 178 *type = bfd_getl16 (buf); 179 buf += 2; 180 if (length != 0) 181 *length = bfd_getl16 (buf); 182 183 #if VMS_DEBUG 184 vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0)); 185 #endif 186 } 187 188 /* Get next record from object file to vms_buf. 189 Set PRIV(buf_size) and return it 190 191 This is a little tricky since it should be portable. 192 193 The openVMS object file has 'variable length' which means that 194 read() returns data in chunks of (hopefully) correct and expected 195 size. The linker (and other tools on vms) depend on that. Unix doesn't 196 know about 'formatted' files, so reading and writing such an object 197 file in a unix environment is not trivial. 198 199 With the tool 'file' (available on all vms ftp sites), one 200 can view and change the attributes of a file. Changing from 201 'variable length' to 'fixed length, 512 bytes' reveals the 202 record length at the first 2 bytes of every record. The same 203 happens during the transfer of object files from vms to unix, 204 at least with ucx, dec's implementation of tcp/ip. 205 206 The vms format repeats the length at bytes 2 & 3 of every record. 207 208 On the first call (file_format == FF_UNKNOWN) we check if 209 the first and the third byte pair (!) of the record match. 210 If they do it's an object file in an unix environment or with 211 wrong attributes (FF_FOREIGN), else we should be in a vms 212 environment where read() returns the record size (FF_NATIVE). 213 214 Reading is always done in 2 steps. 215 First just the record header is read and the length extracted 216 by get_header_values, 217 then the read buffer is adjusted and the remaining bytes are 218 read in. 219 220 All file i/o is always done on even file positions. */ 221 222 int 223 _bfd_vms_get_record (bfd * abfd) 224 { 225 int test_len, test_start, remaining; 226 unsigned char *vms_buf; 227 228 #if VMS_DEBUG 229 vms_debug (8, "_bfd_vms_get_record\n"); 230 #endif 231 232 /* Minimum is 6 bytes on Alpha 233 (2 bytes length, 2 bytes record id, 2 bytes length repeated) 234 235 On the VAX there's no length information in the record 236 so start with OBJ_S_C_MAXRECSIZ. */ 237 238 if (PRIV (buf_size) == 0) 239 { 240 bfd_size_type amt; 241 242 if (PRIV (is_vax)) 243 { 244 amt = OBJ_S_C_MAXRECSIZ; 245 PRIV (file_format) = FF_VAX; 246 } 247 else 248 amt = 6; 249 PRIV (vms_buf) = bfd_malloc (amt); 250 PRIV (buf_size) = amt; 251 } 252 253 vms_buf = PRIV (vms_buf); 254 255 if (vms_buf == 0) 256 return -1; 257 258 switch (PRIV (file_format)) 259 { 260 case FF_UNKNOWN: 261 case FF_FOREIGN: 262 test_len = 6; /* Probe 6 bytes. */ 263 test_start = 2; /* Where the record starts. */ 264 break; 265 266 case FF_NATIVE: 267 test_len = 4; 268 test_start = 0; 269 break; 270 271 default: 272 case FF_VAX: 273 test_len = 0; 274 test_start = 0; 275 break; 276 } 277 278 /* Skip odd alignment byte. */ 279 280 if (bfd_tell (abfd) & 1) 281 { 282 if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1) 283 { 284 bfd_set_error (bfd_error_file_truncated); 285 return 0; 286 } 287 } 288 289 /* Read the record header on Alpha. */ 290 if ((test_len != 0) 291 && (bfd_bread (PRIV (vms_buf), (bfd_size_type) test_len, abfd) 292 != (bfd_size_type) test_len)) 293 { 294 bfd_set_error (bfd_error_file_truncated); 295 return 0; 296 } 297 298 /* Check file format on first call. */ 299 if (PRIV (file_format) == FF_UNKNOWN) 300 { /* Record length repeats ? */ 301 if (vms_buf[0] == vms_buf[4] 302 && vms_buf[1] == vms_buf[5]) 303 { 304 PRIV (file_format) = FF_FOREIGN; /* Y: foreign environment. */ 305 test_start = 2; 306 } 307 else 308 { 309 PRIV (file_format) = FF_NATIVE; /* N: native environment. */ 310 test_start = 0; 311 } 312 } 313 314 if (PRIV (is_vax)) 315 { 316 PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size), 317 abfd); 318 if (PRIV (rec_length) <= 0) 319 { 320 bfd_set_error (bfd_error_file_truncated); 321 return 0; 322 } 323 PRIV (vms_rec) = vms_buf; 324 } 325 else 326 { 327 /* Alpha. */ 328 /* Extract vms record length. */ 329 330 _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL, 331 & PRIV (rec_length)); 332 333 if (PRIV (rec_length) <= 0) 334 { 335 bfd_set_error (bfd_error_file_truncated); 336 return 0; 337 } 338 339 /* That's what the linker manual says. */ 340 341 if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ) 342 { 343 bfd_set_error (bfd_error_file_truncated); 344 return 0; 345 } 346 347 /* Adjust the buffer. */ 348 349 if (PRIV (rec_length) > PRIV (buf_size)) 350 { 351 PRIV (vms_buf) = bfd_realloc (vms_buf, 352 (bfd_size_type) PRIV (rec_length)); 353 vms_buf = PRIV (vms_buf); 354 if (vms_buf == 0) 355 return -1; 356 PRIV (buf_size) = PRIV (rec_length); 357 } 358 359 /* Read the remaining record. */ 360 remaining = PRIV (rec_length) - test_len + test_start; 361 362 #if VMS_DEBUG 363 vms_debug (10, "bfd_bread remaining %d\n", remaining); 364 #endif 365 if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) != 366 (bfd_size_type) remaining) 367 { 368 bfd_set_error (bfd_error_file_truncated); 369 return 0; 370 } 371 PRIV (vms_rec) = vms_buf + test_start; 372 } 373 374 #if VMS_DEBUG 375 vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length)); 376 #endif 377 378 return PRIV (rec_length); 379 } 380 381 /* Get next vms record from file 382 update vms_rec and rec_length to new (remaining) values. */ 383 384 int 385 _bfd_vms_next_record (bfd * abfd) 386 { 387 #if VMS_DEBUG 388 vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n", 389 PRIV (rec_length), PRIV (rec_size)); 390 #endif 391 392 if (PRIV (rec_length) > 0) 393 PRIV (vms_rec) += PRIV (rec_size); 394 else 395 { 396 if (_bfd_vms_get_record (abfd) <= 0) 397 return -1; 398 } 399 400 if (!PRIV (vms_rec) || !PRIV (vms_buf) 401 || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size))) 402 return -1; 403 404 if (PRIV (is_vax)) 405 { 406 PRIV (rec_type) = *(PRIV (vms_rec)); 407 PRIV (rec_size) = PRIV (rec_length); 408 } 409 else 410 _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type), 411 &PRIV (rec_size)); 412 413 PRIV (rec_length) -= PRIV (rec_size); 414 415 #if VMS_DEBUG 416 vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n", 417 PRIV (vms_rec), PRIV (rec_size), PRIV (rec_length), 418 PRIV (rec_type)); 419 #endif 420 421 return PRIV (rec_type); 422 } 423 424 /* Copy sized string (string with fixed length) to new allocated area 425 size is string length (size of record) */ 426 427 char * 428 _bfd_vms_save_sized_string (unsigned char *str, int size) 429 { 430 char *newstr = bfd_malloc ((bfd_size_type) size + 1); 431 432 if (newstr == NULL) 433 return NULL; 434 strncpy (newstr, (char *) str, (size_t) size); 435 newstr[size] = 0; 436 437 return newstr; 438 } 439 440 /* Copy counted string (string with length at first byte) to new allocated area 441 ptr points to length byte on entry */ 442 443 char * 444 _bfd_vms_save_counted_string (unsigned char *ptr) 445 { 446 int len = *ptr++; 447 448 return _bfd_vms_save_sized_string (ptr, len); 449 } 450 451 /* Stack routines for vms ETIR commands. */ 452 453 /* Push value and section index. */ 454 455 void 456 _bfd_vms_push (bfd * abfd, uquad val, int psect) 457 { 458 static int last_psect; 459 460 #if VMS_DEBUG 461 vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr)); 462 #endif 463 464 if (psect >= 0) 465 last_psect = psect; 466 467 PRIV (stack[PRIV (stackptr)]).value = val; 468 PRIV (stack[PRIV (stackptr)]).psect = last_psect; 469 PRIV (stackptr)++; 470 if (PRIV (stackptr) >= STACKSIZE) 471 { 472 bfd_set_error (bfd_error_bad_value); 473 (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); 474 exit (1); 475 } 476 } 477 478 /* Pop value and section index. */ 479 480 uquad 481 _bfd_vms_pop (bfd * abfd, int *psect) 482 { 483 uquad value; 484 485 if (PRIV (stackptr) == 0) 486 { 487 bfd_set_error (bfd_error_bad_value); 488 (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop")); 489 exit (1); 490 } 491 PRIV (stackptr)--; 492 value = PRIV (stack[PRIV (stackptr)]).value; 493 if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0)) 494 *psect = PRIV (stack[PRIV (stackptr)]).psect; 495 496 #if VMS_DEBUG 497 vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect); 498 #endif 499 500 return value; 501 } 502 503 /* Object file output functions. */ 504 505 /* GAS tends to write sections in little chunks (bfd_set_section_contents) 506 which we can't use directly. So we save the little chunks in linked 507 lists (one per section) and write them later. */ 508 509 /* Add a new vms_section structure to vms_section_table 510 - forward chaining -. */ 511 512 static vms_section * 513 add_new_contents (bfd * abfd, sec_ptr section) 514 { 515 vms_section *sptr, *newptr; 516 517 sptr = PRIV (vms_section_table)[section->index]; 518 if (sptr != NULL) 519 return sptr; 520 521 newptr = bfd_alloc (abfd, (bfd_size_type) sizeof (vms_section)); 522 if (newptr == NULL) 523 return NULL; 524 newptr->contents = bfd_alloc (abfd, section->size); 525 if (newptr->contents == NULL) 526 return NULL; 527 newptr->offset = 0; 528 newptr->size = section->size; 529 newptr->next = 0; 530 PRIV (vms_section_table)[section->index] = newptr; 531 return newptr; 532 } 533 534 /* Save section data & offset to a vms_section structure 535 vms_section_table[] holds the vms_section chain. */ 536 537 bfd_boolean 538 _bfd_save_vms_section (bfd * abfd, 539 sec_ptr section, 540 const void * data, 541 file_ptr offset, 542 bfd_size_type count) 543 { 544 vms_section *sptr; 545 546 if (section->index >= VMS_SECTION_COUNT) 547 { 548 bfd_set_error (bfd_error_nonrepresentable_section); 549 return FALSE; 550 } 551 if (count == (bfd_size_type)0) 552 return TRUE; 553 sptr = add_new_contents (abfd, section); 554 if (sptr == NULL) 555 return FALSE; 556 memcpy (sptr->contents + offset, data, (size_t) count); 557 558 return TRUE; 559 } 560 561 /* Get vms_section pointer to saved contents for section # index */ 562 563 vms_section * 564 _bfd_get_vms_section (bfd * abfd, int index) 565 { 566 if (index >= VMS_SECTION_COUNT) 567 { 568 bfd_set_error (bfd_error_nonrepresentable_section); 569 return NULL; 570 } 571 return PRIV (vms_section_table)[index]; 572 } 573 574 /* Object output routines. */ 575 576 /* Begin new record or record header 577 write 2 bytes rectype 578 write 2 bytes record length (filled in at flush) 579 write 2 bytes header type (ommitted if rechead == -1). */ 580 581 void 582 _bfd_vms_output_begin (bfd * abfd, int rectype, int rechead) 583 { 584 #if VMS_DEBUG 585 vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype, 586 rechead); 587 #endif 588 589 _bfd_vms_output_short (abfd, (unsigned int) rectype); 590 591 /* Save current output position to fill in length later. */ 592 593 if (PRIV (push_level) > 0) 594 PRIV (length_pos) = PRIV (output_size); 595 596 #if VMS_DEBUG 597 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n", 598 PRIV (length_pos)); 599 #endif 600 601 /* Placeholder for length. */ 602 _bfd_vms_output_short (abfd, 0); 603 604 if (rechead != -1) 605 _bfd_vms_output_short (abfd, (unsigned int) rechead); 606 } 607 608 /* Set record/subrecord alignment. */ 609 610 void 611 _bfd_vms_output_alignment (bfd * abfd, int alignto) 612 { 613 #if VMS_DEBUG 614 vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto); 615 #endif 616 617 PRIV (output_alignment) = alignto; 618 } 619 620 /* Prepare for subrecord fields. */ 621 622 void 623 _bfd_vms_output_push (bfd * abfd) 624 { 625 #if VMS_DEBUG 626 vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size)); 627 #endif 628 629 PRIV (push_level)++; 630 PRIV (pushed_size) = PRIV (output_size); 631 } 632 633 /* End of subrecord fields. */ 634 635 void 636 _bfd_vms_output_pop (bfd * abfd) 637 { 638 #if VMS_DEBUG 639 vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size)); 640 #endif 641 642 _bfd_vms_output_flush (abfd); 643 PRIV (length_pos) = 2; 644 645 #if VMS_DEBUG 646 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos)); 647 #endif 648 649 PRIV (pushed_size) = 0; 650 PRIV (push_level)--; 651 } 652 653 /* Flush unwritten output, ends current record. */ 654 655 void 656 _bfd_vms_output_flush (bfd * abfd) 657 { 658 int real_size = PRIV (output_size); 659 int aligncount; 660 int length; 661 662 #if VMS_DEBUG 663 vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n", 664 real_size, PRIV (pushed_size), PRIV (length_pos)); 665 #endif 666 667 if (PRIV (push_level) > 0) 668 length = real_size - PRIV (pushed_size); 669 else 670 length = real_size; 671 672 if (length == 0) 673 return; 674 aligncount = (PRIV (output_alignment) 675 - (length % PRIV (output_alignment))) % PRIV (output_alignment); 676 677 #if VMS_DEBUG 678 vms_debug (6, "align: adding %d bytes\n", aligncount); 679 #endif 680 681 while (aligncount-- > 0) 682 { 683 PRIV (output_buf)[real_size++] = 0; 684 length++; 685 } 686 687 /* Put length to buffer. */ 688 PRIV (output_size) = PRIV (length_pos); 689 _bfd_vms_output_short (abfd, (unsigned int) length); 690 691 if (PRIV (push_level) == 0) 692 { 693 #ifndef VMS 694 /* Write length first, see FF_FOREIGN in the input routines. */ 695 fwrite (PRIV (output_buf) + 2, 2, 1, (FILE *) abfd->iostream); 696 #endif 697 fwrite (PRIV (output_buf), (size_t) real_size, 1, 698 (FILE *) abfd->iostream); 699 700 PRIV (output_size) = 0; 701 } 702 else 703 { 704 PRIV (output_size) = real_size; 705 PRIV (pushed_size) = PRIV (output_size); 706 } 707 } 708 709 /* End record output. */ 710 711 void 712 _bfd_vms_output_end (bfd * abfd) 713 { 714 #if VMS_DEBUG 715 vms_debug (6, "_bfd_vms_output_end\n"); 716 #endif 717 718 _bfd_vms_output_flush (abfd); 719 } 720 721 /* Check remaining buffer size 722 723 Return what's left. */ 724 725 int 726 _bfd_vms_output_check (bfd * abfd, int size) 727 { 728 #if VMS_DEBUG 729 vms_debug (6, "_bfd_vms_output_check (%d)\n", size); 730 #endif 731 732 return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT)); 733 } 734 735 /* Output byte (8 bit) value. */ 736 737 void 738 _bfd_vms_output_byte (bfd * abfd, unsigned int value) 739 { 740 #if VMS_DEBUG 741 vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value); 742 #endif 743 744 bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size)); 745 PRIV (output_size) += 1; 746 } 747 748 /* Output short (16 bit) value. */ 749 750 void 751 _bfd_vms_output_short (bfd * abfd, unsigned int value) 752 { 753 #if VMS_DEBUG 754 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value); 755 #endif 756 757 bfd_put_16 (abfd, (bfd_vma) value & 0xffff, 758 PRIV (output_buf) + PRIV (output_size)); 759 PRIV (output_size) += 2; 760 } 761 762 /* Output long (32 bit) value. */ 763 764 void 765 _bfd_vms_output_long (bfd * abfd, unsigned long value) 766 { 767 #if VMS_DEBUG 768 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value); 769 #endif 770 771 bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size)); 772 PRIV (output_size) += 4; 773 } 774 775 /* Output quad (64 bit) value. */ 776 777 void 778 _bfd_vms_output_quad (bfd * abfd, uquad value) 779 { 780 #if VMS_DEBUG 781 vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value); 782 #endif 783 784 bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size)); 785 PRIV (output_size) += 8; 786 } 787 788 /* Output c-string as counted string. */ 789 790 void 791 _bfd_vms_output_counted (bfd * abfd, char *value) 792 { 793 int len; 794 795 #if VMS_DEBUG 796 vms_debug (6, "_bfd_vms_output_counted (%s)\n", value); 797 #endif 798 799 len = strlen (value); 800 if (len == 0) 801 { 802 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes")); 803 return; 804 } 805 if (len > 255) 806 { 807 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes")); 808 return; 809 } 810 _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff); 811 _bfd_vms_output_dump (abfd, (unsigned char *) value, len); 812 } 813 814 /* Output character area. */ 815 816 void 817 _bfd_vms_output_dump (bfd * abfd, 818 unsigned char *data, 819 int length) 820 { 821 #if VMS_DEBUG 822 vms_debug (6, "_bfd_vms_output_dump (%d)\n", length); 823 #endif 824 825 if (length == 0) 826 return; 827 828 memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length); 829 PRIV (output_size) += length; 830 } 831 832 /* Output count bytes of value. */ 833 834 void 835 _bfd_vms_output_fill (bfd * abfd, 836 int value, 837 int count) 838 { 839 #if VMS_DEBUG 840 vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count); 841 #endif 842 843 if (count == 0) 844 return; 845 memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count); 846 PRIV (output_size) += count; 847 } 848 849 /* This hash routine borrowed from GNU-EMACS, and strengthened slightly. ERY. */ 850 851 static int 852 hash_string (const char *ptr) 853 { 854 const unsigned char *p = (unsigned char *) ptr; 855 const unsigned char *end = p + strlen (ptr); 856 unsigned char c; 857 int hash = 0; 858 859 while (p != end) 860 { 861 c = *p++; 862 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c); 863 } 864 return hash; 865 } 866 867 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */ 868 869 char * 870 _bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen) 871 { 872 long int result; 873 int in_len; 874 char *new_name; 875 const char *old_name; 876 int i; 877 static char outbuf[EOBJ_S_C_SYMSIZ+1]; 878 char *out = outbuf; 879 880 #if VMS_DEBUG 881 vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in); 882 #endif 883 884 if (maxlen > EOBJ_S_C_SYMSIZ) 885 maxlen = EOBJ_S_C_SYMSIZ; 886 887 /* Save this for later. */ 888 new_name = out; 889 890 /* We may need to truncate the symbol, save the hash for later. */ 891 in_len = strlen (in); 892 893 result = (in_len > maxlen) ? hash_string (in) : 0; 894 895 old_name = in; 896 897 /* Do the length checking. */ 898 if (in_len <= maxlen) 899 i = in_len; 900 else 901 { 902 if (PRIV (flag_hash_long_names)) 903 i = maxlen-9; 904 else 905 i = maxlen; 906 } 907 908 strncpy (out, in, (size_t) i); 909 in += i; 910 out += i; 911 912 if ((in_len > maxlen) 913 && PRIV (flag_hash_long_names)) 914 sprintf (out, "_%08lx", result); 915 else 916 *out = 0; 917 918 #if VMS_DEBUG 919 vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf); 920 #endif 921 922 if (in_len > maxlen 923 && PRIV (flag_hash_long_names) 924 && PRIV (flag_show_after_trunc)) 925 printf (_("Symbol %s replaced by %s\n"), old_name, new_name); 926 927 return outbuf; 928 } 929 930 /* Allocate and initialize a new symbol. */ 931 932 static asymbol * 933 new_symbol (bfd * abfd, char *name) 934 { 935 asymbol *symbol; 936 937 #if VMS_DEBUG 938 _bfd_vms_debug (7, "new_symbol %s\n", name); 939 #endif 940 941 symbol = bfd_make_empty_symbol (abfd); 942 if (symbol == 0) 943 return symbol; 944 symbol->name = name; 945 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); 946 947 return symbol; 948 } 949 950 /* Allocate and enter a new private symbol. */ 951 952 vms_symbol_entry * 953 _bfd_vms_enter_symbol (bfd * abfd, char *name) 954 { 955 vms_symbol_entry *entry; 956 957 #if VMS_DEBUG 958 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name); 959 #endif 960 961 entry = (vms_symbol_entry *) 962 bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE); 963 if (entry == 0) 964 { 965 #if VMS_DEBUG 966 _bfd_vms_debug (8, "creating hash entry for %s\n", name); 967 #endif 968 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), 969 name, TRUE, FALSE); 970 if (entry != 0) 971 { 972 asymbol *symbol; 973 symbol = new_symbol (abfd, name); 974 if (symbol != 0) 975 { 976 entry->symbol = symbol; 977 PRIV (gsd_sym_count)++; 978 abfd->symcount++; 979 } 980 else 981 entry = 0; 982 } 983 else 984 (*_bfd_error_handler) (_("failed to enter %s"), name); 985 } 986 else 987 { 988 #if VMS_DEBUG 989 _bfd_vms_debug (8, "found hash entry for %s\n", name); 990 #endif 991 } 992 993 #if VMS_DEBUG 994 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol); 995 #endif 996 return entry; 997 } 998