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