00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #if __STDC__
00027 #include <stdarg.h>
00028 #endif
00029
00030 #include "bfd.h"
00031 #include "sysdep.h"
00032 #include "bfdlink.h"
00033 #include "libbfd.h"
00034
00035 #include "vms.h"
00036
00037 static vms_section *add_new_contents PARAMS ((bfd *, sec_ptr));
00038 static int hash_string PARAMS ((const char *));
00039 static asymbol *new_symbol PARAMS ((bfd *, char *));
00040
00041
00042 #if VMS_DEBUG
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #if __STDC__
00061 void
00062 _bfd_vms_debug (int level, char *format, ...)
00063 {
00064 static int min_level = -1;
00065 static FILE *output = NULL;
00066 char *eptr;
00067 va_list args;
00068 int abslvl = (level > 0)?level:-level;
00069
00070 if (min_level == -1)
00071 {
00072 if ((eptr = getenv("VMS_DEBUG")) != NULL)
00073 {
00074 min_level = atoi(eptr);
00075 output = stderr;
00076 }
00077 else
00078 min_level = 0;
00079 }
00080 if (output == NULL)
00081 return;
00082 if (abslvl > min_level)
00083 return;
00084
00085 while (--level>0)
00086 fprintf (output, " ");
00087 va_start(args, format);
00088 vfprintf (output, format, args);
00089 fflush(output);
00090 va_end(args);
00091
00092 return;
00093 }
00094
00095 #else
00096
00097 void
00098 _bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6)
00099 int level;
00100 char *format;
00101 long a1; long a2; long a3;
00102 long a4; long a5; long a6;
00103 {
00104 static int min_level = -1;
00105 static FILE *output = NULL;
00106 char *eptr;
00107
00108 if (min_level == -1)
00109 {
00110 if ((eptr = getenv("VMS_DEBUG")) != NULL)
00111 {
00112 min_level = atoi(eptr);
00113 output = stderr;
00114 }
00115 else
00116 min_level = 0;
00117 }
00118 if (output == NULL)
00119 return;
00120 if (level > min_level)
00121 return;
00122
00123 while (--level>0)
00124 fprintf (output, " ");
00125 fprintf (output, format, a1, a2, a3, a4, a5, a6);
00126 fflush(output);
00127
00128 return;
00129 }
00130 #endif
00131
00132
00133
00134
00135 void
00136 _bfd_hexdump (level, ptr, size, offset)
00137 int level;
00138 unsigned char *ptr;
00139 int size;
00140 int offset;
00141 {
00142 unsigned char *lptr = ptr;
00143 int count = 0;
00144 long start = offset;
00145
00146 while (size-- > 0)
00147 {
00148 if ((count%16) == 0)
00149 vms_debug (level, "%08lx:", start);
00150 vms_debug (-level, " %02x", *ptr++);
00151 count++;
00152 start++;
00153 if (size == 0)
00154 {
00155 while ((count%16) != 0)
00156 {
00157 vms_debug (-level, " ");
00158 count++;
00159 }
00160 }
00161 if ((count%16) == 0)
00162 {
00163 vms_debug (-level, " ");
00164 while (lptr < ptr)
00165 {
00166 vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
00167 lptr++;
00168 }
00169 vms_debug (-level, "\n");
00170 }
00171 }
00172 if ((count%16) != 0)
00173 vms_debug (-level, "\n");
00174
00175 return;
00176 }
00177 #endif
00178
00179
00180
00181
00182
00183
00184
00185
00186 struct bfd_hash_entry *
00187 _bfd_vms_hash_newfunc (entry, table, string)
00188 struct bfd_hash_entry *entry;
00189 struct bfd_hash_table *table;
00190 const char *string;
00191 {
00192 vms_symbol_entry *ret;
00193
00194 #if VMS_DEBUG
00195 vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry, table, string);
00196 #endif
00197
00198 if (entry == (struct bfd_hash_entry *)NULL)
00199 {
00200 ret = (vms_symbol_entry *)
00201 bfd_hash_allocate (table, sizeof (vms_symbol_entry));
00202 if (ret == (vms_symbol_entry *) NULL)
00203 {
00204 bfd_set_error (bfd_error_no_memory);
00205 return (struct bfd_hash_entry *)NULL;
00206 }
00207 entry = (struct bfd_hash_entry *) ret;
00208 }
00209
00210
00211
00212 ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string);
00213 #if VMS_DEBUG
00214 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
00215 #endif
00216
00217 ret->symbol = (asymbol *)NULL;
00218
00219 return (struct bfd_hash_entry *)ret;
00220 }
00221
00222
00223
00224
00225
00226 void
00227 _bfd_vms_get_header_values (abfd, buf, type, length)
00228 bfd *abfd ATTRIBUTE_UNUSED;
00229 unsigned char *buf;
00230 int *type;
00231 int *length;
00232 {
00233 if (type != 0)
00234 *type = bfd_getl16 (buf);
00235 buf += 2;
00236 if (length != 0)
00237 *length = bfd_getl16 (buf);
00238
00239 #if VMS_DEBUG
00240 vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
00241 #endif
00242
00243 return;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 int
00281 _bfd_vms_get_record (abfd)
00282 bfd *abfd;
00283 {
00284 int test_len, test_start, remaining;
00285 unsigned char *vms_buf;
00286
00287 #if VMS_DEBUG
00288 vms_debug (8, "_bfd_vms_get_record\n");
00289 #endif
00290
00291
00292
00293
00294
00295
00296
00297 if (PRIV (buf_size) == 0)
00298 {
00299 bfd_size_type amt;
00300
00301 if (PRIV (is_vax))
00302 {
00303 amt = OBJ_S_C_MAXRECSIZ;
00304 PRIV (file_format) = FF_VAX;
00305 }
00306 else
00307 amt = 6;
00308 PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
00309 PRIV (buf_size) = amt;
00310 }
00311
00312 vms_buf = PRIV (vms_buf);
00313
00314 if (vms_buf == 0)
00315 return -1;
00316
00317 switch (PRIV (file_format))
00318 {
00319 case FF_UNKNOWN:
00320 case FF_FOREIGN:
00321 test_len = 6;
00322 test_start = 2;
00323 break;
00324
00325 case FF_NATIVE:
00326 test_len = 4;
00327 test_start = 0;
00328 break;
00329
00330 default:
00331 case FF_VAX:
00332 test_len = 0;
00333 test_start = 0;
00334 break;
00335 }
00336
00337
00338
00339 if (bfd_tell (abfd) & 1)
00340 {
00341 if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1)
00342 {
00343 bfd_set_error (bfd_error_file_truncated);
00344 return 0;
00345 }
00346 }
00347
00348
00349
00350 if ((test_len != 0)
00351 && (bfd_bread (PRIV (vms_buf), (bfd_size_type) test_len, abfd)
00352 != (bfd_size_type) test_len))
00353 {
00354 bfd_set_error (bfd_error_file_truncated);
00355 return 0;
00356 }
00357
00358
00359
00360 if (PRIV (file_format) == FF_UNKNOWN)
00361 {
00362 if (vms_buf[0] == vms_buf[4]
00363 && vms_buf[1] == vms_buf[5])
00364 {
00365 PRIV (file_format) = FF_FOREIGN;
00366 test_start = 2;
00367 }
00368 else
00369 {
00370 PRIV (file_format) = FF_NATIVE;
00371 test_start = 0;
00372 }
00373 }
00374
00375 if (PRIV (is_vax))
00376 {
00377 PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
00378 abfd);
00379 if (PRIV (rec_length) <= 0)
00380 {
00381 bfd_set_error (bfd_error_file_truncated);
00382 return 0;
00383 }
00384 PRIV (vms_rec) = vms_buf;
00385 }
00386 else
00387 {
00388
00389
00390 _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL,
00391 &PRIV (rec_length));
00392
00393 if (PRIV (rec_length) <= 0)
00394 {
00395 bfd_set_error (bfd_error_file_truncated);
00396 return 0;
00397 }
00398
00399
00400
00401 if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
00402 {
00403 bfd_set_error (bfd_error_file_truncated);
00404 return 0;
00405 }
00406
00407
00408
00409 if (PRIV (rec_length) > PRIV (buf_size))
00410 {
00411 PRIV (vms_buf) = ((unsigned char *)
00412 bfd_realloc (vms_buf,
00413 (bfd_size_type) PRIV (rec_length)));
00414 vms_buf = PRIV (vms_buf);
00415 if (vms_buf == 0)
00416 return -1;
00417 PRIV (buf_size) = PRIV (rec_length);
00418 }
00419
00420
00421
00422 remaining = PRIV (rec_length) - test_len + test_start;
00423
00424 #if VMS_DEBUG
00425 vms_debug (10, "bfd_bread remaining %d\n", remaining);
00426 #endif
00427 if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) !=
00428 (bfd_size_type) remaining)
00429 {
00430 bfd_set_error (bfd_error_file_truncated);
00431 return 0;
00432 }
00433 PRIV (vms_rec) = vms_buf + test_start;
00434 }
00435
00436 #if VMS_DEBUG
00437 vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length));
00438 #endif
00439
00440 return PRIV (rec_length);
00441 }
00442
00443
00444
00445
00446 int
00447 _bfd_vms_next_record (abfd)
00448 bfd *abfd;
00449 {
00450 #if VMS_DEBUG
00451 vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
00452 PRIV (rec_length), PRIV (rec_size));
00453 #endif
00454
00455 if (PRIV (rec_length) > 0)
00456 {
00457 PRIV (vms_rec) += PRIV (rec_size);
00458 }
00459 else
00460 {
00461 if (_bfd_vms_get_record (abfd) <= 0)
00462 return -1;
00463 }
00464
00465 if (!PRIV (vms_rec) || !PRIV (vms_buf)
00466 || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
00467 return -1;
00468
00469 if (PRIV (is_vax))
00470 {
00471 PRIV (rec_type) = *(PRIV (vms_rec));
00472 PRIV (rec_size) = PRIV (rec_length);
00473 }
00474 else
00475 {
00476 _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
00477 &PRIV (rec_size));
00478 }
00479 PRIV (rec_length) -= PRIV (rec_size);
00480
00481 #if VMS_DEBUG
00482 vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
00483 PRIV (vms_rec), PRIV (rec_size), PRIV (rec_length),
00484 PRIV (rec_type));
00485 #endif
00486
00487 return PRIV (rec_type);
00488 }
00489
00490
00491
00492
00493 char *
00494 _bfd_vms_save_sized_string (str, size)
00495 unsigned char *str;
00496 int size;
00497 {
00498 char *newstr = bfd_malloc ((bfd_size_type) size + 1);
00499
00500 if (newstr == NULL)
00501 return 0;
00502 strncpy (newstr, (char *) str, (size_t) size);
00503 newstr[size] = 0;
00504
00505 return newstr;
00506 }
00507
00508
00509
00510
00511 char *
00512 _bfd_vms_save_counted_string (ptr)
00513 unsigned char *ptr;
00514 {
00515 int len = *ptr++;
00516
00517 return _bfd_vms_save_sized_string (ptr, len);
00518 }
00519
00520
00521
00522
00523
00524 void
00525 _bfd_vms_push (abfd, val, psect)
00526 bfd *abfd;
00527 uquad val;
00528 int psect;
00529 {
00530 static int last_psect;
00531
00532 #if VMS_DEBUG
00533 vms_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV (stackptr));
00534 #endif
00535
00536 if (psect >= 0)
00537 last_psect = psect;
00538
00539 PRIV (stack[PRIV (stackptr)]).value = val;
00540 PRIV (stack[PRIV (stackptr)]).psect = last_psect;
00541 PRIV (stackptr)++;
00542 if (PRIV (stackptr) >= STACKSIZE)
00543 {
00544 bfd_set_error (bfd_error_bad_value);
00545 (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
00546 exit (1);
00547 }
00548 return;
00549 }
00550
00551
00552
00553 uquad
00554 _bfd_vms_pop (abfd, psect)
00555 bfd *abfd;
00556 int *psect;
00557 {
00558 uquad value;
00559
00560 if (PRIV (stackptr) == 0)
00561 {
00562 bfd_set_error (bfd_error_bad_value);
00563 (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
00564 exit (1);
00565 }
00566 PRIV (stackptr)--;
00567 value = PRIV (stack[PRIV (stackptr)]).value;
00568 if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
00569 *psect = PRIV (stack[PRIV (stackptr)]).psect;
00570
00571 #if VMS_DEBUG
00572 vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
00573 #endif
00574
00575 return value;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 static vms_section *
00588 add_new_contents (abfd, section)
00589 bfd *abfd;
00590 sec_ptr section;
00591 {
00592 vms_section *sptr, *newptr;
00593
00594 sptr = PRIV (vms_section_table)[section->index];
00595 if (sptr != NULL)
00596 return sptr;
00597
00598 newptr = (vms_section *) bfd_alloc (abfd,
00599 (bfd_size_type) sizeof (vms_section));
00600 if (newptr == (vms_section *) NULL)
00601 return NULL;
00602 newptr->contents = (unsigned char *) bfd_alloc (abfd, section->size);
00603 if (newptr->contents == (unsigned char *) NULL)
00604 return NULL;
00605 newptr->offset = 0;
00606 newptr->size = section->size;
00607 newptr->next = 0;
00608 PRIV (vms_section_table)[section->index] = newptr;
00609 return newptr;
00610 }
00611
00612
00613
00614
00615 bfd_boolean
00616 _bfd_save_vms_section (abfd, section, data, offset, count)
00617 bfd *abfd;
00618 sec_ptr section;
00619 const PTR data;
00620 file_ptr offset;
00621 bfd_size_type count;
00622 {
00623 vms_section *sptr;
00624
00625 if (section->index >= VMS_SECTION_COUNT)
00626 {
00627 bfd_set_error (bfd_error_nonrepresentable_section);
00628 return FALSE;
00629 }
00630 if (count == (bfd_size_type)0)
00631 return TRUE;
00632 sptr = add_new_contents (abfd, section);
00633 if (sptr == NULL)
00634 return FALSE;
00635 memcpy (sptr->contents + offset, data, (size_t) count);
00636
00637 return TRUE;
00638 }
00639
00640
00641
00642 vms_section *
00643 _bfd_get_vms_section (abfd, index)
00644 bfd *abfd;
00645 int index;
00646 {
00647 if (index >= VMS_SECTION_COUNT)
00648 {
00649 bfd_set_error (bfd_error_nonrepresentable_section);
00650 return NULL;
00651 }
00652 return PRIV (vms_section_table)[index];
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662 void
00663 _bfd_vms_output_begin (abfd, rectype, rechead)
00664 bfd *abfd;
00665 int rectype;
00666 int rechead;
00667 {
00668 #if VMS_DEBUG
00669 vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype,
00670 rechead);
00671 #endif
00672
00673 _bfd_vms_output_short (abfd, (unsigned int) rectype);
00674
00675
00676
00677 if (PRIV (push_level) > 0)
00678 PRIV (length_pos) = PRIV (output_size);
00679
00680 #if VMS_DEBUG
00681 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
00682 PRIV (length_pos));
00683 #endif
00684
00685 _bfd_vms_output_short (abfd, 0);
00686
00687 if (rechead != -1)
00688 _bfd_vms_output_short (abfd, (unsigned int) rechead);
00689
00690 return;
00691 }
00692
00693
00694
00695 void
00696 _bfd_vms_output_alignment (abfd, alignto)
00697 bfd *abfd;
00698 int alignto;
00699 {
00700 #if VMS_DEBUG
00701 vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto);
00702 #endif
00703
00704 PRIV (output_alignment) = alignto;
00705 return;
00706 }
00707
00708
00709
00710 void
00711 _bfd_vms_output_push (abfd)
00712 bfd *abfd;
00713 {
00714 #if VMS_DEBUG
00715 vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV (output_size));
00716 #endif
00717
00718 PRIV (push_level)++;
00719 PRIV (pushed_size) = PRIV (output_size);
00720 return;
00721 }
00722
00723
00724
00725 void
00726 _bfd_vms_output_pop (abfd)
00727 bfd *abfd;
00728 {
00729 #if VMS_DEBUG
00730 vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV (pushed_size));
00731 #endif
00732
00733 _bfd_vms_output_flush (abfd);
00734 PRIV (length_pos) = 2;
00735
00736 #if VMS_DEBUG
00737 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
00738 #endif
00739
00740 PRIV (pushed_size) = 0;
00741 PRIV (push_level)--;
00742 return;
00743 }
00744
00745
00746
00747 void
00748 _bfd_vms_output_flush (abfd)
00749 bfd *abfd;
00750 {
00751 int real_size = PRIV (output_size);
00752 int aligncount;
00753 int length;
00754
00755 #if VMS_DEBUG
00756 vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
00757 real_size, PRIV (pushed_size), PRIV (length_pos));
00758 #endif
00759
00760 if (PRIV (push_level) > 0)
00761 length = real_size - PRIV (pushed_size);
00762 else
00763 length = real_size;
00764
00765 if (length == 0)
00766 return;
00767 aligncount = (PRIV (output_alignment)
00768 - (length % PRIV (output_alignment))) % PRIV (output_alignment);
00769
00770 #if VMS_DEBUG
00771 vms_debug (6, "align: adding %d bytes\n", aligncount);
00772 #endif
00773
00774 while (aligncount-- > 0)
00775 {
00776 PRIV (output_buf)[real_size++] = 0;
00777 length++;
00778 }
00779
00780
00781 PRIV (output_size) = PRIV (length_pos);
00782 _bfd_vms_output_short (abfd, (unsigned int) length);
00783
00784 if (PRIV (push_level) == 0)
00785 {
00786 #ifndef VMS
00787
00788 fwrite (PRIV (output_buf) + 2, 2, 1, (FILE *) abfd->iostream);
00789 #endif
00790 fwrite (PRIV (output_buf), (size_t) real_size, 1,
00791 (FILE *) abfd->iostream);
00792
00793 PRIV (output_size) = 0;
00794 }
00795 else
00796 {
00797 PRIV (output_size) = real_size;
00798 PRIV (pushed_size) = PRIV (output_size);
00799 }
00800
00801 return;
00802 }
00803
00804
00805
00806 void
00807 _bfd_vms_output_end (abfd)
00808 bfd *abfd;
00809 {
00810 #if VMS_DEBUG
00811 vms_debug (6, "_bfd_vms_output_end\n");
00812 #endif
00813
00814 _bfd_vms_output_flush (abfd);
00815
00816 return;
00817 }
00818
00819
00820
00821
00822
00823 int
00824 _bfd_vms_output_check (abfd, size)
00825 bfd *abfd;
00826 int size;
00827 {
00828 #if VMS_DEBUG
00829 vms_debug (6, "_bfd_vms_output_check(%d)\n", size);
00830 #endif
00831
00832 return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
00833 }
00834
00835
00836
00837 void
00838 _bfd_vms_output_byte (abfd, value)
00839 bfd *abfd;
00840 unsigned int value;
00841 {
00842 #if VMS_DEBUG
00843 vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value);
00844 #endif
00845
00846 bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
00847 PRIV (output_size) += 1;
00848 return;
00849 }
00850
00851
00852
00853 void
00854 _bfd_vms_output_short (abfd, value)
00855 bfd *abfd;
00856 unsigned int value;
00857 {
00858 #if VMS_DEBUG
00859 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
00860 #endif
00861
00862 bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
00863 PRIV (output_buf) + PRIV (output_size));
00864 PRIV (output_size) += 2;
00865 return;
00866 }
00867
00868
00869
00870 void
00871 _bfd_vms_output_long (abfd, value)
00872 bfd *abfd;
00873 unsigned long value;
00874 {
00875 #if VMS_DEBUG
00876 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
00877 #endif
00878
00879 bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
00880 PRIV (output_size) += 4;
00881 return;
00882 }
00883
00884
00885
00886 void
00887 _bfd_vms_output_quad (abfd, value)
00888 bfd *abfd;
00889 uquad value;
00890 {
00891 #if VMS_DEBUG
00892 vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value);
00893 #endif
00894
00895 bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
00896 PRIV (output_size) += 8;
00897 return;
00898 }
00899
00900
00901
00902 void
00903 _bfd_vms_output_counted (abfd, value)
00904 bfd *abfd;
00905 char *value;
00906 {
00907 int len;
00908
00909 #if VMS_DEBUG
00910 vms_debug (6, "_bfd_vms_output_counted(%s)\n", value);
00911 #endif
00912
00913 len = strlen (value);
00914 if (len == 0)
00915 {
00916 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
00917 return;
00918 }
00919 if (len > 255)
00920 {
00921 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
00922 return;
00923 }
00924 _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
00925 _bfd_vms_output_dump (abfd, (unsigned char *)value, len);
00926 }
00927
00928
00929
00930 void
00931 _bfd_vms_output_dump (abfd, data, length)
00932 bfd *abfd;
00933 unsigned char *data;
00934 int length;
00935 {
00936 #if VMS_DEBUG
00937 vms_debug (6, "_bfd_vms_output_dump(%d)\n", length);
00938 #endif
00939
00940 if (length == 0)
00941 return;
00942
00943 memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
00944 PRIV (output_size) += length;
00945
00946 return;
00947 }
00948
00949
00950
00951 void
00952 _bfd_vms_output_fill (abfd, value, count)
00953 bfd *abfd;
00954 int value;
00955 int count;
00956 {
00957 #if VMS_DEBUG
00958 vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count);
00959 #endif
00960
00961 if (count == 0)
00962 return;
00963 memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
00964 PRIV (output_size) += count;
00965
00966 return;
00967 }
00968
00969
00970
00971 static int
00972 hash_string (ptr)
00973 const char *ptr;
00974 {
00975 register const unsigned char *p = (unsigned char *) ptr;
00976 register const unsigned char *end = p + strlen (ptr);
00977 register unsigned char c;
00978 register int hash = 0;
00979
00980 while (p != end)
00981 {
00982 c = *p++;
00983 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
00984 }
00985 return hash;
00986 }
00987
00988
00989
00990 char *
00991 _bfd_vms_length_hash_symbol (abfd, in, maxlen)
00992 bfd *abfd;
00993 const char *in;
00994 int maxlen;
00995 {
00996 long int result;
00997 int in_len;
00998 char *new_name;
00999 const char *old_name;
01000 int i;
01001 static char outbuf[EOBJ_S_C_SYMSIZ+1];
01002 char *out = outbuf;
01003
01004 #if VMS_DEBUG
01005 vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
01006 #endif
01007
01008 if (maxlen > EOBJ_S_C_SYMSIZ)
01009 maxlen = EOBJ_S_C_SYMSIZ;
01010
01011 new_name = out;
01012
01013
01014
01015 in_len = strlen (in);
01016
01017 result = (in_len > maxlen) ? hash_string (in) : 0;
01018
01019 old_name = in;
01020
01021
01022
01023 if (in_len <= maxlen)
01024 {
01025 i = in_len;
01026 }
01027 else
01028 {
01029 if (PRIV (flag_hash_long_names))
01030 i = maxlen-9;
01031 else
01032 i = maxlen;
01033 }
01034
01035 strncpy (out, in, (size_t) i);
01036 in += i;
01037 out += i;
01038
01039 if ((in_len > maxlen)
01040 && PRIV (flag_hash_long_names))
01041 sprintf (out, "_%08lx", result);
01042 else
01043 *out = 0;
01044
01045 #if VMS_DEBUG
01046 vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
01047 #endif
01048
01049 if (in_len > maxlen
01050 && PRIV (flag_hash_long_names)
01051 && PRIV (flag_show_after_trunc))
01052 printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
01053
01054 return outbuf;
01055 }
01056
01057
01058
01059 static asymbol *
01060 new_symbol (abfd, name)
01061 bfd *abfd;
01062 char *name;
01063 {
01064 asymbol *symbol;
01065
01066 #if VMS_DEBUG
01067 _bfd_vms_debug (7, "new_symbol %s\n", name);
01068 #endif
01069
01070 symbol = bfd_make_empty_symbol (abfd);
01071 if (symbol == 0)
01072 return symbol;
01073 symbol->name = name;
01074 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
01075
01076 return symbol;
01077 }
01078
01079
01080
01081 vms_symbol_entry *
01082 _bfd_vms_enter_symbol (abfd, name)
01083 bfd *abfd;
01084 char *name;
01085 {
01086 vms_symbol_entry *entry;
01087
01088 #if VMS_DEBUG
01089 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name);
01090 #endif
01091
01092 entry = (vms_symbol_entry *)
01093 bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
01094 if (entry == 0)
01095 {
01096 #if VMS_DEBUG
01097 _bfd_vms_debug (8, "creating hash entry for %s\n", name);
01098 #endif
01099 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
01100 name, TRUE, FALSE);
01101 if (entry != 0)
01102 {
01103 asymbol *symbol;
01104 symbol = new_symbol (abfd, name);
01105 if (symbol != 0)
01106 {
01107 entry->symbol = symbol;
01108 PRIV (gsd_sym_count)++;
01109 abfd->symcount++;
01110 }
01111 else
01112 entry = 0;
01113 }
01114 else
01115 (*_bfd_error_handler) (_("failed to enter %s"), name);
01116 }
01117 else
01118 {
01119 #if VMS_DEBUG
01120 _bfd_vms_debug (8, "found hash entry for %s\n", name);
01121 #endif
01122 }
01123
01124 #if VMS_DEBUG
01125 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
01126 #endif
01127 return entry;
01128 }