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