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