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