1 /* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2007, 2008, 2009 Free Software Foundation, Inc.
6 Miscellaneous functions.
8 Written by Klaus K"ampf (kkaempf@rmi.de)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
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.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
33 #include "safe-ctype.h"
37 #define MIN(a,b) ((a) < (b) ? (a) : (b))
39 static int hash_string
PARAMS ((const char *));
40 static asymbol
*new_symbol
PARAMS ((bfd
*, char *));
41 static void maybe_adjust_record_pointer_for_object
PARAMS ((bfd
*));
42 static int vms_get_remaining_object_record
PARAMS ((bfd
*, int ));
43 static int vms_get_remaining_image_record
PARAMS ((bfd
*, int ));
46 /* Debug functions. */
48 /* Debug function for all vms extensions evaluates environment
49 variable VMS_DEBUG for a numerical value on the first call all
50 error levels below this value are printed:
53 1 toplevel bfd calls (functions from the bfd vector)
54 2 functions called by bfd calls
58 Level is also indentation level. Indentation is performed
62 _bfd_vms_debug (int level
, char *format
, ...)
64 static int min_level
= -1;
65 static FILE *output
= NULL
;
68 int abslvl
= (level
> 0) ? level
: - level
;
72 if ((eptr
= getenv ("VMS_DEBUG")) != NULL
)
74 min_level
= atoi (eptr
);
82 if (abslvl
> min_level
)
86 fprintf (output
, " ");
87 va_start (args
, format
);
88 vfprintf (output
, format
, args
);
94 hex dump 'size' bytes starting at 'ptr'. */
97 _bfd_hexdump (int level
,
102 unsigned char *lptr
= ptr
;
109 vms_debug (level
, "%08lx:", start
);
110 vms_debug (-level
, " %02x", *ptr
++);
115 while ((count
%16) != 0)
117 vms_debug (-level
, " ");
123 vms_debug (-level
, " ");
126 vms_debug (-level
, "%c", (*lptr
< 32)?'.':*lptr
);
129 vms_debug (-level
, "\n");
133 vms_debug (-level
, "\n");
139 These are needed when reading an object file. */
141 /* Allocate new vms_hash_entry
142 keep the symbol name and a pointer to the bfd symbol in the table. */
144 struct bfd_hash_entry
*
145 _bfd_vms_hash_newfunc (struct bfd_hash_entry
*entry
,
146 struct bfd_hash_table
*table
,
149 vms_symbol_entry
*ret
;
152 vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry
, table
, string
);
157 ret
= (vms_symbol_entry
*)
158 bfd_hash_allocate (table
, sizeof (vms_symbol_entry
));
161 bfd_set_error (bfd_error_no_memory
);
164 entry
= (struct bfd_hash_entry
*) ret
;
167 /* Call the allocation method of the base class. */
168 ret
= (vms_symbol_entry
*) bfd_hash_newfunc (entry
, table
, string
);
170 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret
);
175 return (struct bfd_hash_entry
*)ret
;
178 /* Object file input functions. */
180 /* Return type and size from record header (buf) on Alpha. */
183 _bfd_vms_get_header_values (bfd
* abfd ATTRIBUTE_UNUSED
,
189 *type
= bfd_getl16 (buf
);
192 *size
= bfd_getl16 (buf
+2);
195 vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n",
196 type
? *type
: 0, size
? *size
: 0);
200 /* Get next record from object file to vms_buf.
201 Set PRIV(buf_size) and return it
203 This is a little tricky since it should be portable.
205 The openVMS object file has 'variable length' which means that
206 read() returns data in chunks of (hopefully) correct and expected
207 size. The linker (and other tools on VMS) depend on that. Unix
208 doesn't know about 'formatted' files, so reading and writing such
209 an object file in a Unix environment is not trivial.
211 With the tool 'file' (available on all VMS FTP sites), one
212 can view and change the attributes of a file. Changing from
213 'variable length' to 'fixed length, 512 bytes' reveals the
214 record size at the first 2 bytes of every record. The same
215 may happen during the transfer of object files from VMS to Unix,
216 at least with UCX, the DEC implementation of TCP/IP.
218 The VMS format repeats the size at bytes 2 & 3 of every record.
220 On the first call (file_format == FF_UNKNOWN) we check if
221 the first and the third byte pair (!) of the record match.
222 If they do it's an object file in an Unix environment or with
223 wrong attributes (FF_FOREIGN), else we should be in a VMS
224 environment where read() returns the record size (FF_NATIVE).
226 Reading is always done in 2 steps:
227 1. first just the record header is read and the size extracted,
228 2. then the read buffer is adjusted and the remaining bytes are
231 All file I/O is done on even file positions. */
233 #define VMS_OBJECT_ADJUSTMENT 2
236 maybe_adjust_record_pointer_for_object (bfd
*abfd
)
238 /* Set the file format once for all on the first invocation. */
239 if (PRIV (file_format
) == FF_UNKNOWN
)
241 if (PRIV (vms_rec
)[0] == PRIV (vms_rec
)[4]
242 && PRIV (vms_rec
)[1] == PRIV (vms_rec
)[5])
243 PRIV (file_format
) = FF_FOREIGN
;
245 PRIV (file_format
) = FF_NATIVE
;
248 /* The adjustment is needed only in an Unix environment. */
249 if (PRIV (file_format
) == FF_FOREIGN
)
250 PRIV (vms_rec
) += VMS_OBJECT_ADJUSTMENT
;
253 /* Get first record from file and return the file type. */
256 _bfd_vms_get_first_record (bfd
*abfd
)
258 unsigned int test_len
;
261 vms_debug (8, "_bfd_vms_get_first_record\n");
267 /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
268 2 bytes size repeated) and 12 bytes for images (4 bytes major id,
269 4 bytes minor id, 4 bytes length). */
272 /* Size the main buffer. */
273 if (PRIV (buf_size
) == 0)
275 /* On VAX there's no size information in the record, so
276 start with OBJ_S_C_MAXRECSIZ. */
277 bfd_size_type amt
= (test_len
? test_len
: OBJ_S_C_MAXRECSIZ
);
278 PRIV (vms_buf
) = (unsigned char *) bfd_malloc (amt
);
279 PRIV (buf_size
) = amt
;
282 /* Initialize the record pointer. */
283 PRIV (vms_rec
) = PRIV (vms_buf
);
285 /* We only support modules on VAX. */
288 if (vms_get_remaining_object_record (abfd
, test_len
) <= 0)
292 vms_debug (2, "file type is VAX module\n");
298 if (bfd_bread (PRIV (vms_buf
), test_len
, abfd
) != test_len
)
300 bfd_set_error (bfd_error_file_truncated
);
304 /* Is it an image? */
305 if ((bfd_getl32 (PRIV (vms_rec
)) == EIHD_S_K_MAJORID
)
306 && (bfd_getl32 (PRIV (vms_rec
) + 4) == EIHD_S_K_MINORID
))
308 if (vms_get_remaining_image_record (abfd
, test_len
) <= 0)
312 vms_debug (2, "file type is image\n");
318 /* Assume it's a module and adjust record pointer if necessary. */
319 maybe_adjust_record_pointer_for_object (abfd
);
321 /* But is it really a module? */
322 if (bfd_getl16 (PRIV (vms_rec
)) <= EOBJ_S_C_MAXRECTYP
323 && bfd_getl16 (PRIV (vms_rec
) + 2) <= EOBJ_S_C_MAXRECSIZ
)
325 if (vms_get_remaining_object_record (abfd
, test_len
) <= 0)
329 vms_debug (2, "file type is module\n");
336 vms_debug (2, "file type is unknown\n");
342 /* Implement step #1 of the object record reading procedure.
343 Return the record type or -1 on failure. */
346 _bfd_vms_get_object_record (bfd
*abfd
)
348 unsigned int test_len
;
352 vms_debug (8, "_bfd_vms_get_obj_record\n");
361 /* See _bfd_vms_get_first_record. */
364 /* Skip odd alignment byte. */
365 if (bfd_tell (abfd
) & 1)
367 if (bfd_bread (PRIV (vms_buf
), 1, abfd
) != 1)
369 bfd_set_error (bfd_error_file_truncated
);
372 /* Alignment byte may be present or not. This is not easy to
373 detect but all object record types are not 0 (on Alpha VMS).
374 We also hope that pad byte is 0. */
375 if (PRIV (vms_buf
)[0])
379 /* Read the record header */
380 if (bfd_bread (PRIV (vms_buf
) + off
, test_len
- off
, abfd
)
383 bfd_set_error (bfd_error_file_truncated
);
387 /* Reset the record pointer. */
388 PRIV (vms_rec
) = PRIV (vms_buf
);
389 maybe_adjust_record_pointer_for_object (abfd
);
392 if (vms_get_remaining_object_record (abfd
, test_len
) <= 0)
396 type
= PRIV (vms_rec
) [0];
398 type
= bfd_getl16 (PRIV (vms_rec
));
401 vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
402 PRIV (vms_rec
), PRIV (rec_size
), type
);
408 /* Implement step #2 of the object record reading procedure.
409 Return the size of the record or 0 on failure. */
412 vms_get_remaining_object_record (bfd
*abfd
, int read_so_far
)
415 vms_debug (8, "vms_get_remaining_obj_record\n");
420 if (read_so_far
!= 0)
423 PRIV (rec_size
) = bfd_bread (PRIV (vms_buf
), PRIV (buf_size
), abfd
);
425 if (PRIV (rec_size
) <= 0)
427 bfd_set_error (bfd_error_file_truncated
);
431 /* Reset the record pointer. */
432 PRIV (vms_rec
) = PRIV (vms_buf
);
436 unsigned int to_read
;
438 /* Extract record size. */
439 PRIV (rec_size
) = bfd_getl16 (PRIV (vms_rec
) + 2);
441 if (PRIV (rec_size
) <= 0)
443 bfd_set_error (bfd_error_file_truncated
);
447 /* That's what the linker manual says. */
448 if (PRIV (rec_size
) > EOBJ_S_C_MAXRECSIZ
)
450 bfd_set_error (bfd_error_file_truncated
);
454 /* Take into account object adjustment. */
455 to_read
= PRIV (rec_size
);
456 if (PRIV (file_format
) == FF_FOREIGN
)
457 to_read
+= VMS_OBJECT_ADJUSTMENT
;
459 /* Adjust the buffer. */
460 if (to_read
> PRIV (buf_size
))
463 = (unsigned char *) bfd_realloc (PRIV (vms_buf
), to_read
);
464 if (PRIV (vms_buf
) == NULL
)
466 PRIV (buf_size
) = to_read
;
469 /* Read the remaining record. */
470 to_read
-= read_so_far
;
473 vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read
);
476 if (bfd_bread (PRIV (vms_buf
) + read_so_far
, to_read
, abfd
) != to_read
)
478 bfd_set_error (bfd_error_file_truncated
);
482 /* Reset the record pointer. */
483 PRIV (vms_rec
) = PRIV (vms_buf
);
484 maybe_adjust_record_pointer_for_object (abfd
);
488 vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size
));
491 return PRIV (rec_size
);
494 /* Implement step #2 of the record reading procedure for images.
495 Return the size of the record or 0 on failure. */
498 vms_get_remaining_image_record (bfd
*abfd
, int read_so_far
)
500 unsigned int to_read
;
503 /* Extract record size. */
504 PRIV (rec_size
) = bfd_getl32 (PRIV (vms_rec
) + EIHD_S_L_SIZE
);
506 if (PRIV (rec_size
) > PRIV (buf_size
))
508 PRIV (vms_buf
) = bfd_realloc (PRIV (vms_buf
), PRIV (rec_size
));
510 if (PRIV (vms_buf
) == NULL
)
512 bfd_set_error (bfd_error_no_memory
);
516 PRIV (buf_size
) = PRIV (rec_size
);
519 /* Read the remaining record. */
520 remaining
= PRIV (rec_size
) - read_so_far
;
521 to_read
= MIN (VMS_BLOCK_SIZE
- read_so_far
, remaining
);
523 while (remaining
> 0)
525 if (bfd_bread (PRIV (vms_buf
) + read_so_far
, to_read
, abfd
) != to_read
)
527 bfd_set_error (bfd_error_file_truncated
);
531 read_so_far
+= to_read
;
532 remaining
-= to_read
;
534 /* Eat trailing 0xff's. */
536 while (PRIV (vms_buf
) [read_so_far
- 1] == 0xff)
539 to_read
= MIN (VMS_BLOCK_SIZE
, remaining
);
542 /* Reset the record pointer. */
543 PRIV (vms_rec
) = PRIV (vms_buf
);
545 return PRIV (rec_size
);
548 /* Copy sized string (string with fixed size) to new allocated area
549 size is string size (size of record) */
552 _bfd_vms_save_sized_string (unsigned char *str
, int size
)
554 char *newstr
= bfd_malloc ((bfd_size_type
) size
+ 1);
558 strncpy (newstr
, (char *) str
, (size_t) size
);
564 /* Copy counted string (string with size at first byte) to new allocated area
565 ptr points to size byte on entry */
568 _bfd_vms_save_counted_string (unsigned char *ptr
)
572 return _bfd_vms_save_sized_string (ptr
, len
);
575 /* Stack routines for vms ETIR commands. */
577 /* Push value and section index. */
580 _bfd_vms_push (bfd
* abfd
, uquad val
, int psect
)
582 static int last_psect
;
585 vms_debug (4, "<push %016lx (%d) at %d>\n", val
, psect
, PRIV (stackptr
));
591 PRIV (stack
[PRIV (stackptr
)]).value
= val
;
592 PRIV (stack
[PRIV (stackptr
)]).psect
= last_psect
;
594 if (PRIV (stackptr
) >= STACKSIZE
)
596 bfd_set_error (bfd_error_bad_value
);
597 (*_bfd_error_handler
) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr
));
602 /* Pop value and section index. */
605 _bfd_vms_pop (bfd
* abfd
, int *psect
)
609 if (PRIV (stackptr
) == 0)
611 bfd_set_error (bfd_error_bad_value
);
612 (*_bfd_error_handler
) (_("Stack underflow in _bfd_vms_pop"));
616 value
= PRIV (stack
[PRIV (stackptr
)]).value
;
617 if ((psect
!= NULL
) && (PRIV (stack
[PRIV (stackptr
)]).psect
>= 0))
618 *psect
= PRIV (stack
[PRIV (stackptr
)]).psect
;
621 vms_debug (4, "<pop %016lx(%d)>\n", value
, PRIV (stack
[PRIV (stackptr
)]).psect
);
627 /* Object output routines. */
629 /* Begin new record or record header
630 write 2 bytes rectype
631 write 2 bytes record length (filled in at flush)
632 write 2 bytes header type (ommitted if rechead == -1). */
635 _bfd_vms_output_begin (bfd
* abfd
, int rectype
, int rechead
)
638 vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype
,
642 _bfd_vms_output_short (abfd
, (unsigned int) rectype
);
644 /* Save current output position to fill in length later. */
646 if (PRIV (push_level
) > 0)
647 PRIV (length_pos
) = PRIV (output_size
);
650 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
654 /* Placeholder for length. */
655 _bfd_vms_output_short (abfd
, 0);
658 _bfd_vms_output_short (abfd
, (unsigned int) rechead
);
661 /* Set record/subrecord alignment. */
664 _bfd_vms_output_alignment (bfd
* abfd
, int alignto
)
667 vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto
);
670 PRIV (output_alignment
) = alignto
;
673 /* Prepare for subrecord fields. */
676 _bfd_vms_output_push (bfd
* abfd
)
679 vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size
));
683 PRIV (pushed_size
) = PRIV (output_size
);
686 /* End of subrecord fields. */
689 _bfd_vms_output_pop (bfd
* abfd
)
692 vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size
));
695 _bfd_vms_output_flush (abfd
);
696 PRIV (length_pos
) = 2;
699 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos
));
702 PRIV (pushed_size
) = 0;
706 /* Flush unwritten output, ends current record. */
709 _bfd_vms_output_flush (bfd
* abfd
)
711 int real_size
= PRIV (output_size
);
716 vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n",
717 real_size
, PRIV (pushed_size
), PRIV (length_pos
));
720 if (PRIV (push_level
) > 0)
721 length
= real_size
- PRIV (pushed_size
);
727 aligncount
= (PRIV (output_alignment
)
728 - (length
% PRIV (output_alignment
))) % PRIV (output_alignment
);
731 vms_debug (6, "align: adding %d bytes\n", aligncount
);
734 while (aligncount
-- > 0)
736 PRIV (output_buf
)[real_size
++] = 0;
740 /* Put length to buffer. */
741 PRIV (output_size
) = PRIV (length_pos
);
742 _bfd_vms_output_short (abfd
, (unsigned int) length
);
744 if (PRIV (push_level
) == 0)
746 /* File is open in undefined (UDF) format on VMS, but ultimately will be
747 converted to variable length (VAR) format. VAR format has a length
748 word first which must be explicitly output in UDF format. */
749 bfd_bwrite (PRIV (output_buf
) + 2, 2, abfd
);
750 bfd_bwrite (PRIV (output_buf
), (size_t) real_size
, abfd
);
751 PRIV (output_size
) = 0;
755 PRIV (output_size
) = real_size
;
756 PRIV (pushed_size
) = PRIV (output_size
);
760 /* End record output. */
763 _bfd_vms_output_end (bfd
* abfd
)
766 vms_debug (6, "_bfd_vms_output_end\n");
769 _bfd_vms_output_flush (abfd
);
772 /* Check remaining buffer size
774 Return what's left. */
777 _bfd_vms_output_check (bfd
* abfd
, int size
)
780 vms_debug (6, "_bfd_vms_output_check (%d)\n", size
);
783 return (MAX_OUTREC_SIZE
- (PRIV (output_size
) + size
+ MIN_OUTREC_LUFT
));
786 /* Output byte (8 bit) value. */
789 _bfd_vms_output_byte (bfd
* abfd
, unsigned int value
)
792 vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value
);
795 bfd_put_8 (abfd
, value
& 0xff, PRIV (output_buf
) + PRIV (output_size
));
796 PRIV (output_size
) += 1;
799 /* Output short (16 bit) value. */
802 _bfd_vms_output_short (bfd
* abfd
, unsigned int value
)
805 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value
);
808 bfd_put_16 (abfd
, (bfd_vma
) value
& 0xffff,
809 PRIV (output_buf
) + PRIV (output_size
));
810 PRIV (output_size
) += 2;
813 /* Output long (32 bit) value. */
816 _bfd_vms_output_long (bfd
* abfd
, unsigned long value
)
819 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value
);
822 bfd_put_32 (abfd
, (bfd_vma
) value
, PRIV (output_buf
) + PRIV (output_size
));
823 PRIV (output_size
) += 4;
826 /* Output quad (64 bit) value. */
829 _bfd_vms_output_quad (bfd
* abfd
, uquad value
)
832 vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value
);
835 bfd_put_64(abfd
, value
, PRIV (output_buf
) + PRIV (output_size
));
836 PRIV (output_size
) += 8;
839 /* Output c-string as counted string. */
842 _bfd_vms_output_counted (bfd
* abfd
, char *value
)
847 vms_debug (6, "_bfd_vms_output_counted (%s)\n", value
);
850 len
= strlen (value
);
853 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with zero bytes"));
858 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with too many bytes"));
861 _bfd_vms_output_byte (abfd
, (unsigned int) len
& 0xff);
862 _bfd_vms_output_dump (abfd
, (unsigned char *) value
, len
);
865 /* Output character area. */
868 _bfd_vms_output_dump (bfd
* abfd
,
873 vms_debug (6, "_bfd_vms_output_dump (%d)\n", length
);
879 memcpy (PRIV (output_buf
) + PRIV (output_size
), data
, (size_t) length
);
880 PRIV (output_size
) += length
;
883 /* Output count bytes of value. */
886 _bfd_vms_output_fill (bfd
* abfd
,
891 vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value
, count
);
896 memset (PRIV (output_buf
) + PRIV (output_size
), value
, (size_t) count
);
897 PRIV (output_size
) += count
;
900 /* This hash routine borrowed from GNU-EMACS, and strengthened slightly. ERY. */
903 hash_string (const char *ptr
)
905 const unsigned char *p
= (unsigned char *) ptr
;
906 const unsigned char *end
= p
+ strlen (ptr
);
913 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
918 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
921 _bfd_vms_length_hash_symbol (bfd
* abfd
, const char *in
, int maxlen
)
923 unsigned long result
;
926 const char *old_name
;
928 static char outbuf
[EOBJ_S_C_SYMSIZ
+1];
932 vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in
);
935 if (maxlen
> EOBJ_S_C_SYMSIZ
)
936 maxlen
= EOBJ_S_C_SYMSIZ
;
938 /* Save this for later. */
941 /* We may need to truncate the symbol, save the hash for later. */
942 in_len
= strlen (in
);
944 result
= (in_len
> maxlen
) ? hash_string (in
) : 0;
948 /* Do the length checking. */
949 if (in_len
<= maxlen
)
953 if (PRIV (flag_hash_long_names
))
959 strncpy (out
, in
, (size_t) i
);
963 if ((in_len
> maxlen
)
964 && PRIV (flag_hash_long_names
))
965 sprintf (out
, "_%08lx", result
);
970 vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf
), outbuf
);
974 && PRIV (flag_hash_long_names
)
975 && PRIV (flag_show_after_trunc
))
976 printf (_("Symbol %s replaced by %s\n"), old_name
, new_name
);
981 /* Allocate and initialize a new symbol. */
984 new_symbol (bfd
* abfd
, char *name
)
989 _bfd_vms_debug (7, "new_symbol %s\n", name
);
992 symbol
= bfd_make_empty_symbol (abfd
);
996 symbol
->section
= (asection
*)(unsigned long)-1;
1001 /* Allocate and enter a new private symbol. */
1004 _bfd_vms_enter_symbol (bfd
* abfd
, char *name
)
1006 vms_symbol_entry
*entry
;
1009 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name
);
1012 entry
= (vms_symbol_entry
*)
1013 bfd_hash_lookup (PRIV (vms_symbol_table
), name
, FALSE
, FALSE
);
1017 _bfd_vms_debug (8, "creating hash entry for %s\n", name
);
1019 entry
= (vms_symbol_entry
*) bfd_hash_lookup (PRIV (vms_symbol_table
),
1024 symbol
= new_symbol (abfd
, name
);
1027 entry
->symbol
= symbol
;
1028 PRIV (gsd_sym_count
)++;
1035 (*_bfd_error_handler
) (_("failed to enter %s"), name
);
1040 _bfd_vms_debug (8, "found hash entry for %s\n", name
);
1045 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry
, entry
->symbol
);
1050 /* Create module name from filename (ie, extract the basename and convert it
1051 in upper cases). Works on both VMS and UNIX pathes.
1052 The result has to be free(). */
1055 vms_get_module_name (const char *filename
, bfd_boolean upcase
)
1060 /* Strip VMS path. */
1061 fout
= strrchr (filename
, ']');
1063 fout
= strchr (filename
, ':');
1069 /* Strip UNIX path. */
1070 fptr
= strrchr (fout
, '/');
1074 fname
= strdup (fout
);
1077 fptr
= strrchr (fname
, '.');
1081 /* Convert to upper case and truncate at 31 characters.
1082 (VMS object file format restricts module name length to 31). */
1084 for (fptr
= fname
; *fptr
!= 0; fptr
++)
1086 if (*fptr
== ';' || (fptr
- fname
) >= 31)
1092 *fptr
= TOUPPER (*fptr
);
1097 /* Convert a raw VMS time to a unix time. */
1100 vms_time_to_time_t (unsigned int hi
, unsigned int lo
)
1102 const unsigned int off
= 3506716800U;
1103 const unsigned int factor
= 10000000;
1108 /* First convert to seconds. */
1112 for (i
= 0; i
< 4; i
++)
1114 tmp
= (tmp
<< 8) | (lo
>> 24);
1117 rlo
= (rlo
<< 8) | (tmp
/ factor
);
1122 /* Return 0 in case of overflow. */
1123 if (lo
> off
&& hi
> 1)
1129 /* Convert a raw (stored in a buffer) VMS time to a unix time. */
1132 vms_rawtime_to_time_t (unsigned char *buf
)
1134 unsigned int hi
= bfd_getl32 (buf
+ 4);
1135 unsigned int lo
= bfd_getl32 (buf
+ 0);
1137 return vms_time_to_time_t (hi
, lo
);