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