X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fvms-misc.c;h=21816587ef458f7a32add36a53ce3e52ea287b26;hb=d2c7a1a63b98c1add3d78ba71ffa9f2a105c1cd4;hp=48029dd5cd246bc30785ec3e52ae37e010fd2fb8;hpb=558e161f24558ec8b8e78d135e4d9db182885a3e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c index 48029dd5cd..21816587ef 100644 --- a/bfd/vms-misc.c +++ b/bfd/vms-misc.c @@ -1,54 +1,62 @@ -/* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and +/* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and EVAX (openVMS/Alpha) files. - Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008, 2009 Free Software Foundation, Inc. + + Miscellaneous functions. Written by Klaus K"ampf (kkaempf@rmi.de) -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #if __STDC__ #include #endif -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "libbfd.h" #include "vms.h" -/*-----------------------------------------------------------------------------*/ +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +static int hash_string PARAMS ((const char *)); +static asymbol *new_symbol PARAMS ((bfd *, char *)); +static void maybe_adjust_record_pointer_for_object PARAMS ((bfd *)); +static int vms_get_remaining_object_record PARAMS ((bfd *, int )); +static int vms_get_remaining_image_record PARAMS ((bfd *, int )); + #if VMS_DEBUG -/* debug functions */ +/* Debug functions. */ -/* debug function for all vms extensions - evaluates environment variable VMS_DEBUG for a - numerical value on the first call - all error levels below this value are printed +/* Debug function for all vms extensions evaluates environment + variable VMS_DEBUG for a numerical value on the first call all + error levels below this value are printed: - levels: + Levels: 1 toplevel bfd calls (functions from the bfd vector) 2 functions called by bfd calls ... 9 almost everything - level is also identation level. Indentation is performed - if level > 0 - */ + Level is also indentation level. Indentation is performed + if level > 0. */ -#if __STDC__ void _bfd_vms_debug (int level, char *format, ...) { @@ -56,13 +64,13 @@ _bfd_vms_debug (int level, char *format, ...) static FILE *output = NULL; char *eptr; va_list args; - int abslvl = (level > 0)?level:-level; + int abslvl = (level > 0) ? level : - level; if (min_level == -1) { - if ((eptr = getenv("VMS_DEBUG")) != NULL) + if ((eptr = getenv ("VMS_DEBUG")) != NULL) { - min_level = atoi(eptr); + min_level = atoi (eptr); output = stderr; } else @@ -75,60 +83,20 @@ _bfd_vms_debug (int level, char *format, ...) while (--level>0) fprintf (output, " "); - va_start(args, format); + va_start (args, format); vfprintf (output, format, args); - fflush(output); - va_end(args); - - return; -} - -#else /* not __STDC__ */ - -void -_bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6) - int level; - char *format; - long a1; long a2; long a3; - long a4; long a5; long a6; -{ - static int min_level = -1; - static FILE *output = NULL; - char *eptr; - - if (min_level == -1) - { - if ((eptr = getenv("VMS_DEBUG")) != NULL) - { - min_level = atoi(eptr); - output = stderr; - } - else - min_level = 0; - } - if (output == NULL) - return; - if (level > min_level) - return; - - while (--level>0) - fprintf (output, " "); - fprintf (output, format, a1, a2, a3, a4, a5, a6); - fflush(output); - - return; + fflush (output); + va_end (args); } -#endif /* __STDC__ */ -/* a debug function - hex dump 'size' bytes starting at 'ptr' */ +/* A debug function + hex dump 'size' bytes starting at 'ptr'. */ void -_bfd_hexdump (level, ptr, size, offset) - int level; - unsigned char *ptr; - int size; - int offset; +_bfd_hexdump (int level, + unsigned char *ptr, + int size, + int offset) { unsigned char *lptr = ptr; int count = 0; @@ -162,605 +130,593 @@ _bfd_hexdump (level, ptr, size, offset) } if ((count%16) != 0) vms_debug (-level, "\n"); - - return; } #endif - -/* hash functions +/* Hash functions These are needed when reading an object file. */ -/* allocate new vms_hash_entry - keep the symbol name and a pointer to the bfd symbol in the table */ +/* Allocate new vms_hash_entry + keep the symbol name and a pointer to the bfd symbol in the table. */ struct bfd_hash_entry * -_bfd_vms_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +_bfd_vms_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { vms_symbol_entry *ret; #if VMS_DEBUG - vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry, table, string); + vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string); #endif - if (entry == (struct bfd_hash_entry *)NULL) + if (entry == NULL) { ret = (vms_symbol_entry *) bfd_hash_allocate (table, sizeof (vms_symbol_entry)); - if (ret == (vms_symbol_entry *) NULL) + if (ret == NULL) { bfd_set_error (bfd_error_no_memory); - return (struct bfd_hash_entry *)NULL; + return NULL; } entry = (struct bfd_hash_entry *) ret; } /* Call the allocation method of the base class. */ - ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string); #if VMS_DEBUG vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret); #endif - ret->symbol = (asymbol *)NULL; + ret->symbol = NULL; return (struct bfd_hash_entry *)ret; } - -/* object file input functions */ +/* Object file input functions. */ -/* Return type and length from record header (buf) on Alpha. */ +/* Return type and size from record header (buf) on Alpha. */ void -_bfd_vms_get_header_values (abfd, buf, type, length) - bfd *abfd ATTRIBUTE_UNUSED; - unsigned char *buf; - int *type; - int *length; +_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED, + unsigned char *buf, + int *type, + int *size) { - if (type != 0) + if (type) *type = bfd_getl16 (buf); - buf += 2; - if (length != 0) - *length = bfd_getl16 (buf); + + if (size) + *size = bfd_getl16 (buf+2); #if VMS_DEBUG - vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0)); + vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n", + type ? *type : 0, size ? *size : 0); #endif - - return; } -/* Get next record from object file to vms_buf - set PRIV(buf_size) and return it +/* Get next record from object file to vms_buf. + Set PRIV(buf_size) and return it - this is a little tricky since it should be portable. + This is a little tricky since it should be portable. - the openVMS object file has 'variable length' which means that + The openVMS object file has 'variable length' which means that read() returns data in chunks of (hopefully) correct and expected - size. The linker (and other tools on vms) depend on that. Unix doesn't - know about 'formatted' files, so reading and writing such an object - file in a unix environment is not trivial. + size. The linker (and other tools on VMS) depend on that. Unix + doesn't know about 'formatted' files, so reading and writing such + an object file in a Unix environment is not trivial. - With the tool 'file' (available on all vms ftp sites), one - can view and change the attributes of a file. Changing from + With the tool 'file' (available on all VMS FTP sites), one + can view and change the attributes of a file. Changing from 'variable length' to 'fixed length, 512 bytes' reveals the - record length at the first 2 bytes of every record. The same - happens during the transfer of object files from vms to unix, - at least with ucx, dec's implementation of tcp/ip. + record size at the first 2 bytes of every record. The same + happens during the transfer of object files from VMS to Unix, + at least with UCX, the DEC implementation of TCP/IP. - The vms format repeats the length at bytes 2 & 3 of every record. + The VMS format repeats the size at bytes 2 & 3 of every record. On the first call (file_format == FF_UNKNOWN) we check if the first and the third byte pair (!) of the record match. - If they do it's an object file in an unix environment or with - wrong attributes (FF_FOREIGN), else we should be in a vms + If they do it's an object file in an Unix environment or with + wrong attributes (FF_FOREIGN), else we should be in a VMS environment where read() returns the record size (FF_NATIVE). - reading is always done in 2 steps. - first just the record header is read and the length extracted - by get_header_values - then the read buffer is adjusted and the remaining bytes are - read in. + Reading is always done in 2 steps: + 1. first just the record header is read and the size extracted, + 2. then the read buffer is adjusted and the remaining bytes are + read in. + + All file I/O is done on even file positions. */ + +#define VMS_OBJECT_ADJUSTMENT 2 + +static void +maybe_adjust_record_pointer_for_object (bfd *abfd) +{ + /* Set the file format once for all on the first invocation. */ + if (PRIV (file_format) == FF_UNKNOWN) + { + if (PRIV (vms_rec)[0] == PRIV (vms_rec)[4] + && PRIV (vms_rec)[1] == PRIV (vms_rec)[5]) + PRIV (file_format) = FF_FOREIGN; + else + PRIV (file_format) = FF_NATIVE; + } + + /* The adjustment is needed only in an Unix environment. */ + if (PRIV (file_format) == FF_FOREIGN) + PRIV (vms_rec) += VMS_OBJECT_ADJUSTMENT; +} - all file i/o is always done on even file positions */ +/* Get first record from file and return the file type. */ int -_bfd_vms_get_record (abfd) - bfd *abfd; +_bfd_vms_get_first_record (bfd *abfd) { - int test_len, test_start, remaining; - unsigned char *vms_buf; + unsigned int test_len; #if VMS_DEBUG - vms_debug (8, "_bfd_vms_get_record\n"); + vms_debug (8, "_bfd_vms_get_first_record\n"); #endif - /* minimum is 6 bytes on Alpha - (2 bytes length, 2 bytes record id, 2 bytes length repeated) - - on VAX there's no length information in the record - so start with OBJ_S_C_MAXRECSIZ */ + if (PRIV (is_vax)) + test_len = 0; + else + /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id, + 2 bytes size repeated) and 12 bytes for images (4 bytes major id, + 4 bytes minor id, 4 bytes length). */ + test_len = 12; - if (PRIV(buf_size) == 0) + /* Size the main buffer. */ + if (PRIV (buf_size) == 0) { - if (PRIV(is_vax)) - { - PRIV(vms_buf) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ); - PRIV(buf_size) = OBJ_S_C_MAXRECSIZ; - PRIV(file_format) = FF_VAX; - } - else - PRIV(vms_buf) = (unsigned char *) malloc (6); + /* On VAX there's no size information in the record, so + start with OBJ_S_C_MAXRECSIZ. */ + bfd_size_type amt = (test_len ? test_len : OBJ_S_C_MAXRECSIZ); + PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt); + PRIV (buf_size) = amt; } - vms_buf = PRIV(vms_buf); + /* Initialize the record pointer. */ + PRIV (vms_rec) = PRIV (vms_buf); - if (vms_buf == 0) + /* We only support modules on VAX. */ + if (PRIV (is_vax)) { - bfd_set_error (bfd_error_no_memory); - return -1; + if (vms_get_remaining_object_record (abfd, test_len) <= 0) + return FT_UNKNOWN; + +#if VMS_DEBUG + vms_debug (2, "file type is VAX module\n"); +#endif + + return FT_MODULE; } - switch (PRIV(file_format)) + if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len) { - case FF_UNKNOWN: - case FF_FOREIGN: - test_len = 6; /* probe 6 bytes */ - test_start = 2; /* where the record starts */ - break; - - case FF_NATIVE: - test_len = 4; - test_start = 0; - break; - - default: - case FF_VAX: - test_len = 0; - test_start = 0; - break; + bfd_set_error (bfd_error_file_truncated); + return FT_UNKNOWN; } - /* skip odd alignment byte */ - - if (bfd_tell (abfd) & 1) + /* Is it an image? */ + if ((bfd_getl32 (PRIV (vms_rec)) == EIHD_S_K_MAJORID) + && (bfd_getl32 (PRIV (vms_rec) + 4) == EIHD_S_K_MINORID)) { - if (bfd_read (PRIV(vms_buf), 1, 1, abfd) != 1) - { - bfd_set_error (bfd_error_file_truncated); - return 0; - } + if (vms_get_remaining_image_record (abfd, test_len) <= 0) + return FT_UNKNOWN; + +#if VMS_DEBUG + vms_debug (2, "file type is image\n"); +#endif + + return FT_IMAGE; } - /* read the record header on Alpha. */ + /* Assume it's a module and adjust record pointer if necessary. */ + maybe_adjust_record_pointer_for_object (abfd); - if ((test_len != 0) - && (bfd_read (PRIV(vms_buf), 1, test_len, abfd) - != (bfd_size_type) test_len)) + /* But is it really a module? */ + if (bfd_getl16 (PRIV (vms_rec)) <= EOBJ_S_C_MAXRECTYP + && bfd_getl16 (PRIV (vms_rec) + 2) <= EOBJ_S_C_MAXRECSIZ) { - bfd_set_error (bfd_error_file_truncated); - return 0; + if (vms_get_remaining_object_record (abfd, test_len) <= 0) + return FT_UNKNOWN; + +#if VMS_DEBUG + vms_debug (2, "file type is module\n"); +#endif + + return FT_MODULE; } - /* check file format on first call */ +#if VMS_DEBUG + vms_debug (2, "file type is unknown\n"); +#endif + + return FT_UNKNOWN; +} + +/* Implement step #1 of the object record reading procedure. + Return the record type or -1 on failure. */ + +int +_bfd_vms_get_object_record (bfd *abfd) +{ + unsigned int test_len; + int type; + +#if VMS_DEBUG + vms_debug (8, "_bfd_vms_get_obj_record\n"); +#endif - if (PRIV(file_format) == FF_UNKNOWN) - { /* record length repeats ? */ - if ( (vms_buf[0] == vms_buf[4]) - && (vms_buf[1] == vms_buf[5])) + if (PRIV (is_vax)) + test_len = 0; + else + { + /* See _bfd_vms_get_first_record. */ + test_len = 6; + + /* Skip odd alignment byte. */ + if (bfd_tell (abfd) & 1) { - PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */ - test_start = 2; + if (bfd_bread (PRIV (vms_buf), 1, abfd) != 1) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } } - else + + /* Read the record header */ + if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len) { - PRIV(file_format) = FF_NATIVE; /* N: native environment */ - test_start = 0; + bfd_set_error (bfd_error_file_truncated); + return -1; } + + /* Reset the record pointer. */ + PRIV (vms_rec) = PRIV (vms_buf); + maybe_adjust_record_pointer_for_object (abfd); } - if (PRIV(is_vax)) + if (vms_get_remaining_object_record (abfd, test_len) <= 0) + return -1; + + if (PRIV (is_vax)) + type = PRIV (vms_rec) [0]; + else + type = bfd_getl16 (PRIV (vms_rec)); + +#if VMS_DEBUG + vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n", + PRIV (vms_rec), PRIV (rec_size), type); +#endif + + return type; +} + +/* Implement step #2 of the object record reading procedure. + Return the size of the record or 0 on failure. */ + +static int +vms_get_remaining_object_record (bfd *abfd, int read_so_far) +{ +#if VMS_DEBUG + vms_debug (8, "vms_get_remaining_obj_record\n"); +#endif + + if (PRIV (is_vax)) { - PRIV(rec_length) = bfd_read (vms_buf, 1, PRIV(buf_size), abfd); - if (PRIV(rec_length) <= 0) + if (read_so_far != 0) + abort (); + + PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd); + + if (PRIV (rec_size) <= 0) { bfd_set_error (bfd_error_file_truncated); return 0; } - PRIV(vms_rec) = vms_buf; + + /* Reset the record pointer. */ + PRIV (vms_rec) = PRIV (vms_buf); } - else /* Alpha */ + else { - /* extract vms record length */ + unsigned int to_read; - _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL, - &PRIV(rec_length)); + /* Extract record size. */ + PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2); - if (PRIV(rec_length) <= 0) + if (PRIV (rec_size) <= 0) { bfd_set_error (bfd_error_file_truncated); return 0; } - /* that's what the linker manual says */ - - if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ) + /* That's what the linker manual says. */ + if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ) { bfd_set_error (bfd_error_file_truncated); return 0; } - /* adjust the buffer */ + /* Take into account object adjustment. */ + to_read = PRIV (rec_size); + if (PRIV (file_format) == FF_FOREIGN) + to_read += VMS_OBJECT_ADJUSTMENT; - if (PRIV(rec_length) > PRIV(buf_size)) + /* Adjust the buffer. */ + if (to_read > PRIV (buf_size)) { - PRIV(vms_buf) = (unsigned char *) realloc (vms_buf, PRIV(rec_length)); - vms_buf = PRIV(vms_buf); - if (vms_buf == 0) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - PRIV(buf_size) = PRIV(rec_length); + PRIV (vms_buf) + = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read); + if (PRIV (vms_buf) == NULL) + return 0; + PRIV (buf_size) = to_read; } - /* read the remaining record */ - - remaining = PRIV(rec_length) - test_len + test_start; + /* Read the remaining record. */ + to_read -= read_so_far; #if VMS_DEBUG - vms_debug (10, "bfd_read remaining %d\n", remaining); + vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read); #endif - if (bfd_read (vms_buf + test_len, 1, remaining, abfd) != - (bfd_size_type) remaining) + + if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read) { bfd_set_error (bfd_error_file_truncated); return 0; } - PRIV(vms_rec) = vms_buf + test_start; + + /* Reset the record pointer. */ + PRIV (vms_rec) = PRIV (vms_buf); + maybe_adjust_record_pointer_for_object (abfd); } #if VMS_DEBUG - vms_debug (11, "bfd_read rec_length %d\n", PRIV(rec_length)); + vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size)); #endif - return PRIV(rec_length); + return PRIV (rec_size); } -/* get next vms record from file - update vms_rec and rec_length to new (remaining) values */ +/* Implement step #2 of the record reading procedure for images. + Return the size of the record or 0 on failure. */ -int -_bfd_vms_next_record (abfd) - bfd *abfd; +static int +vms_get_remaining_image_record (bfd *abfd, int read_so_far) { -#if VMS_DEBUG - vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n", - PRIV(rec_length), PRIV(rec_size)); -#endif + unsigned int to_read; + int remaining; - if (PRIV(rec_length) > 0) - { - PRIV(vms_rec) += PRIV(rec_size); - } - else + /* Extract record size. */ + PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE); + + if (PRIV (rec_size) > PRIV (buf_size)) { - if (_bfd_vms_get_record (abfd) <= 0) - return -1; - } + PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size)); - if (!PRIV(vms_rec)) - return -1; + if (PRIV (vms_buf) == NULL) + { + bfd_set_error (bfd_error_no_memory); + return 0; + } - if (PRIV(is_vax)) - { - PRIV(rec_type) = *(PRIV(vms_rec)); - PRIV(rec_size) = PRIV(rec_length); + PRIV (buf_size) = PRIV (rec_size); } - else + + /* Read the remaining record. */ + remaining = PRIV (rec_size) - read_so_far; + to_read = MIN (VMS_BLOCK_SIZE - read_so_far, remaining); + + while (remaining > 0) { - _bfd_vms_get_header_values (abfd, PRIV(vms_rec), &PRIV(rec_type), - &PRIV(rec_size)); + if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read) + { + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + read_so_far += to_read; + remaining -= to_read; + + /* Eat trailing 0xff's. */ + if (remaining > 0) + while (PRIV (vms_buf) [read_so_far - 1] == 0xff) + read_so_far--; + + to_read = MIN (VMS_BLOCK_SIZE, remaining); } - PRIV(rec_length) -= PRIV(rec_size); -#if VMS_DEBUG - vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n", - PRIV(vms_rec), PRIV(rec_size), PRIV(rec_length), - PRIV(rec_type)); -#endif + /* Reset the record pointer. */ + PRIV (vms_rec) = PRIV (vms_buf); - return PRIV(rec_type); + return PRIV (rec_size); } - -/* Copy sized string (string with fixed length) to new allocated area - size is string length (size of record) */ +/* Copy sized string (string with fixed size) to new allocated area + size is string size (size of record) */ char * -_bfd_vms_save_sized_string (str, size) - unsigned char *str; - int size; +_bfd_vms_save_sized_string (unsigned char *str, int size) { - char *newstr = bfd_malloc (size + 1); + char *newstr = bfd_malloc ((bfd_size_type) size + 1); if (newstr == NULL) - return 0; - strncpy (newstr, (char *)str, size); + return NULL; + strncpy (newstr, (char *) str, (size_t) size); newstr[size] = 0; return newstr; } -/* Copy counted string (string with length at first byte) to new allocated area - ptr points to length byte on entry */ +/* Copy counted string (string with size at first byte) to new allocated area + ptr points to size byte on entry */ char * -_bfd_vms_save_counted_string (ptr) - unsigned char *ptr; +_bfd_vms_save_counted_string (unsigned char *ptr) { int len = *ptr++; return _bfd_vms_save_sized_string (ptr, len); } - -/* stack routines for vms ETIR commands */ +/* Stack routines for vms ETIR commands. */ -/* Push value and section index */ +/* Push value and section index. */ void -_bfd_vms_push (abfd, val, psect) - bfd *abfd; - uquad val; - int psect; +_bfd_vms_push (bfd * abfd, uquad val, int psect) { static int last_psect; #if VMS_DEBUG - vms_debug (4, "\n", val, psect, PRIV(stackptr)); + vms_debug (4, "\n", val, psect, PRIV (stackptr)); #endif if (psect >= 0) last_psect = psect; - PRIV(stack[PRIV(stackptr)]).value = val; - PRIV(stack[PRIV(stackptr)]).psect = last_psect; - PRIV(stackptr)++; - if (PRIV(stackptr) >= STACKSIZE) + PRIV (stack[PRIV (stackptr)]).value = val; + PRIV (stack[PRIV (stackptr)]).psect = last_psect; + PRIV (stackptr)++; + if (PRIV (stackptr) >= STACKSIZE) { bfd_set_error (bfd_error_bad_value); - (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV(stackptr)); + (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); exit (1); } - return; } -/* Pop value and section index */ +/* Pop value and section index. */ uquad -_bfd_vms_pop (abfd, psect) - bfd *abfd; - int *psect; +_bfd_vms_pop (bfd * abfd, int *psect) { uquad value; - if (PRIV(stackptr) == 0) + if (PRIV (stackptr) == 0) { bfd_set_error (bfd_error_bad_value); (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop")); exit (1); } - PRIV(stackptr)--; - value = PRIV(stack[PRIV(stackptr)]).value; - if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0)) - *psect = PRIV(stack[PRIV(stackptr)]).psect; + PRIV (stackptr)--; + value = PRIV (stack[PRIV (stackptr)]).value; + if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0)) + *psect = PRIV (stack[PRIV (stackptr)]).psect; #if VMS_DEBUG - vms_debug (4, "\n", value, PRIV(stack[PRIV(stackptr)]).psect); + vms_debug (4, "\n", value, PRIV (stack[PRIV (stackptr)]).psect); #endif return value; } - - -/* object file output functions */ - -/* GAS tends to write sections in little chunks (bfd_set_section_contents) - which we can't use directly. So we save the little chunks in linked - lists (one per section) and write them later. */ - -/* Add a new vms_section structure to vms_section_table - - forward chaining - */ - -static vms_section * -add_new_contents (abfd, section) - bfd *abfd; - sec_ptr section; -{ - vms_section *sptr, *newptr; - - sptr = PRIV(vms_section_table)[section->index]; - if (sptr != NULL) - return sptr; - - newptr = (vms_section *) bfd_malloc (sizeof (vms_section)); - if (newptr == (vms_section *) NULL) - return NULL; - newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size); - if (newptr->contents == (unsigned char *)NULL) - return NULL; - newptr->offset = 0; - newptr->size = section->_raw_size; - newptr->next = 0; - PRIV(vms_section_table)[section->index] = newptr; - return newptr; -} - -/* Save section data & offset to an vms_section structure - vms_section_table[] holds the vms_section chain */ - -boolean -_bfd_save_vms_section (abfd, section, data, offset, count) - bfd *abfd; - sec_ptr section; - PTR data; - file_ptr offset; - bfd_size_type count; -{ - vms_section *sptr; - - if (section->index >= VMS_SECTION_COUNT) - { - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - if (count == (bfd_size_type)0) - return true; - sptr = add_new_contents (abfd, section); - if (sptr == NULL) - return false; - memcpy (sptr->contents + offset, data, (size_t) count); - - return true; -} - -/* Get vms_section pointer to saved contents for section # index */ - -vms_section * -_bfd_get_vms_section (abfd, index) - bfd *abfd; - int index; -{ - if (index >= VMS_SECTION_COUNT) - { - bfd_set_error (bfd_error_nonrepresentable_section); - return NULL; - } - return PRIV(vms_section_table)[index]; -} - -/* Object output routines */ +/* Object output routines. */ /* Begin new record or record header write 2 bytes rectype write 2 bytes record length (filled in at flush) - write 2 bytes header type (ommitted if rechead == -1) */ + write 2 bytes header type (ommitted if rechead == -1). */ void -_bfd_vms_output_begin (abfd, rectype, rechead) - bfd *abfd; - int rectype; - int rechead; +_bfd_vms_output_begin (bfd * abfd, int rectype, int rechead) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype, + vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype, rechead); #endif - _bfd_vms_output_short (abfd,rectype); + _bfd_vms_output_short (abfd, (unsigned int) rectype); - /* save current output position to fill in lenght later */ + /* Save current output position to fill in length later. */ - if (PRIV(push_level) > 0) - PRIV(length_pos) = PRIV(output_size); + if (PRIV (push_level) > 0) + PRIV (length_pos) = PRIV (output_size); #if VMS_DEBUG vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n", - PRIV(length_pos)); + PRIV (length_pos)); #endif - _bfd_vms_output_short (abfd,0); /* placeholder for length */ + /* Placeholder for length. */ + _bfd_vms_output_short (abfd, 0); if (rechead != -1) - _bfd_vms_output_short (abfd,rechead); - - return; + _bfd_vms_output_short (abfd, (unsigned int) rechead); } -/* Set record/subrecord alignment */ +/* Set record/subrecord alignment. */ void -_bfd_vms_output_alignment (abfd, alignto) - bfd *abfd; - int alignto; +_bfd_vms_output_alignment (bfd * abfd, int alignto) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto); + vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto); #endif - PRIV(output_alignment) = alignto; - return; + PRIV (output_alignment) = alignto; } -/* Prepare for subrecord fields */ +/* Prepare for subrecord fields. */ void -_bfd_vms_output_push (abfd) - bfd *abfd; +_bfd_vms_output_push (bfd * abfd) { #if VMS_DEBUG - vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV(output_size)); + vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size)); #endif - PRIV(push_level)++; - PRIV(pushed_size) = PRIV(output_size); - return; + PRIV (push_level)++; + PRIV (pushed_size) = PRIV (output_size); } -/* End of subrecord fields */ +/* End of subrecord fields. */ void -_bfd_vms_output_pop (abfd) - bfd *abfd; +_bfd_vms_output_pop (bfd * abfd) { #if VMS_DEBUG - vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV(pushed_size)); + vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size)); #endif _bfd_vms_output_flush (abfd); - PRIV(length_pos) = 2; + PRIV (length_pos) = 2; #if VMS_DEBUG - vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV(length_pos)); + vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos)); #endif - PRIV(pushed_size) = 0; - PRIV(push_level)--; - return; + PRIV (pushed_size) = 0; + PRIV (push_level)--; } -/* Flush unwritten output, ends current record */ +/* Flush unwritten output, ends current record. */ void -_bfd_vms_output_flush (abfd) - bfd *abfd; +_bfd_vms_output_flush (bfd * abfd) { - int real_size = PRIV(output_size); + int real_size = PRIV (output_size); int aligncount; int length; #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n", - real_size, PRIV(pushed_size), PRIV(length_pos)); + vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n", + real_size, PRIV (pushed_size), PRIV (length_pos)); #endif - if (PRIV(push_level) > 0) - length = real_size - PRIV(pushed_size); + if (PRIV (push_level) > 0) + length = real_size - PRIV (pushed_size); else length = real_size; if (length == 0) return; - aligncount = (PRIV(output_alignment) - - (length % PRIV(output_alignment))) % PRIV(output_alignment); + aligncount = (PRIV (output_alignment) + - (length % PRIV (output_alignment))) % PRIV (output_alignment); #if VMS_DEBUG vms_debug (6, "align: adding %d bytes\n", aligncount); @@ -768,145 +724,118 @@ _bfd_vms_output_flush (abfd) while (aligncount-- > 0) { - PRIV(output_buf)[real_size++] = 0; -#if 0 - /* this is why I *love* vms: inconsistency :-} - alignment is added to the subrecord length - but not to the record length */ - if (PRIV(push_level) > 0) -#endif - length++; + PRIV (output_buf)[real_size++] = 0; + length++; } - /* put length to buffer */ - PRIV(output_size) = PRIV(length_pos); - _bfd_vms_output_short (abfd, (unsigned int)length); + /* Put length to buffer. */ + PRIV (output_size) = PRIV (length_pos); + _bfd_vms_output_short (abfd, (unsigned int) length); - if (PRIV(push_level) == 0) + if (PRIV (push_level) == 0) { -#ifndef VMS - /* write length first, see FF_FOREIGN in the input routines */ - fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream); -#endif - fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream); - - PRIV(output_size) = 0; + /* File is open in undefined (UDF) format on VMS, but ultimately will be + converted to variable length (VAR) format. VAR format has a length + word first which must be explicitly output in UDF format. */ + bfd_bwrite (PRIV (output_buf) + 2, 2, abfd); + bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd); + PRIV (output_size) = 0; } else { - PRIV(output_size) = real_size; - PRIV(pushed_size) = PRIV(output_size); + PRIV (output_size) = real_size; + PRIV (pushed_size) = PRIV (output_size); } - - return; } -/* End record output */ +/* End record output. */ void -_bfd_vms_output_end (abfd) - bfd *abfd; +_bfd_vms_output_end (bfd * abfd) { #if VMS_DEBUG vms_debug (6, "_bfd_vms_output_end\n"); #endif _bfd_vms_output_flush (abfd); - - return; } -/* check remaining buffer size +/* Check remaining buffer size - return what's left. */ + Return what's left. */ int -_bfd_vms_output_check (abfd, size) - bfd *abfd; - int size; +_bfd_vms_output_check (bfd * abfd, int size) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_check(%d)\n", size); + vms_debug (6, "_bfd_vms_output_check (%d)\n", size); #endif - return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT)); + return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT)); } -/* Output byte (8 bit) value */ +/* Output byte (8 bit) value. */ void -_bfd_vms_output_byte (abfd, value) - bfd *abfd; - unsigned int value; +_bfd_vms_output_byte (bfd * abfd, unsigned int value) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value); + vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value); #endif - bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size)); - PRIV(output_size) += 1; - return; + bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size)); + PRIV (output_size) += 1; } -/* Output short (16 bit) value */ +/* Output short (16 bit) value. */ void -_bfd_vms_output_short (abfd, value) - bfd *abfd; - unsigned int value; +_bfd_vms_output_short (bfd * abfd, unsigned int value) { #if VMS_DEBUG vms_debug (6, "_bfd_vms_output_short (%04x)\n", value); #endif - bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size)); - PRIV(output_size) += 2; - return; + bfd_put_16 (abfd, (bfd_vma) value & 0xffff, + PRIV (output_buf) + PRIV (output_size)); + PRIV (output_size) += 2; } -/* Output long (32 bit) value */ +/* Output long (32 bit) value. */ void -_bfd_vms_output_long (abfd, value) - bfd *abfd; - unsigned long value; +_bfd_vms_output_long (bfd * abfd, unsigned long value) { #if VMS_DEBUG vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value); #endif - bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size)); - PRIV(output_size) += 4; - return; + bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size)); + PRIV (output_size) += 4; } -/* Output quad (64 bit) value */ +/* Output quad (64 bit) value. */ void -_bfd_vms_output_quad (abfd, value) - bfd *abfd; - uquad value; +_bfd_vms_output_quad (bfd * abfd, uquad value) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value); + vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value); #endif - bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size)); - PRIV(output_size) += 8; - return; + bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size)); + PRIV (output_size) += 8; } -/* Output c-string as counted string */ +/* Output c-string as counted string. */ void -_bfd_vms_output_counted (abfd, value) - bfd *abfd; - char *value; +_bfd_vms_output_counted (bfd * abfd, char *value) { -int len; + int len; #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_counted(%s)\n", value); + vms_debug (6, "_bfd_vms_output_counted (%s)\n", value); #endif len = strlen (value); @@ -920,61 +849,54 @@ int len; (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes")); return; } - _bfd_vms_output_byte (abfd, len & 0xff); - _bfd_vms_output_dump (abfd, (unsigned char *)value, len); + _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff); + _bfd_vms_output_dump (abfd, (unsigned char *) value, len); } -/* Output character area */ +/* Output character area. */ void -_bfd_vms_output_dump (abfd, data, length) - bfd *abfd; - unsigned char *data; - int length; +_bfd_vms_output_dump (bfd * abfd, + unsigned char *data, + int length) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_dump(%d)\n", length); + vms_debug (6, "_bfd_vms_output_dump (%d)\n", length); #endif if (length == 0) return; - memcpy (PRIV(output_buf) + PRIV(output_size), data, length); - PRIV(output_size) += length; - - return; + memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length); + PRIV (output_size) += length; } -/* Output count bytes of value */ +/* Output count bytes of value. */ void -_bfd_vms_output_fill (abfd, value, count) - bfd *abfd; - int value; - int count; +_bfd_vms_output_fill (bfd * abfd, + int value, + int count) { #if VMS_DEBUG - vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count); + vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count); #endif if (count == 0) return; - memset (PRIV(output_buf) + PRIV(output_size), value, count); - PRIV(output_size) += count; - - return; + memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count); + PRIV (output_size) += count; } -/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/ +/* This hash routine borrowed from GNU-EMACS, and strengthened slightly. ERY. */ static int -hash_string (ptr) - const char *ptr; +hash_string (const char *ptr) { - register const unsigned char *p = (unsigned char *) ptr; - register const unsigned char *end = p + strlen (ptr); - register unsigned char c; - register int hash = 0; + const unsigned char *p = (unsigned char *) ptr; + const unsigned char *end = p + strlen (ptr); + unsigned char c; + int hash = 0; while (p != end) { @@ -987,12 +909,9 @@ hash_string (ptr) /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */ char * -_bfd_vms_length_hash_symbol (abfd, in, maxlen) - bfd *abfd; - const char *in; - int maxlen; +_bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen) { - long int result; + unsigned long result; int in_len; char *new_name; const char *old_name; @@ -1001,16 +920,16 @@ _bfd_vms_length_hash_symbol (abfd, in, maxlen) char *out = outbuf; #if VMS_DEBUG - vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in); + vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in); #endif if (maxlen > EOBJ_S_C_SYMSIZ) maxlen = EOBJ_S_C_SYMSIZ; - new_name = out; /* save this for later. */ + /* Save this for later. */ + new_name = out; /* We may need to truncate the symbol, save the hash for later. */ - in_len = strlen (in); result = (in_len > maxlen) ? hash_string (in) : 0; @@ -1018,36 +937,33 @@ _bfd_vms_length_hash_symbol (abfd, in, maxlen) old_name = in; /* Do the length checking. */ - if (in_len <= maxlen) - { - i = in_len; - } + i = in_len; else { - if (PRIV(flag_hash_long_names)) + if (PRIV (flag_hash_long_names)) i = maxlen-9; else i = maxlen; } - strncpy (out, in, i); + strncpy (out, in, (size_t) i); in += i; out += i; if ((in_len > maxlen) - && PRIV(flag_hash_long_names)) + && PRIV (flag_hash_long_names)) sprintf (out, "_%08lx", result); else *out = 0; #if VMS_DEBUG - vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf); + vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf); #endif if (in_len > maxlen - && PRIV(flag_hash_long_names) - && PRIV(flag_show_after_trunc)) + && PRIV (flag_hash_long_names) + && PRIV (flag_show_after_trunc)) printf (_("Symbol %s replaced by %s\n"), old_name, new_name); return outbuf; @@ -1056,9 +972,7 @@ _bfd_vms_length_hash_symbol (abfd, in, maxlen) /* Allocate and initialize a new symbol. */ static asymbol * -new_symbol (abfd, name) - bfd *abfd; - char *name; +new_symbol (bfd * abfd, char *name) { asymbol *symbol; @@ -1066,11 +980,11 @@ new_symbol (abfd, name) _bfd_vms_debug (7, "new_symbol %s\n", name); #endif - symbol = _bfd_vms_make_empty_symbol (abfd); + symbol = bfd_make_empty_symbol (abfd); if (symbol == 0) return symbol; symbol->name = name; - symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); + symbol->section = (asection *)(unsigned long)-1; return symbol; } @@ -1078,9 +992,7 @@ new_symbol (abfd, name) /* Allocate and enter a new private symbol. */ vms_symbol_entry * -_bfd_vms_enter_symbol (abfd, name) - bfd *abfd; - char *name; +_bfd_vms_enter_symbol (bfd * abfd, char *name) { vms_symbol_entry *entry; @@ -1089,13 +1001,14 @@ _bfd_vms_enter_symbol (abfd, name) #endif entry = (vms_symbol_entry *) - bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false); + bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE); if (entry == 0) { #if VMS_DEBUG _bfd_vms_debug (8, "creating hash entry for %s\n", name); #endif - entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, true, false); + entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table), + name, TRUE, FALSE); if (entry != 0) { asymbol *symbol; @@ -1103,7 +1016,7 @@ _bfd_vms_enter_symbol (abfd, name) if (symbol != 0) { entry->symbol = symbol; - PRIV(gsd_sym_count)++; + PRIV (gsd_sym_count)++; abfd->symcount++; } else