2010-01-27 Tristan Gingold <gingold@adacore.com>
[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 may happen 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 int off = 0;
359
360 /* See _bfd_vms_get_first_record. */
361 test_len = 6;
362
363 /* Skip odd alignment byte. */
364 if (bfd_tell (abfd) & 1)
365 {
366 if (bfd_bread (PRIV (vms_buf), 1, abfd) != 1)
367 {
368 bfd_set_error (bfd_error_file_truncated);
369 return -1;
370 }
371 /* Alignment byte may be present or not. This is not easy to
372 detect but all object record types are not 0 (on Alpha VMS).
373 We also hope that pad byte is 0. */
374 if (PRIV (vms_buf)[0])
375 off = 1;
376 }
377
378 /* Read the record header */
379 if (bfd_bread (PRIV (vms_buf) + off, test_len - off, abfd)
380 != test_len - off)
381 {
382 bfd_set_error (bfd_error_file_truncated);
383 return -1;
384 }
385
386 /* Reset the record pointer. */
387 PRIV (vms_rec) = PRIV (vms_buf);
388 maybe_adjust_record_pointer_for_object (abfd);
389 }
390
391 if (vms_get_remaining_object_record (abfd, test_len) <= 0)
392 return -1;
393
394 if (PRIV (is_vax))
395 type = PRIV (vms_rec) [0];
396 else
397 type = bfd_getl16 (PRIV (vms_rec));
398
399 #if VMS_DEBUG
400 vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
401 PRIV (vms_rec), PRIV (rec_size), type);
402 #endif
403
404 return type;
405 }
406
407 /* Implement step #2 of the object record reading procedure.
408 Return the size of the record or 0 on failure. */
409
410 static int
411 vms_get_remaining_object_record (bfd *abfd, int read_so_far)
412 {
413 #if VMS_DEBUG
414 vms_debug (8, "vms_get_remaining_obj_record\n");
415 #endif
416
417 if (PRIV (is_vax))
418 {
419 if (read_so_far != 0)
420 abort ();
421
422 PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd);
423
424 if (PRIV (rec_size) <= 0)
425 {
426 bfd_set_error (bfd_error_file_truncated);
427 return 0;
428 }
429
430 /* Reset the record pointer. */
431 PRIV (vms_rec) = PRIV (vms_buf);
432 }
433 else
434 {
435 unsigned int to_read;
436
437 /* Extract record size. */
438 PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2);
439
440 if (PRIV (rec_size) <= 0)
441 {
442 bfd_set_error (bfd_error_file_truncated);
443 return 0;
444 }
445
446 /* That's what the linker manual says. */
447 if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ)
448 {
449 bfd_set_error (bfd_error_file_truncated);
450 return 0;
451 }
452
453 /* Take into account object adjustment. */
454 to_read = PRIV (rec_size);
455 if (PRIV (file_format) == FF_FOREIGN)
456 to_read += VMS_OBJECT_ADJUSTMENT;
457
458 /* Adjust the buffer. */
459 if (to_read > PRIV (buf_size))
460 {
461 PRIV (vms_buf)
462 = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read);
463 if (PRIV (vms_buf) == NULL)
464 return 0;
465 PRIV (buf_size) = to_read;
466 }
467
468 /* Read the remaining record. */
469 to_read -= read_so_far;
470
471 #if VMS_DEBUG
472 vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read);
473 #endif
474
475 if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
476 {
477 bfd_set_error (bfd_error_file_truncated);
478 return 0;
479 }
480
481 /* Reset the record pointer. */
482 PRIV (vms_rec) = PRIV (vms_buf);
483 maybe_adjust_record_pointer_for_object (abfd);
484 }
485
486 #if VMS_DEBUG
487 vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size));
488 #endif
489
490 return PRIV (rec_size);
491 }
492
493 /* Implement step #2 of the record reading procedure for images.
494 Return the size of the record or 0 on failure. */
495
496 static int
497 vms_get_remaining_image_record (bfd *abfd, int read_so_far)
498 {
499 unsigned int to_read;
500 int remaining;
501
502 /* Extract record size. */
503 PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
504
505 if (PRIV (rec_size) > PRIV (buf_size))
506 {
507 PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size));
508
509 if (PRIV (vms_buf) == NULL)
510 {
511 bfd_set_error (bfd_error_no_memory);
512 return 0;
513 }
514
515 PRIV (buf_size) = PRIV (rec_size);
516 }
517
518 /* Read the remaining record. */
519 remaining = PRIV (rec_size) - read_so_far;
520 to_read = MIN (VMS_BLOCK_SIZE - read_so_far, remaining);
521
522 while (remaining > 0)
523 {
524 if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
525 {
526 bfd_set_error (bfd_error_file_truncated);
527 return 0;
528 }
529
530 read_so_far += to_read;
531 remaining -= to_read;
532
533 /* Eat trailing 0xff's. */
534 if (remaining > 0)
535 while (PRIV (vms_buf) [read_so_far - 1] == 0xff)
536 read_so_far--;
537
538 to_read = MIN (VMS_BLOCK_SIZE, remaining);
539 }
540
541 /* Reset the record pointer. */
542 PRIV (vms_rec) = PRIV (vms_buf);
543
544 return PRIV (rec_size);
545 }
546
547 /* Copy sized string (string with fixed size) to new allocated area
548 size is string size (size of record) */
549
550 char *
551 _bfd_vms_save_sized_string (unsigned char *str, int size)
552 {
553 char *newstr = bfd_malloc ((bfd_size_type) size + 1);
554
555 if (newstr == NULL)
556 return NULL;
557 strncpy (newstr, (char *) str, (size_t) size);
558 newstr[size] = 0;
559
560 return newstr;
561 }
562
563 /* Copy counted string (string with size at first byte) to new allocated area
564 ptr points to size byte on entry */
565
566 char *
567 _bfd_vms_save_counted_string (unsigned char *ptr)
568 {
569 int len = *ptr++;
570
571 return _bfd_vms_save_sized_string (ptr, len);
572 }
573 \f
574 /* Stack routines for vms ETIR commands. */
575
576 /* Push value and section index. */
577
578 void
579 _bfd_vms_push (bfd * abfd, uquad val, int psect)
580 {
581 static int last_psect;
582
583 #if VMS_DEBUG
584 vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr));
585 #endif
586
587 if (psect >= 0)
588 last_psect = psect;
589
590 PRIV (stack[PRIV (stackptr)]).value = val;
591 PRIV (stack[PRIV (stackptr)]).psect = last_psect;
592 PRIV (stackptr)++;
593 if (PRIV (stackptr) >= STACKSIZE)
594 {
595 bfd_set_error (bfd_error_bad_value);
596 (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
597 exit (1);
598 }
599 }
600
601 /* Pop value and section index. */
602
603 uquad
604 _bfd_vms_pop (bfd * abfd, int *psect)
605 {
606 uquad value;
607
608 if (PRIV (stackptr) == 0)
609 {
610 bfd_set_error (bfd_error_bad_value);
611 (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
612 exit (1);
613 }
614 PRIV (stackptr)--;
615 value = PRIV (stack[PRIV (stackptr)]).value;
616 if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
617 *psect = PRIV (stack[PRIV (stackptr)]).psect;
618
619 #if VMS_DEBUG
620 vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
621 #endif
622
623 return value;
624 }
625 \f
626 /* Object output routines. */
627
628 /* Begin new record or record header
629 write 2 bytes rectype
630 write 2 bytes record length (filled in at flush)
631 write 2 bytes header type (ommitted if rechead == -1). */
632
633 void
634 _bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
635 {
636 #if VMS_DEBUG
637 vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype,
638 rechead);
639 #endif
640
641 _bfd_vms_output_short (abfd, (unsigned int) rectype);
642
643 /* Save current output position to fill in length later. */
644
645 if (PRIV (push_level) > 0)
646 PRIV (length_pos) = PRIV (output_size);
647
648 #if VMS_DEBUG
649 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
650 PRIV (length_pos));
651 #endif
652
653 /* Placeholder for length. */
654 _bfd_vms_output_short (abfd, 0);
655
656 if (rechead != -1)
657 _bfd_vms_output_short (abfd, (unsigned int) rechead);
658 }
659
660 /* Set record/subrecord alignment. */
661
662 void
663 _bfd_vms_output_alignment (bfd * abfd, int alignto)
664 {
665 #if VMS_DEBUG
666 vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto);
667 #endif
668
669 PRIV (output_alignment) = alignto;
670 }
671
672 /* Prepare for subrecord fields. */
673
674 void
675 _bfd_vms_output_push (bfd * abfd)
676 {
677 #if VMS_DEBUG
678 vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size));
679 #endif
680
681 PRIV (push_level)++;
682 PRIV (pushed_size) = PRIV (output_size);
683 }
684
685 /* End of subrecord fields. */
686
687 void
688 _bfd_vms_output_pop (bfd * abfd)
689 {
690 #if VMS_DEBUG
691 vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size));
692 #endif
693
694 _bfd_vms_output_flush (abfd);
695 PRIV (length_pos) = 2;
696
697 #if VMS_DEBUG
698 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
699 #endif
700
701 PRIV (pushed_size) = 0;
702 PRIV (push_level)--;
703 }
704
705 /* Flush unwritten output, ends current record. */
706
707 void
708 _bfd_vms_output_flush (bfd * abfd)
709 {
710 int real_size = PRIV (output_size);
711 int aligncount;
712 int length;
713
714 #if VMS_DEBUG
715 vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n",
716 real_size, PRIV (pushed_size), PRIV (length_pos));
717 #endif
718
719 if (PRIV (push_level) > 0)
720 length = real_size - PRIV (pushed_size);
721 else
722 length = real_size;
723
724 if (length == 0)
725 return;
726 aligncount = (PRIV (output_alignment)
727 - (length % PRIV (output_alignment))) % PRIV (output_alignment);
728
729 #if VMS_DEBUG
730 vms_debug (6, "align: adding %d bytes\n", aligncount);
731 #endif
732
733 while (aligncount-- > 0)
734 {
735 PRIV (output_buf)[real_size++] = 0;
736 length++;
737 }
738
739 /* Put length to buffer. */
740 PRIV (output_size) = PRIV (length_pos);
741 _bfd_vms_output_short (abfd, (unsigned int) length);
742
743 if (PRIV (push_level) == 0)
744 {
745 /* File is open in undefined (UDF) format on VMS, but ultimately will be
746 converted to variable length (VAR) format. VAR format has a length
747 word first which must be explicitly output in UDF format. */
748 bfd_bwrite (PRIV (output_buf) + 2, 2, abfd);
749 bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd);
750 PRIV (output_size) = 0;
751 }
752 else
753 {
754 PRIV (output_size) = real_size;
755 PRIV (pushed_size) = PRIV (output_size);
756 }
757 }
758
759 /* End record output. */
760
761 void
762 _bfd_vms_output_end (bfd * abfd)
763 {
764 #if VMS_DEBUG
765 vms_debug (6, "_bfd_vms_output_end\n");
766 #endif
767
768 _bfd_vms_output_flush (abfd);
769 }
770
771 /* Check remaining buffer size
772
773 Return what's left. */
774
775 int
776 _bfd_vms_output_check (bfd * abfd, int size)
777 {
778 #if VMS_DEBUG
779 vms_debug (6, "_bfd_vms_output_check (%d)\n", size);
780 #endif
781
782 return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
783 }
784
785 /* Output byte (8 bit) value. */
786
787 void
788 _bfd_vms_output_byte (bfd * abfd, unsigned int value)
789 {
790 #if VMS_DEBUG
791 vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value);
792 #endif
793
794 bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
795 PRIV (output_size) += 1;
796 }
797
798 /* Output short (16 bit) value. */
799
800 void
801 _bfd_vms_output_short (bfd * abfd, unsigned int value)
802 {
803 #if VMS_DEBUG
804 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
805 #endif
806
807 bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
808 PRIV (output_buf) + PRIV (output_size));
809 PRIV (output_size) += 2;
810 }
811
812 /* Output long (32 bit) value. */
813
814 void
815 _bfd_vms_output_long (bfd * abfd, unsigned long value)
816 {
817 #if VMS_DEBUG
818 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
819 #endif
820
821 bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
822 PRIV (output_size) += 4;
823 }
824
825 /* Output quad (64 bit) value. */
826
827 void
828 _bfd_vms_output_quad (bfd * abfd, uquad value)
829 {
830 #if VMS_DEBUG
831 vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value);
832 #endif
833
834 bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
835 PRIV (output_size) += 8;
836 }
837
838 /* Output c-string as counted string. */
839
840 void
841 _bfd_vms_output_counted (bfd * abfd, char *value)
842 {
843 int len;
844
845 #if VMS_DEBUG
846 vms_debug (6, "_bfd_vms_output_counted (%s)\n", value);
847 #endif
848
849 len = strlen (value);
850 if (len == 0)
851 {
852 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
853 return;
854 }
855 if (len > 255)
856 {
857 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
858 return;
859 }
860 _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
861 _bfd_vms_output_dump (abfd, (unsigned char *) value, len);
862 }
863
864 /* Output character area. */
865
866 void
867 _bfd_vms_output_dump (bfd * abfd,
868 unsigned char *data,
869 int length)
870 {
871 #if VMS_DEBUG
872 vms_debug (6, "_bfd_vms_output_dump (%d)\n", length);
873 #endif
874
875 if (length == 0)
876 return;
877
878 memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
879 PRIV (output_size) += length;
880 }
881
882 /* Output count bytes of value. */
883
884 void
885 _bfd_vms_output_fill (bfd * abfd,
886 int value,
887 int count)
888 {
889 #if VMS_DEBUG
890 vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count);
891 #endif
892
893 if (count == 0)
894 return;
895 memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
896 PRIV (output_size) += count;
897 }
898
899 /* This hash routine borrowed from GNU-EMACS, and strengthened slightly. ERY. */
900
901 static int
902 hash_string (const char *ptr)
903 {
904 const unsigned char *p = (unsigned char *) ptr;
905 const unsigned char *end = p + strlen (ptr);
906 unsigned char c;
907 int hash = 0;
908
909 while (p != end)
910 {
911 c = *p++;
912 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
913 }
914 return hash;
915 }
916
917 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
918
919 char *
920 _bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen)
921 {
922 unsigned long result;
923 int in_len;
924 char *new_name;
925 const char *old_name;
926 int i;
927 static char outbuf[EOBJ_S_C_SYMSIZ+1];
928 char *out = outbuf;
929
930 #if VMS_DEBUG
931 vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
932 #endif
933
934 if (maxlen > EOBJ_S_C_SYMSIZ)
935 maxlen = EOBJ_S_C_SYMSIZ;
936
937 /* Save this for later. */
938 new_name = out;
939
940 /* We may need to truncate the symbol, save the hash for later. */
941 in_len = strlen (in);
942
943 result = (in_len > maxlen) ? hash_string (in) : 0;
944
945 old_name = in;
946
947 /* Do the length checking. */
948 if (in_len <= maxlen)
949 i = in_len;
950 else
951 {
952 if (PRIV (flag_hash_long_names))
953 i = maxlen-9;
954 else
955 i = maxlen;
956 }
957
958 strncpy (out, in, (size_t) i);
959 in += i;
960 out += i;
961
962 if ((in_len > maxlen)
963 && PRIV (flag_hash_long_names))
964 sprintf (out, "_%08lx", result);
965 else
966 *out = 0;
967
968 #if VMS_DEBUG
969 vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
970 #endif
971
972 if (in_len > maxlen
973 && PRIV (flag_hash_long_names)
974 && PRIV (flag_show_after_trunc))
975 printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
976
977 return outbuf;
978 }
979
980 /* Allocate and initialize a new symbol. */
981
982 static asymbol *
983 new_symbol (bfd * abfd, char *name)
984 {
985 asymbol *symbol;
986
987 #if VMS_DEBUG
988 _bfd_vms_debug (7, "new_symbol %s\n", name);
989 #endif
990
991 symbol = bfd_make_empty_symbol (abfd);
992 if (symbol == 0)
993 return symbol;
994 symbol->name = name;
995 symbol->section = (asection *)(unsigned long)-1;
996
997 return symbol;
998 }
999
1000 /* Allocate and enter a new private symbol. */
1001
1002 vms_symbol_entry *
1003 _bfd_vms_enter_symbol (bfd * abfd, char *name)
1004 {
1005 vms_symbol_entry *entry;
1006
1007 #if VMS_DEBUG
1008 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name);
1009 #endif
1010
1011 entry = (vms_symbol_entry *)
1012 bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
1013 if (entry == 0)
1014 {
1015 #if VMS_DEBUG
1016 _bfd_vms_debug (8, "creating hash entry for %s\n", name);
1017 #endif
1018 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
1019 name, TRUE, FALSE);
1020 if (entry != 0)
1021 {
1022 asymbol *symbol;
1023 symbol = new_symbol (abfd, name);
1024 if (symbol != 0)
1025 {
1026 entry->symbol = symbol;
1027 PRIV (gsd_sym_count)++;
1028 abfd->symcount++;
1029 }
1030 else
1031 entry = 0;
1032 }
1033 else
1034 (*_bfd_error_handler) (_("failed to enter %s"), name);
1035 }
1036 else
1037 {
1038 #if VMS_DEBUG
1039 _bfd_vms_debug (8, "found hash entry for %s\n", name);
1040 #endif
1041 }
1042
1043 #if VMS_DEBUG
1044 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
1045 #endif
1046 return entry;
1047 }
This page took 0.08583 seconds and 4 git commands to generate.