X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Fvms-alpha.c;h=1129c98f0e2cb894c3f8dd029d4050289098ca78;hb=e330d4c033eab2e0e7206a29d6c11a9a59fd205b;hp=69822a2ce6a4c379e3c2b5c555846de0aa84a695;hpb=cb7f4b298e5e0a3ab4fb6b13aa89e970478597bc;p=binutils-gdb.git diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index 69822a2ce6a..1129c98f0e2 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -1,5 +1,5 @@ /* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files. - Copyright (C) 1996-2019 Free Software Foundation, Inc. + Copyright (C) 1996-2022 Free Software Foundation, Inc. Initial version written by Klaus Kaempf (kkaempf@rmi.de) Major rewrite by Adacore. @@ -34,6 +34,7 @@ */ #include "sysdep.h" +#include #include "bfd.h" #include "bfdlink.h" #include "libbfd.h" @@ -71,6 +72,9 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif /* The r_type field in a reloc is one of the following values. */ #define ALPHA_R_IGNORE 0 @@ -151,7 +155,7 @@ struct eom_struct { unsigned int eom_l_total_lps; unsigned short eom_w_comcod; - bfd_boolean eom_has_transfer; + bool eom_has_transfer; unsigned char eom_b_tfrflg; unsigned int eom_l_psindx; unsigned int eom_l_tfradr; @@ -263,7 +267,7 @@ struct module struct vms_private_data_struct { /* If true, relocs have been read. */ - bfd_boolean reloc_done; + bool reloc_done; /* Record input buffer. */ struct vms_rec_rd recrd; @@ -367,15 +371,15 @@ struct vms_section_data_struct struct vms_private_data_struct *bfd_vms_get_data (bfd *); static int vms_get_remaining_object_record (bfd *, unsigned int); -static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd); -static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *); -static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *); -static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *, +static bool _bfd_vms_slurp_object_records (bfd * abfd); +static bool alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *); +static bool alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *); +static bool alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *, bfd_vma); -static void alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int, +static bool alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int, bfd_vma); -static void alpha_vms_add_lw_reloc (struct bfd_link_info *); -static void alpha_vms_add_qw_reloc (struct bfd_link_info *); +static bool alpha_vms_add_lw_reloc (struct bfd_link_info *); +static bool alpha_vms_add_qw_reloc (struct bfd_link_info *); struct vector_type { @@ -401,17 +405,12 @@ struct vector_type /* Be sure there is room for a new element. */ -static void vector_grow1 (struct vector_type *vec, size_t elsz); +static void *vector_grow1 (struct vector_type *vec, size_t elsz); /* Allocate room for a new element and return its address. */ #define VEC_APPEND(VEC, TYPE) \ - (vector_grow1 (&VEC, sizeof (TYPE)), &VEC_EL(VEC, TYPE, (VEC).nbr_el++)) - -/* Append an element. */ - -#define VEC_APPEND_EL(VEC, TYPE, EL) \ - (*(VEC_APPEND (VEC, TYPE)) = EL) + ((TYPE *) vector_grow1 (&VEC, sizeof (TYPE))) struct alpha_vms_vma_ref { @@ -422,7 +421,7 @@ struct alpha_vms_vma_ref struct alpha_vms_shlib_el { bfd *abfd; - bfd_boolean has_fixups; + bool has_fixups; struct vector_type lp; /* Vector of bfd_vma. */ struct vector_type ca; /* Vector of bfd_vma. */ @@ -463,7 +462,7 @@ struct alpha_vms_link_hash_entry /* Read & process EIHD record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset, unsigned int *eihs_offset) { @@ -478,7 +477,7 @@ _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset, { _bfd_error_handler (_("corrupt EIHD record - size is too small")); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } size = bfd_getl32 (eihd->size); @@ -503,14 +502,15 @@ _bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset, vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n", size, imgtype, (unsigned long)symvva, *eisd_offset, *eihs_offset)); + (void) size; - return TRUE; + return true; } /* Read & process EISD record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) { int section_count = 0; @@ -529,12 +529,12 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) asection *section; flagword bfd_flags; - /* PR 17512: file: 3d9e9fe9. - 12 is the offset of the eisdsize field from the start of the record (8) - plus the size of the eisdsize field (4). */ - if (offset >= PRIV (recrd.rec_size) - 12) - return FALSE; - eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset); + /* PR 17512: file: 3d9e9fe9. */ + if (offset > PRIV (recrd.rec_size) + || (PRIV (recrd.rec_size) - offset + < offsetof (struct vms_eisd, eisdsize) + 4)) + return false; + eisd = (struct vms_eisd *) (PRIV (recrd.rec) + offset); rec_size = bfd_getl32 (eisd->eisdsize); if (rec_size == 0) break; @@ -547,12 +547,11 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) } /* Make sure that there is enough data present in the record. */ - /* FIXME: Should we use sizeof (struct vms_eisd) rather than just 32 here ? */ - if (rec_size < 32) - return FALSE; + if (rec_size < offsetof (struct vms_eisd, type) + 1) + return false; /* Make sure that the record is not too big either. */ - if (offset + rec_size >= PRIV (recrd.rec_size)) - return FALSE; + if (rec_size > PRIV (recrd.rec_size) - offset) + return false; offset += rec_size; @@ -592,13 +591,16 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) if (flags & EISD__M_GBL) { - if (rec_size < offsetof (struct vms_eisd, gblnam)) - return FALSE; + if (rec_size <= offsetof (struct vms_eisd, gblnam)) + return false; else if (rec_size < sizeof (struct vms_eisd)) - name = _bfd_vms_save_counted_string (eisd->gblnam, + name = _bfd_vms_save_counted_string (abfd, eisd->gblnam, rec_size - offsetof (struct vms_eisd, gblnam)); else - name = _bfd_vms_save_counted_string (eisd->gblnam, EISD__K_GBLNAMLEN); + name = _bfd_vms_save_counted_string (abfd, eisd->gblnam, + EISD__K_GBLNAMLEN); + if (name == NULL || name[0] == 0) + return false; bfd_flags |= SEC_COFF_SHARED_LIBRARY; bfd_flags &= ~(SEC_ALLOC | SEC_LOAD); } @@ -610,7 +612,9 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) { const char *pfx; - name = (char*) bfd_alloc (abfd, 32); + name = (char *) bfd_alloc (abfd, 32); + if (name == NULL) + return false; if (flags & EISD__M_DZRO) pfx = "BSS"; else if (flags & EISD__M_EXE) @@ -626,23 +630,23 @@ _bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset) section = bfd_make_section (abfd, name); if (!section) - return FALSE; + return false; section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : 0; section->size = size; section->vma = vaddr; - if (!bfd_set_section_flags (abfd, section, bfd_flags)) - return FALSE; + if (!bfd_set_section_flags (section, bfd_flags)) + return false; } - return TRUE; + return true; } /* Read & process EIHS record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) { unsigned char *p = PRIV (recrd.rec) + offset; @@ -660,7 +664,7 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) _bfd_error_handler (_("unable to read EIHS record at offset %#x"), offset); bfd_set_error (bfd_error_file_truncated); - return FALSE; + return false; } gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN); @@ -682,13 +686,13 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) section = bfd_make_section (abfd, "$DST$"); if (!section) - return FALSE; + return false; section->size = dstsize; section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1); - if (!bfd_set_section_flags (abfd, section, bfd_flags)) - return FALSE; + if (!bfd_set_section_flags (section, bfd_flags)) + return false; PRIV (dst_section) = section; abfd->flags |= (HAS_DEBUG | HAS_LINENO); @@ -700,13 +704,13 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) section = bfd_make_section (abfd, "$DMT$"); if (!section) - return FALSE; + return false; section->size = dmtbytes; section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1); - if (!bfd_set_section_flags (abfd, section, bfd_flags)) - return FALSE; + if (!bfd_set_section_flags (section, bfd_flags)) + return false; } if (gstvbn) @@ -714,16 +718,16 @@ _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset) if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET)) { bfd_set_error (bfd_error_file_truncated); - return FALSE; + return false; } if (!_bfd_vms_slurp_object_records (abfd)) - return FALSE; + return false; abfd->flags |= HAS_SYMS; } - return TRUE; + return true; } /* Object file reading. */ @@ -861,7 +865,7 @@ vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far) if (to_read > PRIV (recrd.buf_size)) { PRIV (recrd.buf) - = (unsigned char *) bfd_realloc (PRIV (recrd.buf), to_read); + = (unsigned char *) bfd_realloc_or_free (PRIV (recrd.buf), to_read); if (PRIV (recrd.buf) == NULL) return 0; PRIV (recrd.buf_size) = to_read; @@ -894,7 +898,7 @@ vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far) /* Read and process emh record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_ehdr (bfd *abfd) { unsigned char *ptr; @@ -924,36 +928,39 @@ _bfd_vms_slurp_ehdr (bfd *abfd) PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16); if ((vms_rec + 20 + vms_rec[20] + 1) >= end) goto fail; - PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20, vms_rec[20]); + PRIV (hdr_data).hdr_t_name + = _bfd_vms_save_counted_string (abfd, vms_rec + 20, vms_rec[20]); ptr = vms_rec + 20 + vms_rec[20] + 1; if ((ptr + *ptr + 1) >= end) goto fail; - PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr, *ptr); + PRIV (hdr_data).hdr_t_version + = _bfd_vms_save_counted_string (abfd, ptr, *ptr); ptr += *ptr + 1; if (ptr + 17 >= end) goto fail; - PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17); + PRIV (hdr_data).hdr_t_date + = _bfd_vms_save_sized_string (abfd, ptr, 17); break; case EMH__C_LNM: if (vms_rec + PRIV (recrd.rec_size - 6) > end) goto fail; - PRIV (hdr_data).hdr_c_lnm = - _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); + PRIV (hdr_data).hdr_c_lnm + = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6)); break; case EMH__C_SRC: if (vms_rec + PRIV (recrd.rec_size - 6) > end) goto fail; - PRIV (hdr_data).hdr_c_src = - _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); + PRIV (hdr_data).hdr_c_src + = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6)); break; case EMH__C_TTL: if (vms_rec + PRIV (recrd.rec_size - 6) > end) goto fail; - PRIV (hdr_data).hdr_c_ttl = - _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6)); + PRIV (hdr_data).hdr_c_ttl + = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6)); break; case EMH__C_CPR: @@ -964,10 +971,10 @@ _bfd_vms_slurp_ehdr (bfd *abfd) default: fail: bfd_set_error (bfd_error_wrong_format); - return FALSE; + return false; } - return TRUE; + return true; } /* Typical sections for evax object files. */ @@ -1107,7 +1114,7 @@ vms_esecflag_by_name (const struct sec_flags_struct *section_flags, /* Add SYM to the symbol table of ABFD. Return FALSE in case of error. */ -static bfd_boolean +static bool add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym) { if (PRIV (gsd_sym_count) >= PRIV (max_sym_count)) @@ -1121,28 +1128,36 @@ add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym) else { PRIV (max_sym_count) *= 2; - PRIV (syms) = bfd_realloc + PRIV (syms) = bfd_realloc_or_free (PRIV (syms), (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *))); } if (PRIV (syms) == NULL) - return FALSE; + return false; } PRIV (syms)[PRIV (gsd_sym_count)++] = sym; - return TRUE; + return true; } /* Create a symbol whose name is ASCIC and add it to ABFD. Return NULL in case of error. */ static struct vms_symbol_entry * -add_symbol (bfd *abfd, const unsigned char *ascic) +add_symbol (bfd *abfd, const unsigned char *ascic, unsigned int max) { struct vms_symbol_entry *entry; - int len; + unsigned int len; len = *ascic++; + max -= 1; + if (len > max) + { + _bfd_error_handler (_("record is too small for symbol name length")); + bfd_set_error (bfd_error_bad_value); + return NULL; + } + entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len); if (entry == NULL) return NULL; @@ -1158,13 +1173,14 @@ add_symbol (bfd *abfd, const unsigned char *ascic) /* Read and process EGSD. Return FALSE on failure. */ -static bfd_boolean +static bool _bfd_vms_slurp_egsd (bfd *abfd) { int gsd_type; unsigned int gsd_size; unsigned char *vms_rec; - unsigned long base_addr; + bfd_vma base_addr; + long psindx; vms_debug2 ((2, "EGSD\n")); @@ -1173,14 +1189,14 @@ _bfd_vms_slurp_egsd (bfd *abfd) _bfd_error_handler (_("corrupt EGSD record: its size (%#x) is too small"), PRIV (recrd.rec_size)); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } PRIV (recrd.rec) += 8; /* Skip type, size, align pad. */ PRIV (recrd.rec_size) -= 8; /* Calculate base address for each section. */ - base_addr = 0L; + base_addr = 0; while (PRIV (recrd.rec_size) > 4) { @@ -1194,18 +1210,21 @@ _bfd_vms_slurp_egsd (bfd *abfd) /* PR 21615: Check for size overflow. */ if (PRIV (recrd.rec_size) < gsd_size) { - _bfd_error_handler (_("corrupt EGSD record: size (%#x) is larger than remaining space (%#x)"), - gsd_size, PRIV (recrd.rec_size)); + _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) " + "is larger than remaining space (%#x)"), + gsd_type, gsd_size, PRIV (recrd.rec_size)); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } if (gsd_size < 4) { - _bfd_error_handler (_("corrupt EGSD record: size (%#x) is too small"), - gsd_size); + too_small: + _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) " + "is too small"), + gsd_type, gsd_size); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } switch (gsd_type) @@ -1213,10 +1232,12 @@ _bfd_vms_slurp_egsd (bfd *abfd) case EGSD__C_PSC: /* Program section definition. */ { - struct vms_egps *egps = (struct vms_egps *)vms_rec; + struct vms_egps *egps = (struct vms_egps *) vms_rec; flagword new_flags, vms_flags; asection *section; + if (offsetof (struct vms_egps, flags) + 2 > gsd_size) + goto too_small; vms_flags = bfd_getl16 (egps->flags); if ((vms_flags & EGPS__V_REL) == 0) @@ -1228,22 +1249,29 @@ _bfd_vms_slurp_egsd (bfd *abfd) else { char *name; - unsigned long align_addr; + bfd_vma align_addr; + size_t left; - name = _bfd_vms_save_counted_string (&egps->namlng, gsd_size - 4); + if (offsetof (struct vms_egps, namlng) >= gsd_size) + goto too_small; + left = gsd_size - offsetof (struct vms_egps, namlng); + name = _bfd_vms_save_counted_string (abfd, &egps->namlng, left); + if (name == NULL || name[0] == 0) + return false; section = bfd_make_section (abfd, name); if (!section) - return FALSE; + return false; section->filepos = 0; section->size = bfd_getl32 (egps->alloc); - section->alignment_power = egps->align; + section->alignment_power = egps->align & 31; vms_section_data (section)->flags = vms_flags; vms_section_data (section)->no_flags = 0; - new_flags = vms_secflag_by_name (evax_section_flags, name, + new_flags = vms_secflag_by_name (evax_section_flags, + section->name, section->size > 0); if (section->size > 0) new_flags |= SEC_LOAD; @@ -1261,14 +1289,13 @@ _bfd_vms_slurp_egsd (bfd *abfd) new_flags |= SEC_CODE; new_flags &= ~SEC_DATA; } - if (!bfd_set_section_flags (abfd, section, new_flags)) - return FALSE; + if (!bfd_set_section_flags (section, new_flags)) + return false; /* Give a non-overlapping vma to non absolute sections. */ - align_addr = (1 << section->alignment_power); - if ((base_addr % align_addr) != 0) - base_addr += (align_addr - (base_addr % align_addr)); - section->vma = (bfd_vma)base_addr; + align_addr = (bfd_vma) 1 << section->alignment_power; + base_addr = (base_addr + align_addr - 1) & -align_addr; + section->vma = base_addr; base_addr += section->size; } @@ -1282,7 +1309,7 @@ _bfd_vms_slurp_egsd (bfd *abfd) PRIV (sections) = bfd_realloc_or_free (PRIV (sections), PRIV (section_max) * sizeof (asection *)); if (PRIV (sections) == NULL) - return FALSE; + return false; } PRIV (sections)[PRIV (section_count)] = section; @@ -1292,20 +1319,24 @@ _bfd_vms_slurp_egsd (bfd *abfd) case EGSD__C_SYM: { - int nameoff; + unsigned int nameoff; struct vms_symbol_entry *entry; struct vms_egsy *egsy = (struct vms_egsy *) vms_rec; flagword old_flags; + if (offsetof (struct vms_egsy, flags) + 2 > gsd_size) + goto too_small; old_flags = bfd_getl16 (egsy->flags); if (old_flags & EGSY__V_DEF) nameoff = ESDF__B_NAMLNG; else nameoff = ESRF__B_NAMLNG; - entry = add_symbol (abfd, vms_rec + nameoff); + if (nameoff >= gsd_size) + goto too_small; + entry = add_symbol (abfd, vms_rec + nameoff, gsd_size - nameoff); if (entry == NULL) - return FALSE; + return false; /* Allow only duplicate reference. */ if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF)) @@ -1320,21 +1351,22 @@ _bfd_vms_slurp_egsd (bfd *abfd) if (old_flags & EGSY__V_DEF) { - struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; - long psindx; + struct vms_esdf *esdf = (struct vms_esdf *) vms_rec; entry->value = bfd_getl64 (esdf->value); if (PRIV (sections) == NULL) - return FALSE; + return false; psindx = bfd_getl32 (esdf->psindx); /* PR 21813: Check for an out of range index. */ if (psindx < 0 || psindx >= (int) PRIV (section_count)) { - _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), + bad_psindx: + _bfd_error_handler (_("corrupt EGSD record: its psindx " + "field is too big (%#lx)"), psindx); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } entry->section = PRIV (sections)[psindx]; @@ -1344,14 +1376,9 @@ _bfd_vms_slurp_egsd (bfd *abfd) entry->code_value = bfd_getl64 (esdf->code_address); psindx = bfd_getl32 (esdf->ca_psindx); - /* PR 21813: Check for an out of range index. */ + /* PR 21813: Check for an out of range index. */ if (psindx < 0 || psindx >= (int) PRIV (section_count)) - { - _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), - psindx); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } + goto bad_psindx; entry->code_section = PRIV (sections)[psindx]; } } @@ -1363,14 +1390,15 @@ _bfd_vms_slurp_egsd (bfd *abfd) struct vms_symbol_entry *entry; struct vms_egst *egst = (struct vms_egst *)vms_rec; flagword old_flags; + unsigned int nameoff = offsetof (struct vms_egst, namlng); - old_flags = bfd_getl16 (egst->header.flags); - - entry = add_symbol (abfd, &egst->namlng); - + if (nameoff >= gsd_size) + goto too_small; + entry = add_symbol (abfd, &egst->namlng, gsd_size - nameoff); if (entry == NULL) - return FALSE; + return false; + old_flags = bfd_getl16 (egst->header.flags); entry->typ = gsd_type; entry->data_type = egst->header.datyp; entry->flags = old_flags; @@ -1379,19 +1407,12 @@ _bfd_vms_slurp_egsd (bfd *abfd) if (old_flags & EGSY__V_REL) { - long psindx; - if (PRIV (sections) == NULL) - return FALSE; + return false; psindx = bfd_getl32 (egst->psindx); /* PR 21813: Check for an out of range index. */ if (psindx < 0 || psindx >= (int) PRIV (section_count)) - { - _bfd_error_handler (_("corrupt EGSD record: its psindx field is too big (%#lx)"), - psindx); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } + goto bad_psindx; entry->section = PRIV (sections)[psindx]; } else @@ -1418,7 +1439,7 @@ _bfd_vms_slurp_egsd (bfd *abfd) default: _bfd_error_handler (_("unknown EGSD subtype %d"), gsd_type); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } PRIV (recrd.rec_size) -= gsd_size; @@ -1430,14 +1451,14 @@ _bfd_vms_slurp_egsd (bfd *abfd) if (PRIV (gsd_sym_count) > 0) abfd->flags |= HAS_SYMS; - return TRUE; + return true; } /* Stack routines for vms ETIR commands. */ /* Push value and section index. */ -static void +static bool _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc) { vms_debug2 ((4, "\n", @@ -1450,26 +1471,28 @@ _bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc) { bfd_set_error (bfd_error_bad_value); _bfd_error_handler (_("stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr)); - exit (1); + return false; } + return true; } /* Pop value and section index. */ -static void +static bool _bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel) { if (PRIV (stackptr) == 0) { bfd_set_error (bfd_error_bad_value); _bfd_error_handler (_("stack underflow in _bfd_vms_pop")); - exit (1); + return false; } PRIV (stackptr)--; *val = PRIV (stack[PRIV (stackptr)]).value; *rel = PRIV (stack[PRIV (stackptr)]).reloc; vms_debug2 ((4, "\n", (unsigned long)*val, *rel)); + return true; } /* Routines to fill sections contents during tir/etir read. */ @@ -1526,77 +1549,109 @@ image_inc_ptr (bfd *abfd, bfd_vma offset) /* Save current DST location counter under specified index. */ -static void +static bool dst_define_location (bfd *abfd, unsigned int loc) { vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc)); + if (loc > 1 << 24) + { + /* 16M entries ought to be plenty. */ + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("dst_define_location %u too large"), loc); + return false; + } + /* Grow the ptr offset table if necessary. */ if (loc + 1 > PRIV (dst_ptr_offsets_count)) { - PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets), - (loc + 1) * sizeof (unsigned int)); + PRIV (dst_ptr_offsets) + = bfd_realloc_or_free (PRIV (dst_ptr_offsets), + (loc + 1) * sizeof (unsigned int)); + if (PRIV (dst_ptr_offsets) == NULL) + return false; PRIV (dst_ptr_offsets_count) = loc + 1; } PRIV (dst_ptr_offsets)[loc] = PRIV (image_offset); + return true; } /* Restore saved DST location counter from specified index. */ -static void +static bool dst_restore_location (bfd *abfd, unsigned int loc) { vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc)); - PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc]; + if (loc < PRIV (dst_ptr_offsets_count)) + { + PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc]; + return true; + } + return false; } /* Retrieve saved DST location counter from specified index. */ -static unsigned int -dst_retrieve_location (bfd *abfd, unsigned int loc) +static bool +dst_retrieve_location (bfd *abfd, bfd_vma *loc) { - vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc)); + vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int) *loc)); - return PRIV (dst_ptr_offsets)[loc]; + if (*loc < PRIV (dst_ptr_offsets_count)) + { + *loc = PRIV (dst_ptr_offsets)[*loc]; + return true; + } + return false; } /* Write multiple bytes to section image. */ -static bfd_boolean +static bool image_write (bfd *abfd, unsigned char *ptr, unsigned int size) { + asection *sec = PRIV (image_section); + size_t off = PRIV (image_offset); + + /* Check bounds. */ + if (off > sec->size + || size > sec->size - off) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + #if VMS_DEBUG _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size, - (long)PRIV (image_offset)); - _bfd_hexdump (9, ptr, size, 0); + (long) off)); #endif if (PRIV (image_section)->contents != NULL) + memcpy (sec->contents + off, ptr, size); + else { - asection *sec = PRIV (image_section); - file_ptr off = PRIV (image_offset); - - /* Check bounds. */ - if (off > (file_ptr)sec->size - || size > (file_ptr)sec->size - || off + size > (file_ptr)sec->size) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - memcpy (sec->contents + off, ptr, size); + unsigned int i; + for (i = 0; i < size; i++) + if (ptr[i] != 0) + { + bfd_set_error (bfd_error_bad_value); + return false; + } } +#if VMS_DEBUG + _bfd_hexdump (9, ptr, size, 0); +#endif + PRIV (image_offset) += size; - return TRUE; + return true; } /* Write byte to section image. */ -static bfd_boolean +static bool image_write_b (bfd * abfd, unsigned int value) { unsigned char data[1]; @@ -1610,7 +1665,7 @@ image_write_b (bfd * abfd, unsigned int value) /* Write 2-byte word to image. */ -static bfd_boolean +static bool image_write_w (bfd * abfd, unsigned int value) { unsigned char data[2]; @@ -1623,7 +1678,7 @@ image_write_w (bfd * abfd, unsigned int value) /* Write 4-byte long to image. */ -static bfd_boolean +static bool image_write_l (bfd * abfd, unsigned long value) { unsigned char data[4]; @@ -1636,7 +1691,7 @@ image_write_l (bfd * abfd, unsigned long value) /* Write 8-byte quad to image. */ -static bfd_boolean +static bool image_write_q (bfd * abfd, bfd_vma value) { unsigned char data[8]; @@ -1746,7 +1801,7 @@ _bfd_vms_get_value (bfd *abfd, name[i] = 0; h = (struct alpha_vms_link_hash_entry *) - bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); + bfd_link_hash_lookup (info->hash, name, false, false, true); *hp = h; @@ -1761,7 +1816,7 @@ _bfd_vms_get_value (bfd *abfd, else { (*info->callbacks->undefined_symbol) - (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE); + (info, name, abfd, PRIV (image_section), PRIV (image_offset), true); *vma = 0; } } @@ -1831,16 +1886,16 @@ alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info, the output section (used during linking). Return FALSE in case of error. */ -static bfd_boolean +static bool _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { unsigned char *ptr; unsigned int length; unsigned char *maxptr; - bfd_vma op1; - bfd_vma op2; - unsigned int rel1; - unsigned int rel2; + bfd_vma op1 = 0; + bfd_vma op2 = 0; + unsigned int rel1 = RELC_NONE; + unsigned int rel2 = RELC_NONE; struct alpha_vms_link_hash_entry *h; PRIV (recrd.rec) += ETIR__C_HEADER_SIZE; @@ -1854,24 +1909,29 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) while (ptr < maxptr) { - int cmd = bfd_getl16 (ptr); - int cmd_length = bfd_getl16 (ptr + 2); + int cmd, cmd_length; - ptr += 4; + if (ptr + 4 > maxptr) + goto corrupt_etir; + + cmd = bfd_getl16 (ptr); + cmd_length = bfd_getl16 (ptr + 2); /* PR 21589 and 21579: Check for a corrupt ETIR record. */ - if (cmd_length < 4 || (ptr + cmd_length > maxptr + 4)) + if (cmd_length < 4 || ptr + cmd_length > maxptr) { corrupt_etir: _bfd_error_handler (_("corrupt ETIR record encountered")); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } + ptr += 4; + cmd_length -= 4; #if VMS_DEBUG _bfd_vms_debug (4, "etir: %s(%d)\n", _bfd_vms_etir_name (cmd), cmd); - _bfd_hexdump (8, ptr, cmd_length - 4, 0); + _bfd_hexdump (8, ptr, cmd_length, 0); #endif switch (cmd) @@ -1881,8 +1941,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 32 bit value of symbol (high bits set to 0). */ case ETIR__C_STA_GBL: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); - _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); + if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h))) + return false; break; /* Stack longword @@ -1890,9 +1951,10 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 32 bit value, sign extend to 64 bit. */ case ETIR__C_STA_LW: - if (ptr + 4 >= maxptr) + if (cmd_length < 4) goto corrupt_etir; - _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE); + if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE)) + return false; break; /* Stack quadword @@ -1900,9 +1962,10 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) stack 64 bit value of symbol. */ case ETIR__C_STA_QW: - if (ptr + 8 >= maxptr) + if (cmd_length < 8) goto corrupt_etir; - _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE); + if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE)) + return false; break; /* Stack psect base plus quadword offset @@ -1915,7 +1978,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { int psect; - if (ptr + 12 >= maxptr) + if (cmd_length < 12) goto corrupt_etir; psect = bfd_getl32 (ptr); if ((unsigned int) psect >= PRIV (section_count)) @@ -1923,10 +1986,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) _bfd_error_handler (_("bad section index in %s"), _bfd_vms_etir_name (cmd)); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } op1 = bfd_getl64 (ptr + 4); - _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE); + if (!_bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE)) + return false; } break; @@ -1935,31 +1999,36 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STA_CKARG: _bfd_error_handler (_("unsupported STA cmd %s"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; /* Store byte: pop stack, write byte arg: -. */ case ETIR__C_STO_B: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - image_write_b (abfd, (unsigned int) op1 & 0xff); + if (!image_write_b (abfd, (unsigned int) op1 & 0xff)) + return false; break; /* Store word: pop stack, write word arg: -. */ case ETIR__C_STO_W: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - image_write_w (abfd, (unsigned int) op1 & 0xffff); + if (!image_write_w (abfd, (unsigned int) op1 & 0xffff)) + return false; break; /* Store longword: pop stack, write longword arg: -. */ case ETIR__C_STO_LW: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 & RELC_SEC_BASE) { op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1); @@ -1967,22 +2036,26 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) } else if (rel1 & RELC_SHR_BASE) { - alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1); + if (!alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1)) + return false; rel1 = RELC_NONE; } if (rel1 != RELC_NONE) { if (rel1 != RELC_REL) abort (); - alpha_vms_add_lw_reloc (info); + if (!alpha_vms_add_lw_reloc (info)) + return false; } - image_write_l (abfd, op1); + if (!image_write_l (abfd, op1)) + return false; break; /* Store quadword: pop stack, write quadword arg: -. */ case ETIR__C_STO_QW: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 & RELC_SEC_BASE) { op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1); @@ -1994,9 +2067,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { if (rel1 != RELC_REL) abort (); - alpha_vms_add_qw_reloc (info); + if (!alpha_vms_add_qw_reloc (info)) + return false; } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return false; break; /* Store immediate repeated: pop stack for repeat count @@ -2006,43 +2081,53 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { int size; - if (ptr + 4 >= maxptr) + if (cmd_length < 4) goto corrupt_etir; size = bfd_getl32 (ptr); - _bfd_vms_pop (abfd, &op1, &rel1); + if (size > cmd_length - 4) + goto corrupt_etir; + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; + if (size == 0) + break; + op1 &= 0xffffffff; while (op1-- > 0) - image_write (abfd, ptr + 4, size); + if (!image_write (abfd, ptr + 4, size)) + return false; } break; /* Store global: write symbol value arg: cs global symbol name. */ case ETIR__C_STO_GBL: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->typ == EGSD__C_SYMG) { - alpha_vms_add_fixup_qr - (info, abfd, h->sym->owner, h->sym->symbol_vector); + if (!alpha_vms_add_fixup_qr (info, abfd, h->sym->owner, + h->sym->symbol_vector)) + return false; op1 = 0; } else { op1 = alpha_vms_get_sym_value (h->sym->section, h->sym->value); - alpha_vms_add_qw_reloc (info); + if (!alpha_vms_add_qw_reloc (info)) + return false; } } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return false; break; /* Store code address: write address of entry point arg: cs global symbol name (procedure). */ case ETIR__C_STO_CA: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->flags & EGSY__V_NORM) @@ -2050,14 +2135,16 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) /* That's really a procedure. */ if (h->sym->typ == EGSD__C_SYMG) { - alpha_vms_add_fixup_ca (info, abfd, h->sym->owner); + if (!alpha_vms_add_fixup_ca (info, abfd, h->sym->owner)) + return false; op1 = h->sym->symbol_vector; } else { op1 = alpha_vms_get_sym_value (h->sym->code_section, h->sym->code_value); - alpha_vms_add_qw_reloc (info); + if (!alpha_vms_add_qw_reloc (info)) + return false; } } else @@ -2066,20 +2153,23 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) abort (); } } - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return false; break; /* Store offset to psect: pop stack, add low 32 bits to base of psect arg: none. */ case ETIR__C_STO_OFF: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (!(rel1 & RELC_SEC_BASE)) abort (); op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1); rel1 = RELC_REL; - image_write_q (abfd, op1); + if (!image_write_q (abfd, op1)) + return false; break; /* Store immediate @@ -2089,10 +2179,11 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) { unsigned int size; - if (ptr + 4 >= maxptr) + if (cmd_length < 4) goto corrupt_etir; size = bfd_getl32 (ptr); - image_write (abfd, ptr + 4, size); + if (!image_write (abfd, ptr + 4, size)) + return false; } break; @@ -2103,11 +2194,12 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) store global longword: store 32bit value of symbol arg: cs symbol name. */ case ETIR__C_STO_GBL_LW: - _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h); #if 0 abort (); #endif - image_write_l (abfd, op1); + if (!image_write_l (abfd, op1)) + return false; break; case ETIR__C_STO_RB: @@ -2115,13 +2207,13 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STO_LP_PSB: _bfd_error_handler (_("%s: not supported"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; case ETIR__C_STO_HINT_GBL: case ETIR__C_STO_HINT_PS: _bfd_error_handler (_("%s: not implemented"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; /* 200 Store-conditional Linkage Pair @@ -2146,7 +2238,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STC_PS: _bfd_error_handler (_("%s: not supported"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; /* 201 Store-conditional Linkage Pair with Procedure Signature @@ -2156,12 +2248,15 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) da signature. */ case ETIR__C_STC_LP_PSB: - _bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h); + if (cmd_length < 4) + goto corrupt_etir; + _bfd_vms_get_value (abfd, ptr + 4, ptr + cmd_length, info, &op1, &h); if (h && h->sym) { if (h->sym->typ == EGSD__C_SYMG) { - alpha_vms_add_fixup_lp (info, abfd, h->sym->owner); + if (!alpha_vms_add_fixup_lp (info, abfd, h->sym->owner)) + return false; op1 = h->sym->symbol_vector; op2 = 0; } @@ -2179,8 +2274,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) op1 = 0; op2 = 0; } - image_write_q (abfd, op1); - image_write_q (abfd, op2); + if (!image_write_q (abfd, op1) + || !image_write_q (abfd, op2)) + return false; break; /* 205 Store-conditional NOP at address of global @@ -2237,13 +2333,14 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_STC_NBH_PS: _bfd_error_handler (_("%s: not supported"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; /* Det relocation base: pop stack, set image location counter arg: none. */ case ETIR__C_CTL_SETRB: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (!(rel1 & RELC_SEC_BASE)) abort (); image_set_ptr (abfd, op1, rel1 & RELC_MASK, info); @@ -2252,7 +2349,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) /* Augment relocation base: increment image location counter by offset arg: lw offset value. */ case ETIR__C_CTL_AUGRB: - if (ptr + 4 >= maxptr) + if (cmd_length < 4) goto corrupt_etir; op1 = bfd_getl32 (ptr); image_inc_ptr (abfd, op1); @@ -2261,46 +2358,65 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) /* Define location: pop index, save location counter under index arg: none. */ case ETIR__C_CTL_DFLOC: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - dst_define_location (abfd, op1); + if (!dst_define_location (abfd, op1)) + return false; break; /* Set location: pop index, restore location counter from index arg: none. */ case ETIR__C_CTL_STLOC: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - dst_restore_location (abfd, op1); + if (!dst_restore_location (abfd, op1)) + { + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STLOC"); + return false; + } break; /* Stack defined location: pop index, push location counter from index arg: none. */ case ETIR__C_CTL_STKDL: - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE); + if (!dst_retrieve_location (abfd, &op1)) + { + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STKDL"); + return false; + } + if (!_bfd_vms_push (abfd, op1, RELC_NONE)) + return false; break; case ETIR__C_OPR_NOP: /* No-op. */ break; case ETIR__C_OPR_ADD: /* Add. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 == RELC_NONE && rel2 != RELC_NONE) rel1 = rel2; else if (rel1 != RELC_NONE && rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op1 + op2, rel1); + if (!_bfd_vms_push (abfd, op1 + op2, rel1)) + return false; break; case ETIR__C_OPR_SUB: /* Subtract. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 == RELC_NONE && rel2 != RELC_NONE) rel1 = rel2; else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE)) @@ -2311,81 +2427,123 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) } else if (rel1 != RELC_NONE && rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op2 - op1, rel1); + if (!_bfd_vms_push (abfd, op2 - op1, rel1)) + return false; break; case ETIR__C_OPR_MUL: /* Multiply. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op1 * op2, RELC_NONE); + if (!_bfd_vms_push (abfd, op1 * op2, RELC_NONE)) + return false; break; case ETIR__C_OPR_DIV: /* Divide. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - if (op2 == 0) - _bfd_vms_push (abfd, 0, RELC_NONE); + if (op1 == 0) + { + /* Divide by zero is supposed to give a result of zero, + and a non-fatal warning message. */ + _bfd_error_handler (_("%s divide by zero"), "ETIR__C_OPR_DIV"); + if (!_bfd_vms_push (abfd, 0, RELC_NONE)) + return false; + } else - _bfd_vms_push (abfd, op2 / op1, RELC_NONE); + { + if (!_bfd_vms_push (abfd, op2 / op1, RELC_NONE)) + return false; + } break; case ETIR__C_OPR_AND: /* Logical AND. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op1 & op2, RELC_NONE); + if (!_bfd_vms_push (abfd, op1 & op2, RELC_NONE)) + return false; break; case ETIR__C_OPR_IOR: /* Logical inclusive OR. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op1 | op2, RELC_NONE); + if (!_bfd_vms_push (abfd, op1 | op2, RELC_NONE)) + return false; break; case ETIR__C_OPR_EOR: /* Logical exclusive OR. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE); + if (!_bfd_vms_push (abfd, op1 ^ op2, RELC_NONE)) + return false; break; case ETIR__C_OPR_NEG: /* Negate. */ - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, -op1, RELC_NONE); + if (!_bfd_vms_push (abfd, -op1, RELC_NONE)) + return false; break; case ETIR__C_OPR_COM: /* Complement. */ - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (rel1 != RELC_NONE) goto bad_context; - _bfd_vms_push (abfd, ~op1, RELC_NONE); + if (!_bfd_vms_push (abfd, ~op1, RELC_NONE)) + return false; break; case ETIR__C_OPR_ASH: /* Arithmetic shift. */ - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; if (rel1 != RELC_NONE || rel2 != RELC_NONE) { bad_context: _bfd_error_handler (_("invalid use of %s with contexts"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; + } + if ((bfd_signed_vma) op2 < 0) + { + /* Shift right. */ + bfd_vma sign; + op2 = -op2; + if (op2 >= CHAR_BIT * sizeof (op1)) + op2 = CHAR_BIT * sizeof (op1) - 1; + /* op1 = (bfd_signed_vma) op1 >> op2; */ + sign = op1 & ((bfd_vma) 1 << (CHAR_BIT * sizeof (op1) - 1)); + op1 >>= op2; + sign >>= op2; + op1 = (op1 ^ sign) - sign; + } + else + { + /* Shift left. */ + if (op2 >= CHAR_BIT * sizeof (op1)) + op1 = 0; + else + op1 <<= op2; } - if ((int)op2 < 0) /* Shift right. */ - op1 >>= -(int)op2; - else /* Shift left. */ - op1 <<= (int)op2; - _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym. */ + if (!_bfd_vms_push (abfd, op1, RELC_NONE)) /* FIXME: sym. */ + return false; break; case ETIR__C_OPR_INSV: /* Insert field. */ @@ -2395,37 +2553,43 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) case ETIR__C_OPR_DFLIT: /* Define a literal. */ _bfd_error_handler (_("%s: not supported"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; break; case ETIR__C_OPR_SEL: /* Select. */ - _bfd_vms_pop (abfd, &op1, &rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; if (op1 & 0x01L) - _bfd_vms_pop (abfd, &op1, &rel1); + { + if (!_bfd_vms_pop (abfd, &op1, &rel1)) + return false; + } else { - _bfd_vms_pop (abfd, &op1, &rel1); - _bfd_vms_pop (abfd, &op2, &rel2); - _bfd_vms_push (abfd, op1, rel1); + if (!_bfd_vms_pop (abfd, &op1, &rel1) + || !_bfd_vms_pop (abfd, &op2, &rel2)) + return false; + if (!_bfd_vms_push (abfd, op1, rel1)) + return false; } break; default: _bfd_error_handler (_("reserved cmd %d"), cmd); - return FALSE; + return false; break; } - ptr += cmd_length - 4; + ptr += cmd_length; } - return TRUE; + return true; } /* Process EDBG/ETBT record. Return TRUE on success, FALSE on error */ -static bfd_boolean +static bool vms_slurp_debug (bfd *abfd) { asection *section = PRIV (dst_section); @@ -2440,9 +2604,9 @@ vms_slurp_debug (bfd *abfd) section = bfd_make_section (abfd, "$DST$"); if (!section) - return FALSE; - if (!bfd_set_section_flags (abfd, section, flags)) - return FALSE; + return false; + if (!bfd_set_section_flags (section, flags)) + return false; PRIV (dst_section) = section; } @@ -2450,16 +2614,16 @@ vms_slurp_debug (bfd *abfd) PRIV (image_offset) = section->size; if (!_bfd_vms_slurp_etir (abfd, NULL)) - return FALSE; + return false; section->size = PRIV (image_offset); - return TRUE; + return true; } /* Process EDBG record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_edbg (bfd *abfd) { vms_debug2 ((2, "EDBG\n")); @@ -2472,7 +2636,7 @@ _bfd_vms_slurp_edbg (bfd *abfd) /* Process ETBT record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_etbt (bfd *abfd) { vms_debug2 ((2, "ETBT\n")); @@ -2485,7 +2649,7 @@ _bfd_vms_slurp_etbt (bfd *abfd) /* Process EEOM record. Return TRUE on success, FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_eeom (bfd *abfd) { struct vms_eeom *eeom = (struct vms_eeom *) PRIV (recrd.rec); @@ -2497,7 +2661,7 @@ _bfd_vms_slurp_eeom (bfd *abfd) { _bfd_error_handler (_("corrupt EEOM record - size is too small")); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps); @@ -2506,28 +2670,28 @@ _bfd_vms_slurp_eeom (bfd *abfd) { _bfd_error_handler (_("object module not error-free !")); bfd_set_error (bfd_error_bad_value); - return FALSE; + return false; } - PRIV (eom_data).eom_has_transfer = FALSE; + PRIV (eom_data).eom_has_transfer = false; if (PRIV (recrd.rec_size) > 10) { - PRIV (eom_data).eom_has_transfer = TRUE; + PRIV (eom_data).eom_has_transfer = true; PRIV (eom_data).eom_b_tfrflg = eeom->tfrflg; PRIV (eom_data).eom_l_psindx = bfd_getl32 (eeom->psindx); PRIV (eom_data).eom_l_tfradr = bfd_getl32 (eeom->tfradr); abfd->start_address = PRIV (eom_data).eom_l_tfradr; } - return TRUE; + return true; } /* Slurp an ordered set of VMS object records. Return FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_slurp_object_records (bfd * abfd) { - bfd_boolean err; + bool ok; int type; do @@ -2538,53 +2702,53 @@ _bfd_vms_slurp_object_records (bfd * abfd) if (type < 0) { vms_debug2 ((2, "next_record failed\n")); - return FALSE; + return false; } switch (type) { case EOBJ__C_EMH: - err = _bfd_vms_slurp_ehdr (abfd); + ok = _bfd_vms_slurp_ehdr (abfd); break; case EOBJ__C_EEOM: - err = _bfd_vms_slurp_eeom (abfd); + ok = _bfd_vms_slurp_eeom (abfd); break; case EOBJ__C_EGSD: - err = _bfd_vms_slurp_egsd (abfd); + ok = _bfd_vms_slurp_egsd (abfd); break; case EOBJ__C_ETIR: - err = TRUE; /* _bfd_vms_slurp_etir (abfd); */ + ok = true; /* _bfd_vms_slurp_etir (abfd); */ break; case EOBJ__C_EDBG: - err = _bfd_vms_slurp_edbg (abfd); + ok = _bfd_vms_slurp_edbg (abfd); break; case EOBJ__C_ETBT: - err = _bfd_vms_slurp_etbt (abfd); + ok = _bfd_vms_slurp_etbt (abfd); break; default: - err = FALSE; + ok = false; } - if (!err) + if (!ok) { vms_debug2 ((2, "slurp type %d failed\n", type)); - return FALSE; + return false; } } while (type != EOBJ__C_EEOM); - return TRUE; + return true; } /* Initialize private data */ -static bfd_boolean +static bool vms_initialize (bfd * abfd) { - bfd_size_type amt; + size_t amt; amt = sizeof (struct vms_private_data_struct); abfd->tdata.any = bfd_zalloc (abfd, amt); if (abfd->tdata.any == NULL) - return FALSE; + return false; PRIV (recrd.file_format) = FF_UNKNOWN; @@ -2593,18 +2757,34 @@ vms_initialize (bfd * abfd) if (PRIV (stack) == NULL) goto error_ret1; - return TRUE; + return true; error_ret1: bfd_release (abfd, abfd->tdata.any); abfd->tdata.any = NULL; - return FALSE; + return false; +} + +/* Free malloc'd memory. */ + +static void +alpha_vms_free_private (bfd *abfd) +{ + struct module *module; + + free (PRIV (recrd.buf)); + free (PRIV (sections)); + free (PRIV (syms)); + free (PRIV (dst_ptr_offsets)); + + for (module = PRIV (modules); module; module = module->next) + free (module->file_table); } /* Check the format for a file being read. Return a (bfd_target *) if it's an object file or zero if not. */ -static const struct bfd_target * +static bfd_cleanup alpha_vms_object_p (bfd *abfd) { void *tdata_save = abfd->tdata.any; @@ -2615,10 +2795,13 @@ alpha_vms_object_p (bfd *abfd) /* Allocate alpha-vms specific data. */ if (!vms_initialize (abfd)) - goto error_ret; + { + abfd->tdata.any = tdata_save; + return NULL; + } if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)) - goto err_wrong_format; + goto error_ret; /* The first challenge with VMS is to discover the kind of the file. @@ -2637,27 +2820,17 @@ alpha_vms_object_p (bfd *abfd) 2 bytes size repeated) and 12 bytes for images (4 bytes major id, 4 bytes minor id, 4 bytes length). */ test_len = 12; - - /* Size the main buffer. */ - buf = (unsigned char *) bfd_malloc (test_len); + buf = _bfd_malloc_and_read (abfd, test_len, test_len); if (buf == NULL) goto error_ret; PRIV (recrd.buf) = buf; PRIV (recrd.buf_size) = test_len; - - /* Initialize the record pointer. */ PRIV (recrd.rec) = buf; - if (bfd_bread (buf, test_len, abfd) != test_len) - goto err_wrong_format; - /* Is it an image? */ if ((bfd_getl32 (buf) == EIHD__K_MAJORID) && (bfd_getl32 (buf + 4) == EIHD__K_MINORID)) { - unsigned int to_read; - unsigned int read_so_far; - unsigned int remaining; unsigned int eisd_offset, eihs_offset; /* Extract the header size. */ @@ -2667,44 +2840,25 @@ alpha_vms_object_p (bfd *abfd) if (PRIV (recrd.rec_size) == 0) PRIV (recrd.rec_size) = sizeof (struct vms_eihd); - if (PRIV (recrd.rec_size) > PRIV (recrd.buf_size)) - { - buf = bfd_realloc_or_free (buf, PRIV (recrd.rec_size)); - - if (buf == NULL) - { - PRIV (recrd.buf) = NULL; - goto error_ret; - } - PRIV (recrd.buf) = buf; - PRIV (recrd.buf_size) = PRIV (recrd.rec_size); - } - /* PR 21813: Check for a truncated record. */ - if (PRIV (recrd.rec_size < test_len)) - goto error_ret; - /* Read the remaining record. */ - remaining = PRIV (recrd.rec_size) - test_len; - to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining); - read_so_far = test_len; - - while (remaining > 0) - { - if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read) - goto err_wrong_format; + /* PR 17512: file: 7d7c57c2. */ + if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd)) + goto err_wrong_format; - read_so_far += to_read; - remaining -= to_read; + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)) + goto error_ret; - to_read = MIN (VMS_BLOCK_SIZE, remaining); - } + free (PRIV (recrd.buf)); + PRIV (recrd.buf) = NULL; + buf = _bfd_malloc_and_read (abfd, PRIV (recrd.rec_size), + PRIV (recrd.rec_size)); + if (buf == NULL) + goto error_ret; - /* Reset the record pointer. */ + PRIV (recrd.buf) = buf; + PRIV (recrd.buf_size) = PRIV (recrd.rec_size); PRIV (recrd.rec) = buf; - /* PR 17512: file: 7d7c57c2. */ - if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd)) - goto error_ret; vms_debug2 ((2, "file type is image\n")); if (!_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset)) @@ -2749,14 +2903,13 @@ alpha_vms_object_p (bfd *abfd) if (! bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0)) goto err_wrong_format; - return abfd->xvec; + return alpha_vms_free_private; err_wrong_format: bfd_set_error (bfd_error_wrong_format); error_ret: - if (PRIV (recrd.buf)) - free (PRIV (recrd.buf)); + alpha_vms_free_private (abfd); if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) bfd_release (abfd, abfd->tdata.any); abfd->tdata.any = tdata_save; @@ -2771,6 +2924,7 @@ static void _bfd_vms_write_emh (bfd *abfd) { struct vms_rec_wr *recwr = &PRIV (recwr); + unsigned char tbuf[18]; _bfd_vms_output_alignment (recwr, 2); @@ -2785,7 +2939,7 @@ _bfd_vms_write_emh (bfd *abfd) /* Create module name from filename. */ if (bfd_get_filename (abfd) != 0) { - char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE); + char *module = vms_get_module_name (bfd_get_filename (abfd), true); _bfd_vms_output_counted (recwr, module); free (module); } @@ -2793,7 +2947,7 @@ _bfd_vms_write_emh (bfd *abfd) _bfd_vms_output_counted (recwr, "NONAME"); _bfd_vms_output_counted (recwr, BFD_VERSION_STRING); - _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH); + _bfd_vms_output_dump (recwr, get_vms_time_string (tbuf), EMH_DATE_LENGTH); _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH); _bfd_vms_output_end (abfd, recwr); } @@ -2819,7 +2973,7 @@ _bfd_vms_write_lmn (bfd *abfd, const char *name) /* Write eom record for bfd abfd. Return FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_write_eeom (bfd *abfd) { struct vms_rec_wr *recwr = &PRIV (recwr); @@ -2842,7 +2996,7 @@ _bfd_vms_write_eeom (bfd *abfd) if (section == 0) { bfd_set_error (bfd_error_nonrepresentable_section); - return FALSE; + return false; } _bfd_vms_output_short (recwr, 0); _bfd_vms_output_long (recwr, (unsigned long) section->target_index); @@ -2852,25 +3006,39 @@ _bfd_vms_write_eeom (bfd *abfd) } _bfd_vms_output_end (abfd, recwr); - return TRUE; + return true; } -static void +static void * vector_grow1 (struct vector_type *vec, size_t elsz) { - if (vec->nbr_el + 1 < vec->max_el) - return; - - if (vec->max_el == 0) + if (vec->nbr_el >= vec->max_el) { - vec->max_el = 16; - vec->els = bfd_malloc2 (vec->max_el, elsz); - } - else - { - vec->max_el *= 2; - vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz); + if (vec->max_el == 0) + { + vec->max_el = 16; + vec->els = bfd_malloc (vec->max_el * elsz); + } + else + { + size_t amt; + if (vec->max_el > -1u / 2) + { + bfd_set_error (bfd_error_file_too_big); + return NULL; + } + vec->max_el *= 2; + if (_bfd_mul_overflow (vec->max_el, elsz, &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return NULL; + } + vec->els = bfd_realloc_or_free (vec->els, amt); + } } + if (vec->els == NULL) + return NULL; + return (char *) vec->els + elsz * vec->nbr_el++; } /* Bump ABFD file position to next block. */ @@ -2926,7 +3094,7 @@ alpha_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd) /* Create an EISD for shared image SHRIMG. Return FALSE in case of error. */ -static bfd_boolean +static bool alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg) { struct vms_internal_eisd_map *eisd; @@ -2936,12 +3104,12 @@ alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg) if (namlen + 5 > EISD__K_GBLNAMLEN) { /* Won't fit. */ - return FALSE; + return false; } eisd = bfd_alloc (abfd, sizeof (*eisd)); if (eisd == NULL) - return FALSE; + return false; /* Fill the fields. */ eisd->u.gbl_eisd.common.majorid = EISD__K_MAJORID; @@ -2964,25 +3132,25 @@ alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg) /* Append it to the list. */ alpha_vms_append_extra_eisd (abfd, eisd); - return TRUE; + return true; } /* Create an EISD for section SEC. Return FALSE in case of failure. */ -static bfd_boolean +static bool alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec) { struct vms_internal_eisd_map *eisd; /* Only for allocating section. */ if (!(sec->flags & SEC_ALLOC)) - return TRUE; + return true; BFD_ASSERT (vms_section_data (sec)->eisd == NULL); eisd = bfd_alloc (abfd, sizeof (*eisd)); if (eisd == NULL) - return FALSE; + return false; vms_section_data (sec)->eisd = eisd; /* Fill the fields. */ @@ -3026,13 +3194,13 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec) PRIV (eisd_tail)->next = eisd; PRIV (eisd_tail) = eisd; - return TRUE; + return true; } /* Layout executable ABFD and write it to the disk. Return FALSE in case of failure. */ -static bfd_boolean +static bool alpha_vms_write_exec (bfd *abfd) { struct vms_eihd eihd; @@ -3082,7 +3250,7 @@ alpha_vms_write_exec (bfd *abfd) bfd_putl32 (16, eihd.virt_mem_block_size); bfd_putl32 (0, eihd.ext_fixup_off); bfd_putl32 (0, eihd.noopt_psect_off); - bfd_putl32 (-1, eihd.alias); + bfd_putl16 (-1, eihd.alias); /* Alloc EIHA. */ eiha = (struct vms_eiha *)((char *) &eihd + PRIV (file_pos)); @@ -3109,7 +3277,7 @@ alpha_vms_write_exec (bfd *abfd) unsigned int len; /* Set module name. */ - module = vms_get_module_name (bfd_get_filename (abfd), TRUE); + module = vms_get_module_name (bfd_get_filename (abfd), true); len = strlen (module); if (len > sizeof (eihi->imgnam) - 1) len = sizeof (eihi->imgnam) - 1; @@ -3153,7 +3321,7 @@ alpha_vms_write_exec (bfd *abfd) for (sec = abfd->sections; sec; sec = sec->next) { if (!alpha_vms_create_eisd_for_section (abfd, sec)) - return FALSE; + return false; } /* Merge section EIDS which extra ones. */ @@ -3171,7 +3339,7 @@ alpha_vms_write_exec (bfd *abfd) { eisd = bfd_zalloc (abfd, sizeof (*eisd)); if (eisd == NULL) - return FALSE; + return false; eisd->u.eisd.majorid = 0; eisd->u.eisd.minorid = 0; eisd->u.eisd.eisdsize = 0; @@ -3255,7 +3423,7 @@ alpha_vms_write_exec (bfd *abfd) /* Write first block. */ bfd_putl32 (lnkflags, eihd.lnkflags); if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd)) - return FALSE; + return false; /* Write remaining eisd. */ if (eisd != NULL) @@ -3276,7 +3444,7 @@ alpha_vms_write_exec (bfd *abfd) != eisd->file_pos / VMS_BLOCK_SIZE)) { if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk)) - return FALSE; + return false; memset (blk, 0xff, sizeof (blk)); } @@ -3293,7 +3461,7 @@ alpha_vms_write_exec (bfd *abfd) if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS)) continue; if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size) - return FALSE; + return false; /* Pad. */ len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE; @@ -3301,7 +3469,7 @@ alpha_vms_write_exec (bfd *abfd) { memset (blk, 0, len); if (bfd_bwrite (blk, len, abfd) != len) - return FALSE; + return false; } } @@ -3363,16 +3531,16 @@ alpha_vms_write_exec (bfd *abfd) _bfd_vms_output_end (abfd, recwr); if (!_bfd_vms_write_eeom (abfd)) - return FALSE; + return false; } - return TRUE; + return true; } /* Object write. */ /* Write section and symbol directory of bfd abfd. Return FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_write_egsd (bfd *abfd) { asection *section; @@ -3595,12 +3763,12 @@ _bfd_vms_write_egsd (bfd *abfd) _bfd_vms_output_alignment (recwr, 8); _bfd_vms_output_end (abfd, recwr); - return TRUE; + return true; } /* Write object header for bfd abfd. Return FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_write_ehdr (bfd *abfd) { asymbol *symbol; @@ -3649,7 +3817,7 @@ _bfd_vms_write_ehdr (bfd *abfd) 39); _bfd_vms_output_end (abfd, recwr); - return TRUE; + return true; } /* Part 4.6, relocations. */ @@ -3770,7 +3938,7 @@ etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen) /* Return whether RELOC must be deferred till the end. */ -static bfd_boolean +static bool defer_reloc_p (arelent *reloc) { switch (reloc->howto->type) @@ -3779,16 +3947,16 @@ defer_reloc_p (arelent *reloc) case ALPHA_R_LDA: case ALPHA_R_BSR: case ALPHA_R_BOH: - return TRUE; + return true; default: - return FALSE; + return false; } } /* Write section contents for bfd abfd. Return FALSE on error. */ -static bfd_boolean +static bool _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) { asection *section; @@ -3812,7 +3980,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) if (!section->contents) { bfd_set_error (bfd_error_no_contents); - return FALSE; + return false; } start_etir_or_etbt_record (abfd, section, 0); @@ -3860,7 +4028,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) bfd_vma addr = rptr->address; asymbol *sym = *rptr->sym_ptr_ptr; asection *sec = sym->section; - bfd_boolean defer = defer_reloc_p (rptr); + bool defer = defer_reloc_p (rptr); unsigned int slen; if (pass2_in_progress) @@ -4096,7 +4264,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) if (curr_addr > section->size) { _bfd_error_handler (_("size error in section %pA"), section); - return FALSE; + return false; } size = section->size - curr_addr; sto_imm (abfd, section, size, curr_data, curr_addr); @@ -4118,12 +4286,12 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED) } _bfd_vms_output_alignment (recwr, 2); - return TRUE; + return true; } /* Write cached information into a file being written, at bfd_close. */ -static bfd_boolean +static bool alpha_vms_write_object_contents (bfd *abfd) { vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd)); @@ -4137,16 +4305,16 @@ alpha_vms_write_object_contents (bfd *abfd) if (abfd->section_count > 0) /* we have sections */ { if (!_bfd_vms_write_ehdr (abfd)) - return FALSE; + return false; if (!_bfd_vms_write_egsd (abfd)) - return FALSE; + return false; if (!_bfd_vms_write_etir (abfd, EOBJ__C_ETIR)) - return FALSE; + return false; if (!_bfd_vms_write_eeom (abfd)) - return FALSE; + return false; } } - return TRUE; + return true; } /* Debug stuff: nearest line. */ @@ -4170,7 +4338,7 @@ new_module (bfd *abfd) /* Parse debug info for a module and internalize it. */ -static void +static bool parse_module (bfd *abfd, struct module *module, unsigned char *ptr, int length) { @@ -4184,9 +4352,13 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, /* Initialize tables with zero element. */ curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo)); + if (!curr_srec) + return false; module->srec_table = curr_srec; curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo)); + if (!curr_line) + return false; module->line_table = curr_line; while (length == -1 || ptr < maxptr) @@ -4204,7 +4376,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, { case DST__K_MODBEG: module->name - = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME, + = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_MODBEG_NAME, maxptr - (ptr + DST_S_B_MODBEG_NAME)); curr_pc = 0; @@ -4221,8 +4393,10 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, case DST__K_RTNBEG: funcinfo = (struct funcinfo *) bfd_zalloc (abfd, sizeof (struct funcinfo)); + if (!funcinfo) + return false; funcinfo->name - = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME, + = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_RTNBEG_NAME, maxptr - (ptr + DST_S_B_RTNBEG_NAME)); funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS); funcinfo->next = module->func_table; @@ -4233,6 +4407,8 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, break; case DST__K_RTNEND: + if (!module->func_table) + return false; module->func_table->high = module->func_table->low + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1; @@ -4273,19 +4449,20 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, { unsigned int fileid = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID); - char *filename - = _bfd_vms_save_counted_string (src_ptr + DST_S_B_SRC_DF_FILENAME, - (ptr + rec_length) - - (src_ptr + DST_S_B_SRC_DF_FILENAME) - ); + char *filename = _bfd_vms_save_counted_string + (abfd, + src_ptr + DST_S_B_SRC_DF_FILENAME, + ptr + rec_length - (src_ptr + DST_S_B_SRC_DF_FILENAME)); while (fileid >= module->file_table_count) { module->file_table_count *= 2; module->file_table - = bfd_realloc (module->file_table, - module->file_table_count - * sizeof (struct fileinfo)); + = bfd_realloc_or_free (module->file_table, + module->file_table_count + * sizeof (struct fileinfo)); + if (module->file_table == NULL) + return false; } module->file_table [fileid].name = filename; @@ -4607,6 +4784,7 @@ parse_module (bfd *abfd, struct module *module, unsigned char *ptr, because parsing can be either performed at module creation or deferred until debug info is consumed. */ SET_MODULE_PARSED (module); + return true; } /* Build the list of modules for the specified BFD. */ @@ -4623,31 +4801,27 @@ build_module_list (bfd *abfd) section and build the list of modules. This is sufficient since we can compute the start address and the end address of every module from the section contents. */ - bfd_size_type size = bfd_get_section_size (dmt); - unsigned char *ptr, *end; - - ptr = (unsigned char *) bfd_alloc (abfd, size); - if (! ptr) - return NULL; + bfd_size_type size = bfd_section_size (dmt); + unsigned char *buf, *ptr, *end; - if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size)) + if (! bfd_malloc_and_get_section (abfd, dmt, &buf)) return NULL; vms_debug2 ((2, "DMT\n")); + ptr = buf; end = ptr + size; - - while (ptr < end) + while (end - ptr >= DBG_S_C_DMT_HEADER_SIZE) { /* Each header declares a module with its start offset and size of debug info in the DST section, as well as the count of program sections (i.e. address spans) it contains. */ - int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG); - int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE); + unsigned int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG); + unsigned int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE); int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT); ptr += DBG_S_C_DMT_HEADER_SIZE; - vms_debug2 ((3, "module: modbeg = %d, size = %d, count = %d\n", + vms_debug2 ((3, "module: modbeg = %u, size = %u, count = %d\n", modbeg, msize, count)); /* We create a 'module' structure for each program section since @@ -4655,10 +4829,10 @@ build_module_list (bfd *abfd) As a consequence, the actual debug info in the DST section is shared and can be parsed multiple times; that doesn't seem to cause problems in practice. */ - while (count-- > 0) + while (count-- > 0 && end - ptr >= DBG_S_C_DMT_PSECT_SIZE) { - int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START); - int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH); + unsigned int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START); + unsigned int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH); module = new_module (abfd); module->modbeg = modbeg; module->size = msize; @@ -4668,10 +4842,11 @@ build_module_list (bfd *abfd) list = module; ptr += DBG_S_C_DMT_PSECT_SIZE; - vms_debug2 ((4, "section: start = 0x%x, length = %d\n", + vms_debug2 ((4, "section: start = 0x%x, length = %u\n", start, length)); } } + free (buf); } else { @@ -4684,7 +4859,8 @@ build_module_list (bfd *abfd) return NULL; module = new_module (abfd); - parse_module (abfd, module, PRIV (dst_section)->contents, -1); + if (!parse_module (abfd, module, PRIV (dst_section)->contents, -1)) + return NULL; list = module; } @@ -4694,7 +4870,7 @@ build_module_list (bfd *abfd) /* Calculate and return the name of the source file and the line nearest to the wanted location in the specified module. */ -static bfd_boolean +static bool module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, const char **file, const char **func, unsigned int *line) @@ -4702,24 +4878,26 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, struct funcinfo *funcinfo; struct lineinfo *lineinfo; struct srecinfo *srecinfo; - bfd_boolean ret = FALSE; + bool ret = false; /* Parse this module if that was not done at module creation. */ if (! IS_MODULE_PARSED (module)) { unsigned int size = module->size; unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg; - unsigned char *buffer = (unsigned char *) bfd_malloc (module->size); + unsigned char *buffer; if (bfd_seek (abfd, modbeg, SEEK_SET) != 0 - || bfd_bread (buffer, size, abfd) != size) + || (buffer = _bfd_malloc_and_read (abfd, size, size)) == NULL) { bfd_set_error (bfd_error_no_debug_section); - return FALSE; + return false; } - parse_module (abfd, module, buffer, size); + ret = parse_module (abfd, module, buffer, size); free (buffer); + if (!ret) + return ret; } /* Find out the function (if any) that contains the address. */ @@ -4727,7 +4905,7 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, if (addr >= funcinfo->low && addr <= funcinfo->high) { *func = funcinfo->name; - ret = TRUE; + ret = true; break; } @@ -4748,7 +4926,7 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, *file = module->name; *line = lineinfo->line; } - return TRUE; + return true; } break; @@ -4761,7 +4939,7 @@ module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr, return the name of the source file and the line nearest to the wanted location. */ -static bfd_boolean +static bool _bfd_vms_find_nearest_line (bfd *abfd, asymbol **symbols ATTRIBUTE_UNUSED, asection *section, @@ -4784,27 +4962,27 @@ _bfd_vms_find_nearest_line (bfd *abfd, /* We can't do anything if there is no DST (debug symbol table). */ if (PRIV (dst_section) == NULL) - return FALSE; + return false; /* Create the module list - if not already done. */ if (PRIV (modules) == NULL) { PRIV (modules) = build_module_list (abfd); if (PRIV (modules) == NULL) - return FALSE; + return false; } for (module = PRIV (modules); module; module = module->next) if (addr >= module->low && addr <= module->high) return module_find_nearest_line (abfd, module, addr, file, func, line); - return FALSE; + return false; } /* Canonicalizations. */ /* Set name, value, section and flags of SYM from E. */ -static bfd_boolean +static bool alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym) { flagword flags; @@ -4862,14 +5040,14 @@ alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym) break; default: - return FALSE; + return false; } sym->name = name; sym->section = sec; sym->flags = flags; sym->value = value; - return TRUE; + return true; } @@ -4934,7 +5112,7 @@ alpha_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols) /* Read and convert relocations from ETIR. We do it once for all sections. */ -static bfd_boolean +static bool alpha_vms_slurp_relocs (bfd *abfd) { int cur_psect = -1; @@ -4943,14 +5121,14 @@ alpha_vms_slurp_relocs (bfd *abfd) /* We slurp relocs only once, for all sections. */ if (PRIV (reloc_done)) - return TRUE; - PRIV (reloc_done) = TRUE; + return true; + PRIV (reloc_done) = true; if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0) - return FALSE; + return false; if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return FALSE; + return false; while (1) { @@ -5012,7 +5190,7 @@ alpha_vms_slurp_relocs (bfd *abfd) /* xgettext:c-format */ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; } cur_psect = cur_psidx; vaddr = cur_addend; @@ -5030,7 +5208,7 @@ alpha_vms_slurp_relocs (bfd *abfd) /* xgettext:c-format */ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), _bfd_vms_etir_name (ETIR__C_STA_LW)); - return FALSE; + return false; } } cur_addend = bfd_getl32 (ptr + 4); @@ -5045,7 +5223,7 @@ alpha_vms_slurp_relocs (bfd *abfd) /* xgettext:c-format */ (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd), _bfd_vms_etir_name (ETIR__C_STA_QW)); - return FALSE; + return false; } cur_addend = bfd_getl64 (ptr + 4); prev_cmd = cmd; @@ -5062,7 +5240,7 @@ alpha_vms_slurp_relocs (bfd *abfd) _bfd_error_handler (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (ETIR__C_STO_LW)); - return FALSE; + return false; } reloc_code = BFD_RELOC_32; break; @@ -5075,7 +5253,7 @@ alpha_vms_slurp_relocs (bfd *abfd) _bfd_error_handler (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (ETIR__C_STO_QW)); - return FALSE; + return false; } reloc_code = BFD_RELOC_64; break; @@ -5087,7 +5265,7 @@ alpha_vms_slurp_relocs (bfd *abfd) _bfd_error_handler (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (ETIR__C_STO_OFF)); - return FALSE; + return false; } reloc_code = BFD_RELOC_64; break; @@ -5100,7 +5278,7 @@ alpha_vms_slurp_relocs (bfd *abfd) _bfd_error_handler (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd), _bfd_vms_etir_name (ETIR__C_OPR_ADD)); - return FALSE; + return false; } prev_cmd = ETIR__C_OPR_ADD; continue; @@ -5154,7 +5332,7 @@ alpha_vms_slurp_relocs (bfd *abfd) default: _bfd_error_handler (_("unknown reloc %s"), _bfd_vms_etir_name (cmd)); - return FALSE; + return false; } { @@ -5167,16 +5345,16 @@ alpha_vms_slurp_relocs (bfd *abfd) if (cur_psect < 0 || cur_psect > (int)PRIV (section_count)) { _bfd_error_handler (_("invalid section index in ETIR")); - return FALSE; + return false; } if (PRIV (sections) == NULL) - return FALSE; + return false; sec = PRIV (sections)[cur_psect]; if (sec == bfd_abs_section_ptr) { _bfd_error_handler (_("relocation for non-REL psect")); - return FALSE; + return false; } vms_sec = vms_section_data (sec); @@ -5193,8 +5371,10 @@ alpha_vms_slurp_relocs (bfd *abfd) else { vms_sec->reloc_max *= 2; - sec->relocation = bfd_realloc + sec->relocation = bfd_realloc_or_free (sec->relocation, vms_sec->reloc_max * sizeof (arelent)); + if (sec->relocation == NULL) + return false; } } reloc = &sec->relocation[sec->reloc_count]; @@ -5232,7 +5412,7 @@ alpha_vms_slurp_relocs (bfd *abfd) else if (cur_psidx >= 0) { if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count)) - return FALSE; + return false; reloc->sym_ptr_ptr = PRIV (sections)[cur_psidx]->symbol_ptr_ptr; } @@ -5255,9 +5435,9 @@ alpha_vms_slurp_relocs (bfd *abfd) cur_psidx = -1; } } - vms_debug2 ((3, "alpha_vms_slurp_relocs: result = TRUE\n")); + vms_debug2 ((3, "alpha_vms_slurp_relocs: result = true\n")); - return TRUE; + return true; } /* Return the number of bytes required to store the relocation @@ -5268,7 +5448,7 @@ alpha_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section) { alpha_vms_slurp_relocs (abfd); - return (section->reloc_count + 1) * sizeof (arelent *); + return (section->reloc_count + 1L) * sizeof (arelent *); } /* Convert relocations from VMS (external) form into BFD internal @@ -5337,30 +5517,30 @@ static reloc_howto_type alpha_howto_table[] = 0, /* Rightshift. */ 0, /* Size (0 = byte, 1 = short, 2 = long). */ 8, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "IGNORE", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0, /* Source mask */ 0, /* Dest mask. */ - TRUE), /* PC rel offset. */ + true), /* PC rel offset. */ /* A 64 bit reference to a symbol. */ HOWTO (ALPHA_R_REFQUAD, /* Type. */ 0, /* Rightshift. */ 4, /* Size (0 = byte, 1 = short, 2 = long). */ 64, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_bitfield, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "REFQUAD", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ MINUS_ONE, /* Source mask. */ MINUS_ONE, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* A 21 bit branch. The native assembler generates these for branches within the text segment, and also fills in the PC @@ -5369,90 +5549,90 @@ static reloc_howto_type alpha_howto_table[] = 2, /* Rightshift. */ 2, /* Size (0 = byte, 1 = short, 2 = long). */ 21, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_signed, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "BRADDR", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0x1fffff, /* Source mask. */ 0x1fffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* A hint for a jump to a register. */ HOWTO (ALPHA_R_HINT, /* Type. */ 2, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 14, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "HINT", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0x3fff, /* Source mask. */ 0x3fff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* 16 bit PC relative offset. */ HOWTO (ALPHA_R_SREL16, /* Type. */ 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_signed, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "SREL16", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0xffff, /* Source mask. */ 0xffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* 32 bit PC relative offset. */ HOWTO (ALPHA_R_SREL32, /* Type. */ 0, /* Rightshift. */ 2, /* Size (0 = byte, 1 = short, 2 = long). */ 32, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_signed, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "SREL32", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* A 64 bit PC relative offset. */ HOWTO (ALPHA_R_SREL64, /* Type. */ 0, /* Rightshift. */ 4, /* Size (0 = byte, 1 = short, 2 = long). */ 64, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_signed, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "SREL64", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ MINUS_ONE, /* Source mask. */ MINUS_ONE, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* Push a value on the reloc evaluation stack. */ HOWTO (ALPHA_R_OP_PUSH, /* Type. */ 0, /* Rightshift. */ 0, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "OP_PUSH", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0, /* Source mask. */ 0, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* Store the value from the stack at the given address. Store it in a bitfield of size r_size starting at bit position r_offset. */ @@ -5460,15 +5640,15 @@ static reloc_howto_type alpha_howto_table[] = 0, /* Rightshift. */ 4, /* Size (0 = byte, 1 = short, 2 = long). */ 64, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "OP_STORE", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0, /* Source mask. */ MINUS_ONE, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* Subtract the reloc address from the value on the top of the relocation stack. */ @@ -5476,15 +5656,15 @@ static reloc_howto_type alpha_howto_table[] = 0, /* Rightshift. */ 0, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "OP_PSUB", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0, /* Source mask. */ 0, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* Shift the value on the top of the relocation stack right by the given value. */ @@ -5492,60 +5672,60 @@ static reloc_howto_type alpha_howto_table[] = 0, /* Rightshift. */ 0, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "OP_PRSHIFT", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0, /* Source mask. */ 0, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* Hack. Linkage is done by linker. */ HOWTO (ALPHA_R_LINKAGE, /* Type. */ 0, /* Rightshift. */ 0, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "LINKAGE", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0, /* Source mask. */ 0, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* A 32 bit reference to a symbol. */ HOWTO (ALPHA_R_REFLONG, /* Type. */ 0, /* Rightshift. */ 2, /* Size (0 = byte, 1 = short, 2 = long). */ 32, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_bitfield, /* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "REFLONG", /* Name. */ - TRUE, /* Partial_inplace. */ + true, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ /* A 64 bit reference to a procedure, written as 32 bit value. */ HOWTO (ALPHA_R_CODEADDR, /* Type. */ 0, /* Rightshift. */ 4, /* Size (0 = byte, 1 = short, 2 = long). */ 64, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_signed,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "CODEADDR", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ HOWTO (ALPHA_R_NOP, /* Type. */ 0, /* Rightshift. */ @@ -5554,57 +5734,57 @@ static reloc_howto_type alpha_howto_table[] = /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH because the calculations for the 3 relocations are the same. See B.4.5.2 of the OpenVMS Linker Utility Manual. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "NOP", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ HOWTO (ALPHA_R_BSR, /* Type. */ 0, /* Rightshift. */ 3, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "BSR", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ HOWTO (ALPHA_R_LDA, /* Type. */ 0, /* Rightshift. */ 3, /* Size (0 = byte, 1 = short, 2 = long). */ 0, /* Bitsize. */ - FALSE, /* PC relative. */ + false, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "LDA", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ HOWTO (ALPHA_R_BOH, /* Type. */ 0, /* Rightshift. */ 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */ 0, /* Bitsize. */ - TRUE, /* PC relative. */ + true, /* PC relative. */ 0, /* Bitpos. */ complain_overflow_dont,/* Complain_on_overflow. */ reloc_nil, /* Special_function. */ "BOH", /* Name. */ - FALSE, /* Partial_inplace. */ + false, /* Partial_inplace. */ 0xffffffff, /* Source mask. */ 0xffffffff, /* Dest mask. */ - FALSE), /* PC rel offset. */ + false), /* PC rel offset. */ }; /* Return a pointer to a howto structure which, when invoked, will perform @@ -5712,7 +5892,7 @@ alpha_vms_get_synthetic_symtab (bfd *abfd, l = strlen (name); sname = bfd_alloc (abfd, l + 5); if (sname == NULL) - return FALSE; + return false; memcpy (sname, name, l); memcpy (sname + l, "..en", 5); @@ -5767,9 +5947,9 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len) case EMH__C_MHD: { struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec; - const char * name; - const char * nextname; - const char * maxname; + unsigned char *name; + unsigned char *nextname; + unsigned char *maxname; /* PR 21840: Check for invalid lengths. */ if (rec_len < sizeof (* mhd)) @@ -5781,8 +5961,8 @@ evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len) fprintf (file, _(" structure level: %u\n"), mhd->strlvl); fprintf (file, _(" max record size: %u\n"), (unsigned) bfd_getl32 (mhd->recsiz)); - name = (char *)(mhd + 1); - maxname = (char *) rec + rec_len; + name = (unsigned char *) (mhd + 1); + maxname = (unsigned char *) rec + rec_len; if (name > maxname - 2) { fprintf (file, _(" Error: The module name is missing\n")); @@ -5926,16 +6106,18 @@ static void evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len) { unsigned int off = sizeof (struct vms_egsd); - unsigned int n; + unsigned int n = 0; fprintf (file, _(" EGSD (len=%u):\n"), rec_len); + if (rec_len < sizeof (struct vms_egsd) + sizeof (struct vms_egsd_entry)) + return; - n = 0; - for (off = sizeof (struct vms_egsd); off < rec_len; ) + while (off <= rec_len - sizeof (struct vms_egsd_entry)) { struct vms_egsd_entry *e = (struct vms_egsd_entry *)(rec + off); unsigned int type; unsigned int len; + unsigned int rest; type = (unsigned)bfd_getl16 (e->gsdtyp); len = (unsigned)bfd_getl16 (e->gsdsiz); @@ -5945,174 +6127,212 @@ evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len) n, type, len); n++; - if (off + len > rec_len || off + len < off) + if (len < sizeof (struct vms_egsd_entry) || len > rec_len - off) { - fprintf (file, _(" Error: length larger than remaining space in record\n")); + fprintf (file, _(" Erroneous length\n")); return; } switch (type) { case EGSD__C_PSC: - { - struct vms_egps *egps = (struct vms_egps *)e; - unsigned int flags = bfd_getl16 (egps->flags); - unsigned int l; - - fprintf (file, _("PSC - Program section definition\n")); - fprintf (file, _(" alignment : 2**%u\n"), egps->align); - fprintf (file, _(" flags : 0x%04x"), flags); - evax_bfd_print_egsd_flags (file, flags); - fputc ('\n', file); - l = bfd_getl32 (egps->alloc); - fprintf (file, _(" alloc (len): %u (0x%08x)\n"), l, l); - fprintf (file, _(" name : %.*s\n"), - egps->namlng, egps->name); - } + if (len >= offsetof (struct vms_egps, name)) + { + struct vms_egps *egps = (struct vms_egps *) e; + unsigned int flags = bfd_getl16 (egps->flags); + unsigned int l; + + fprintf (file, _("PSC - Program section definition\n")); + fprintf (file, _(" alignment : 2**%u\n"), egps->align); + fprintf (file, _(" flags : 0x%04x"), flags); + evax_bfd_print_egsd_flags (file, flags); + fputc ('\n', file); + l = bfd_getl32 (egps->alloc); + fprintf (file, _(" alloc (len): %u (0x%08x)\n"), l, l); + rest = len - offsetof (struct vms_egps, name); + fprintf (file, _(" name : %.*s\n"), + egps->namlng > rest ? rest : egps->namlng, + egps->name); + } break; case EGSD__C_SPSC: - { - struct vms_esgps *esgps = (struct vms_esgps *)e; - unsigned int flags = bfd_getl16 (esgps->flags); - unsigned int l; - - fprintf (file, _("SPSC - Shared Image Program section def\n")); - fprintf (file, _(" alignment : 2**%u\n"), esgps->align); - fprintf (file, _(" flags : 0x%04x"), flags); - evax_bfd_print_egsd_flags (file, flags); - fputc ('\n', file); - l = bfd_getl32 (esgps->alloc); - fprintf (file, _(" alloc (len) : %u (0x%08x)\n"), l, l); - fprintf (file, _(" image offset : 0x%08x\n"), - (unsigned int)bfd_getl32 (esgps->base)); - fprintf (file, _(" symvec offset : 0x%08x\n"), - (unsigned int)bfd_getl32 (esgps->value)); - fprintf (file, _(" name : %.*s\n"), - esgps->namlng, esgps->name); - } + if (len >= offsetof (struct vms_esgps, name)) + { + struct vms_esgps *esgps = (struct vms_esgps *) e; + unsigned int flags = bfd_getl16 (esgps->flags); + unsigned int l; + + fprintf (file, _("SPSC - Shared Image Program section def\n")); + fprintf (file, _(" alignment : 2**%u\n"), esgps->align); + fprintf (file, _(" flags : 0x%04x"), flags); + evax_bfd_print_egsd_flags (file, flags); + fputc ('\n', file); + l = bfd_getl32 (esgps->alloc); + fprintf (file, _(" alloc (len) : %u (0x%08x)\n"), l, l); + fprintf (file, _(" image offset : 0x%08x\n"), + (unsigned int) bfd_getl32 (esgps->base)); + fprintf (file, _(" symvec offset : 0x%08x\n"), + (unsigned int) bfd_getl32 (esgps->value)); + rest = len - offsetof (struct vms_esgps, name); + fprintf (file, _(" name : %.*s\n"), + esgps->namlng > rest ? rest : esgps->namlng, + esgps->name); + } break; case EGSD__C_SYM: - { - struct vms_egsy *egsy = (struct vms_egsy *)e; - unsigned int flags = bfd_getl16 (egsy->flags); + if (len >= sizeof (struct vms_egsy)) + { + struct vms_egsy *egsy = (struct vms_egsy *) e; + unsigned int flags = bfd_getl16 (egsy->flags); - if (flags & EGSY__V_DEF) - { - struct vms_esdf *esdf = (struct vms_esdf *)e; - - fprintf (file, _("SYM - Global symbol definition\n")); - fprintf (file, _(" flags: 0x%04x"), flags); - exav_bfd_print_egsy_flags (flags, file); - fputc ('\n', file); - fprintf (file, _(" psect offset: 0x%08x\n"), - (unsigned)bfd_getl32 (esdf->value)); - if (flags & EGSY__V_NORM) - { - fprintf (file, _(" code address: 0x%08x\n"), - (unsigned)bfd_getl32 (esdf->code_address)); - fprintf (file, _(" psect index for entry point : %u\n"), - (unsigned)bfd_getl32 (esdf->ca_psindx)); - } - fprintf (file, _(" psect index : %u\n"), - (unsigned)bfd_getl32 (esdf->psindx)); - fprintf (file, _(" name : %.*s\n"), - esdf->namlng, esdf->name); - } - else - { - struct vms_esrf *esrf = (struct vms_esrf *)e; + if ((flags & EGSY__V_DEF) != 0 + && len >= offsetof (struct vms_esdf, name)) + { + struct vms_esdf *esdf = (struct vms_esdf *) e; + + fprintf (file, _("SYM - Global symbol definition\n")); + fprintf (file, _(" flags: 0x%04x"), flags); + exav_bfd_print_egsy_flags (flags, file); + fputc ('\n', file); + fprintf (file, _(" psect offset: 0x%08x\n"), + (unsigned) bfd_getl32 (esdf->value)); + if (flags & EGSY__V_NORM) + { + fprintf (file, _(" code address: 0x%08x\n"), + (unsigned) bfd_getl32 (esdf->code_address)); + fprintf (file, _(" psect index for entry point : %u\n"), + (unsigned) bfd_getl32 (esdf->ca_psindx)); + } + fprintf (file, _(" psect index : %u\n"), + (unsigned) bfd_getl32 (esdf->psindx)); + rest = len - offsetof (struct vms_esdf, name); + fprintf (file, _(" name : %.*s\n"), + esdf->namlng > rest ? rest : esdf->namlng, + esdf->name); + } + else if (len >= offsetof (struct vms_esrf, name)) + { + struct vms_esrf *esrf = (struct vms_esrf *)e; - fprintf (file, _("SYM - Global symbol reference\n")); - fprintf (file, _(" name : %.*s\n"), - esrf->namlng, esrf->name); - } - } + fprintf (file, _("SYM - Global symbol reference\n")); + rest = len - offsetof (struct vms_esrf, name); + fprintf (file, _(" name : %.*s\n"), + esrf->namlng > rest ? rest : esrf->namlng, + esrf->name); + } + } break; case EGSD__C_IDC: - { - struct vms_eidc *eidc = (struct vms_eidc *)e; - unsigned int flags = bfd_getl32 (eidc->flags); - unsigned char *p; - - fprintf (file, _("IDC - Ident Consistency check\n")); - fprintf (file, _(" flags : 0x%08x"), flags); - if (flags & EIDC__V_BINIDENT) - fputs (" BINDENT", file); - fputc ('\n', file); - fprintf (file, _(" id match : %x\n"), - (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK); - fprintf (file, _(" error severity: %x\n"), - (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK); - p = eidc->name; - fprintf (file, _(" entity name : %.*s\n"), p[0], p + 1); - p += 1 + p[0]; - fprintf (file, _(" object name : %.*s\n"), p[0], p + 1); - p += 1 + p[0]; - if (flags & EIDC__V_BINIDENT) - fprintf (file, _(" binary ident : 0x%08x\n"), - (unsigned)bfd_getl32 (p + 1)); - else - fprintf (file, _(" ascii ident : %.*s\n"), p[0], p + 1); - } + if (len >= sizeof (struct vms_eidc)) + { + struct vms_eidc *eidc = (struct vms_eidc *) e; + unsigned int flags = bfd_getl32 (eidc->flags); + unsigned char *p; + + fprintf (file, _("IDC - Ident Consistency check\n")); + fprintf (file, _(" flags : 0x%08x"), flags); + if (flags & EIDC__V_BINIDENT) + fputs (" BINDENT", file); + fputc ('\n', file); + fprintf (file, _(" id match : %x\n"), + (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK); + fprintf (file, _(" error severity: %x\n"), + (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK); + p = eidc->name; + rest = len - (p - (unsigned char *) e); + fprintf (file, _(" entity name : %.*s\n"), + p[0] > rest - 1 ? rest - 1 : p[0], p + 1); + if (rest > 1u + p[0]) + { + rest -= 1 + p[0]; + p += 1 + p[0]; + fprintf (file, _(" object name : %.*s\n"), + p[0] > rest - 1 ? rest - 1 : p[0], p + 1); + if (rest > 1u + p[0]) + { + rest -= 1 + p[0]; + p += 1 + p[0]; + if (flags & EIDC__V_BINIDENT) + { + if (rest >= 4) + fprintf (file, _(" binary ident : 0x%08x\n"), + (unsigned) bfd_getl32 (p)); + } + else + fprintf (file, _(" ascii ident : %.*s\n"), + p[0] > rest - 1 ? rest - 1 : p[0], p + 1); + } + } + } break; case EGSD__C_SYMG: - { - struct vms_egst *egst = (struct vms_egst *)e; - unsigned int flags = bfd_getl16 (egst->header.flags); - - fprintf (file, _("SYMG - Universal symbol definition\n")); - fprintf (file, _(" flags: 0x%04x"), flags); - exav_bfd_print_egsy_flags (flags, file); - fputc ('\n', file); - fprintf (file, _(" symbol vector offset: 0x%08x\n"), - (unsigned)bfd_getl32 (egst->value)); - fprintf (file, _(" entry point: 0x%08x\n"), - (unsigned)bfd_getl32 (egst->lp_1)); - fprintf (file, _(" proc descr : 0x%08x\n"), - (unsigned)bfd_getl32 (egst->lp_2)); - fprintf (file, _(" psect index: %u\n"), - (unsigned)bfd_getl32 (egst->psindx)); - fprintf (file, _(" name : %.*s\n"), - egst->namlng, egst->name); - } + if (len >= offsetof (struct vms_egst, name)) + { + struct vms_egst *egst = (struct vms_egst *) e; + unsigned int flags = bfd_getl16 (egst->header.flags); + + fprintf (file, _("SYMG - Universal symbol definition\n")); + fprintf (file, _(" flags: 0x%04x"), flags); + exav_bfd_print_egsy_flags (flags, file); + fputc ('\n', file); + fprintf (file, _(" symbol vector offset: 0x%08x\n"), + (unsigned) bfd_getl32 (egst->value)); + fprintf (file, _(" entry point: 0x%08x\n"), + (unsigned) bfd_getl32 (egst->lp_1)); + fprintf (file, _(" proc descr : 0x%08x\n"), + (unsigned) bfd_getl32 (egst->lp_2)); + fprintf (file, _(" psect index: %u\n"), + (unsigned) bfd_getl32 (egst->psindx)); + rest = len - offsetof (struct vms_egst, name); + fprintf (file, _(" name : %.*s\n"), + egst->namlng > rest ? rest : egst->namlng, + egst->name); + } break; case EGSD__C_SYMV: - { - struct vms_esdfv *esdfv = (struct vms_esdfv *)e; - unsigned int flags = bfd_getl16 (esdfv->flags); - - fprintf (file, _("SYMV - Vectored symbol definition\n")); - fprintf (file, _(" flags: 0x%04x"), flags); - exav_bfd_print_egsy_flags (flags, file); - fputc ('\n', file); - fprintf (file, _(" vector : 0x%08x\n"), - (unsigned)bfd_getl32 (esdfv->vector)); - fprintf (file, _(" psect offset: %u\n"), - (unsigned)bfd_getl32 (esdfv->value)); - fprintf (file, _(" psect index : %u\n"), - (unsigned)bfd_getl32 (esdfv->psindx)); - fprintf (file, _(" name : %.*s\n"), - esdfv->namlng, esdfv->name); - } + if (len >= offsetof (struct vms_esdfv, name)) + { + struct vms_esdfv *esdfv = (struct vms_esdfv *) e; + unsigned int flags = bfd_getl16 (esdfv->flags); + + fprintf (file, _("SYMV - Vectored symbol definition\n")); + fprintf (file, _(" flags: 0x%04x"), flags); + exav_bfd_print_egsy_flags (flags, file); + fputc ('\n', file); + fprintf (file, _(" vector : 0x%08x\n"), + (unsigned) bfd_getl32 (esdfv->vector)); + fprintf (file, _(" psect offset: %u\n"), + (unsigned) bfd_getl32 (esdfv->value)); + fprintf (file, _(" psect index : %u\n"), + (unsigned) bfd_getl32 (esdfv->psindx)); + rest = len - offsetof (struct vms_esdfv, name); + fprintf (file, _(" name : %.*s\n"), + esdfv->namlng > rest ? rest : esdfv->namlng, + esdfv->name); + } break; case EGSD__C_SYMM: - { - struct vms_esdfm *esdfm = (struct vms_esdfm *)e; - unsigned int flags = bfd_getl16 (esdfm->flags); - - fprintf (file, _("SYMM - Global symbol definition with version\n")); - fprintf (file, _(" flags: 0x%04x"), flags); - exav_bfd_print_egsy_flags (flags, file); - fputc ('\n', file); - fprintf (file, _(" version mask: 0x%08x\n"), - (unsigned)bfd_getl32 (esdfm->version_mask)); - fprintf (file, _(" psect offset: %u\n"), - (unsigned)bfd_getl32 (esdfm->value)); - fprintf (file, _(" psect index : %u\n"), - (unsigned)bfd_getl32 (esdfm->psindx)); - fprintf (file, _(" name : %.*s\n"), - esdfm->namlng, esdfm->name); - } + if (len >= offsetof (struct vms_esdfm, name)) + { + struct vms_esdfm *esdfm = (struct vms_esdfm *) e; + unsigned int flags = bfd_getl16 (esdfm->flags); + + fprintf (file, + _("SYMM - Global symbol definition with version\n")); + fprintf (file, _(" flags: 0x%04x"), flags); + exav_bfd_print_egsy_flags (flags, file); + fputc ('\n', file); + fprintf (file, _(" version mask: 0x%08x\n"), + (unsigned)bfd_getl32 (esdfm->version_mask)); + fprintf (file, _(" psect offset: %u\n"), + (unsigned)bfd_getl32 (esdfm->value)); + fprintf (file, _(" psect index : %u\n"), + (unsigned)bfd_getl32 (esdfm->psindx)); + rest = len - offsetof (struct vms_esdfm, name); + fprintf (file, _(" name : %.*s\n"), + esdfm->namlng > rest ? rest : esdfm->namlng, + esdfm->name); + } break; default: fprintf (file, _("unhandled egsd entry type %u\n"), type); @@ -6147,8 +6367,12 @@ evax_bfd_print_hex (FILE *file, const char *pfx, } static void -evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps) +evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, + unsigned int len, int is_ps) { + if (is_ps ? len < 44 : len < 33) + return; + /* xgettext:c-format */ fprintf (file, _(" linkage index: %u, replacement insn: 0x%08x\n"), (unsigned)bfd_getl32 (buf), @@ -6170,62 +6394,71 @@ evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps) (unsigned)bfd_getl32 (buf + 40), (unsigned)bfd_getl32 (buf + 36)); else - fprintf (file, _(" global name: %.*s\n"), buf[32], buf + 33); + fprintf (file, _(" global name: %.*s\n"), + buf[32] > len - 33 ? len - 33 : buf[32], + buf + 33); } static void evax_bfd_print_etir (FILE *file, const char *name, unsigned char *rec, unsigned int rec_len) { - unsigned int off = sizeof (struct vms_egsd); - unsigned int sec_len = 0; + unsigned int off = sizeof (struct vms_eobjrec); /* xgettext:c-format */ - fprintf (file, _(" %s (len=%u+%u):\n"), name, - (unsigned)(rec_len - sizeof (struct vms_eobjrec)), - (unsigned)sizeof (struct vms_eobjrec)); + fprintf (file, _(" %s (len=%u):\n"), name, (unsigned) rec_len); + if (rec_len < sizeof (struct vms_eobjrec) + sizeof (struct vms_etir)) + return; - for (off = sizeof (struct vms_eobjrec); off < rec_len; ) + while (off <= rec_len - sizeof (struct vms_etir)) { struct vms_etir *etir = (struct vms_etir *)(rec + off); unsigned char *buf; unsigned int type; unsigned int size; + unsigned int rest; type = bfd_getl16 (etir->rectyp); size = bfd_getl16 (etir->size); buf = rec + off + sizeof (struct vms_etir); - if (off + size > rec_len || off + size < off) + if (size < sizeof (struct vms_etir) || size > rec_len - off) { - fprintf (file, _(" Error: length larger than remaining space in record\n")); + fprintf (file, _(" Erroneous length\n")); return; } /* xgettext:c-format */ - fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4); + fprintf (file, _(" (type: %3u, size: %3u): "), type, size); + rest = size - sizeof (struct vms_etir); switch (type) { case ETIR__C_STA_GBL: - fprintf (file, _("STA_GBL (stack global) %.*s\n"), - buf[0], buf + 1); + if (rest >= 1) + fprintf (file, _("STA_GBL (stack global) %.*s\n"), + buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1); break; case ETIR__C_STA_LW: - fprintf (file, _("STA_LW (stack longword) 0x%08x\n"), - (unsigned)bfd_getl32 (buf)); + fprintf (file, _("STA_LW (stack longword)")); + if (rest >= 4) + fprintf (file, " 0x%08x\n", + (unsigned) bfd_getl32 (buf)); break; case ETIR__C_STA_QW: - fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"), - (unsigned)bfd_getl32 (buf + 4), - (unsigned)bfd_getl32 (buf + 0)); + fprintf (file, _("STA_QW (stack quadword)")); + if (rest >= 8) + fprintf (file, " 0x%08x %08x\n", + (unsigned) bfd_getl32 (buf + 4), + (unsigned) bfd_getl32 (buf + 0)); break; case ETIR__C_STA_PQ: fprintf (file, _("STA_PQ (stack psect base + offset)\n")); - /* xgettext:c-format */ - fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"), - (unsigned)bfd_getl32 (buf + 0), - (unsigned)bfd_getl32 (buf + 8), - (unsigned)bfd_getl32 (buf + 4)); + if (rest >= 12) + /* xgettext:c-format */ + fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"), + (unsigned) bfd_getl32 (buf + 0), + (unsigned) bfd_getl32 (buf + 8), + (unsigned) bfd_getl32 (buf + 4)); break; case ETIR__C_STA_LI: fprintf (file, _("STA_LI (stack literal)\n")); @@ -6250,22 +6483,26 @@ evax_bfd_print_etir (FILE *file, const char *name, fprintf (file, _("STO_QW (store quadword)\n")); break; case ETIR__C_STO_IMMR: - { - unsigned int len = bfd_getl32 (buf); - fprintf (file, - _("STO_IMMR (store immediate repeat) %u bytes\n"), - len); - evax_bfd_print_hex (file, " ", buf + 4, len); - sec_len += len; - } + if (rest >= 4) + { + unsigned int rpt = bfd_getl32 (buf); + fprintf (file, + _("STO_IMMR (store immediate repeat) %u bytes\n"), + rpt); + if (rpt > rest - 4) + rpt = rest - 4; + evax_bfd_print_hex (file, " ", buf + 4, rpt); + } break; case ETIR__C_STO_GBL: - fprintf (file, _("STO_GBL (store global) %.*s\n"), - buf[0], buf + 1); + if (rest >= 1) + fprintf (file, _("STO_GBL (store global) %.*s\n"), + buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1); break; case ETIR__C_STO_CA: - fprintf (file, _("STO_CA (store code address) %.*s\n"), - buf[0], buf + 1); + if (rest >= 1) + fprintf (file, _("STO_CA (store code address) %.*s\n"), + buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1); break; case ETIR__C_STO_RB: fprintf (file, _("STO_RB (store relative branch)\n")); @@ -6277,18 +6514,21 @@ evax_bfd_print_etir (FILE *file, const char *name, fprintf (file, _("STO_OFF (store offset to psect)\n")); break; case ETIR__C_STO_IMM: - { - unsigned int len = bfd_getl32 (buf); - fprintf (file, - _("STO_IMM (store immediate) %u bytes\n"), - len); - evax_bfd_print_hex (file, " ", buf + 4, len); - sec_len += len; - } + if (rest >= 4) + { + unsigned int rpt = bfd_getl32 (buf); + fprintf (file, + _("STO_IMM (store immediate) %u bytes\n"), + rpt); + if (rpt > rest - 4) + rpt = rest - 4; + evax_bfd_print_hex (file, " ", buf + 4, rpt); + } break; case ETIR__C_STO_GBL_LW: - fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"), - buf[0], buf + 1); + if (rest >= 1) + fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"), + buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1); break; case ETIR__C_STO_LP_PSB: fprintf (file, _("STO_OFF (store LP with procedure signature)\n")); @@ -6358,65 +6598,79 @@ evax_bfd_print_etir (FILE *file, const char *name, case ETIR__C_STC_LP_PSB: fprintf (file, _("STC_LP_PSB (store cond linkage pair + signature)\n")); - /* xgettext:c-format */ - fprintf (file, _(" linkage index: %u, procedure: %.*s\n"), - (unsigned)bfd_getl32 (buf), buf[4], buf + 5); - buf += 4 + 1 + buf[4]; - fprintf (file, _(" signature: %.*s\n"), buf[0], buf + 1); + if (rest >= 5) + { + /* xgettext:c-format */ + fprintf (file, _(" linkage index: %u, procedure: %.*s\n"), + (unsigned) bfd_getl32 (buf), + buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5); + if (rest > 4 + 1u + buf[4]) + { + rest -= 4 + 1 + buf[4]; + buf += 4 + 1 + buf[4]; + fprintf (file, _(" signature: %.*s\n"), + buf[0] > rest - 1 ? rest - 1: buf[0], buf + 1); + } + } break; case ETIR__C_STC_GBL: fprintf (file, _("STC_GBL (store cond global)\n")); - /* xgettext:c-format */ - fprintf (file, _(" linkage index: %u, global: %.*s\n"), - (unsigned)bfd_getl32 (buf), buf[4], buf + 5); + if (rest >= 5) + /* xgettext:c-format */ + fprintf (file, _(" linkage index: %u, global: %.*s\n"), + (unsigned) bfd_getl32 (buf), + buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5); break; case ETIR__C_STC_GCA: fprintf (file, _("STC_GCA (store cond code address)\n")); - /* xgettext:c-format */ - fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"), - (unsigned)bfd_getl32 (buf), buf[4], buf + 5); + if (rest >= 5) + /* xgettext:c-format */ + fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"), + (unsigned) bfd_getl32 (buf), + buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5); break; case ETIR__C_STC_PS: fprintf (file, _("STC_PS (store cond psect + offset)\n")); - fprintf (file, - /* xgettext:c-format */ - _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"), - (unsigned)bfd_getl32 (buf), - (unsigned)bfd_getl32 (buf + 4), - (unsigned)bfd_getl32 (buf + 12), - (unsigned)bfd_getl32 (buf + 8)); + if (rest >= 16) + fprintf (file, + /* xgettext:c-format */ + _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"), + (unsigned)bfd_getl32 (buf), + (unsigned)bfd_getl32 (buf + 4), + (unsigned)bfd_getl32 (buf + 12), + (unsigned)bfd_getl32 (buf + 8)); break; case ETIR__C_STC_NOP_GBL: fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 0); + evax_bfd_print_etir_stc_ir (file, buf, rest, 0); break; case ETIR__C_STC_NOP_PS: fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 1); + evax_bfd_print_etir_stc_ir (file, buf, rest, 1); break; case ETIR__C_STC_BSR_GBL: fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 0); + evax_bfd_print_etir_stc_ir (file, buf, rest, 0); break; case ETIR__C_STC_BSR_PS: fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 1); + evax_bfd_print_etir_stc_ir (file, buf, rest, 1); break; case ETIR__C_STC_LDA_GBL: fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 0); + evax_bfd_print_etir_stc_ir (file, buf, rest, 0); break; case ETIR__C_STC_LDA_PS: fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 1); + evax_bfd_print_etir_stc_ir (file, buf, rest, 1); break; case ETIR__C_STC_BOH_GBL: fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 0); + evax_bfd_print_etir_stc_ir (file, buf, rest, 0); break; case ETIR__C_STC_BOH_PS: fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n")); - evax_bfd_print_etir_stc_ir (file, buf, 1); + evax_bfd_print_etir_stc_ir (file, buf, rest, 1); break; case ETIR__C_STC_NBH_GBL: fprintf (file, @@ -6429,13 +6683,14 @@ evax_bfd_print_etir (FILE *file, const char *name, case ETIR__C_CTL_SETRB: fprintf (file, _("CTL_SETRB (set relocation base)\n")); - sec_len += 4; break; case ETIR__C_CTL_AUGRB: - { - unsigned int val = bfd_getl32 (buf); - fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val); - } + if (rest >= 4) + { + unsigned int val = bfd_getl32 (buf); + fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), + val); + } break; case ETIR__C_CTL_DFLOC: fprintf (file, _("CTL_DFLOC (define location)\n")); @@ -6457,8 +6712,8 @@ evax_bfd_print_etir (FILE *file, const char *name, static void evax_bfd_print_eobj (struct bfd *abfd, FILE *file) { - bfd_boolean is_first = TRUE; - bfd_boolean has_records = FALSE; + bool is_first = true; + bool has_records = false; while (1) { @@ -6472,7 +6727,7 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file) { unsigned char buf[6]; - is_first = FALSE; + is_first = false; /* Read 6 bytes. */ if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf)) @@ -6485,13 +6740,13 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file) && bfd_getl16 (buf + 2) == EOBJ__C_EMH) { /* The format is raw: record-size, type, record-size. */ - has_records = TRUE; + has_records = true; pad_len = (rec_len + 1) & ~1U; hdr_size = 4; } else if (rec_len == EOBJ__C_EMH) { - has_records = FALSE; + has_records = false; pad_len = bfd_getl16 (buf + 2); hdr_size = 6; } @@ -6582,40 +6837,41 @@ evax_bfd_print_eobj (struct bfd *abfd, FILE *file) } static void -evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel, +evax_bfd_print_relocation_records (FILE *file, const unsigned char *buf, + size_t buf_size, size_t off, unsigned int stride) { - while (1) + while (off <= buf_size - 8) { unsigned int base; unsigned int count; unsigned int j; - count = bfd_getl32 (rel + 0); + count = bfd_getl32 (buf + off + 0); if (count == 0) break; - base = bfd_getl32 (rel + 4); + base = bfd_getl32 (buf + off + 4); /* xgettext:c-format */ fprintf (file, _(" bitcount: %u, base addr: 0x%08x\n"), count, base); - rel += 8; - for (j = 0; count > 0; j += 4, count -= 32) + off += 8; + for (j = 0; count > 0 && off <= buf_size - 4; j += 4, count -= 32) { unsigned int k; unsigned int n = 0; unsigned int val; - val = bfd_getl32 (rel); - rel += 4; + val = bfd_getl32 (buf + off); + off += 4; /* xgettext:c-format */ fprintf (file, _(" bitmap: 0x%08x (count: %u):\n"), val, count); for (k = 0; k < 32; k++) - if (val & (1 << k)) + if (val & (1u << k)) { if (n == 0) fputs (" ", file); @@ -6634,60 +6890,62 @@ evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel, } static void -evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel) +evax_bfd_print_address_fixups (FILE *file, const unsigned char *buf, + size_t buf_size, size_t off) { - while (1) + while (off <= buf_size - 8) { unsigned int j; unsigned int count; - count = bfd_getl32 (rel + 0); + count = bfd_getl32 (buf + off + 0); if (count == 0) return; /* xgettext:c-format */ fprintf (file, _(" image %u (%u entries)\n"), - (unsigned)bfd_getl32 (rel + 4), count); - rel += 8; - for (j = 0; j < count; j++) + (unsigned) bfd_getl32 (buf + off + 4), count); + off += 8; + for (j = 0; j < count && off <= buf_size - 8; j++) { /* xgettext:c-format */ fprintf (file, _(" offset: 0x%08x, val: 0x%08x\n"), - (unsigned)bfd_getl32 (rel + 0), - (unsigned)bfd_getl32 (rel + 4)); - rel += 8; + (unsigned) bfd_getl32 (buf + off + 0), + (unsigned) bfd_getl32 (buf + off + 4)); + off += 8; } } } static void -evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel) +evax_bfd_print_reference_fixups (FILE *file, const unsigned char *buf, + size_t buf_size, size_t off) { unsigned int count; - while (1) + while (off <= buf_size - 8) { unsigned int j; unsigned int n = 0; - count = bfd_getl32 (rel + 0); + count = bfd_getl32 (buf + off + 0); if (count == 0) break; /* xgettext:c-format */ fprintf (file, _(" image %u (%u entries), offsets:\n"), - (unsigned)bfd_getl32 (rel + 4), count); - rel += 8; - for (j = 0; j < count; j++) + (unsigned) bfd_getl32 (buf + off + 4), count); + off += 8; + for (j = 0; j < count && off <= buf_size - 4; j++) { if (n == 0) fputs (" ", file); - fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel)); + fprintf (file, _(" 0x%08x"), (unsigned) bfd_getl32 (buf + off)); n++; if (n == 7) { fputs ("\n", file); n = 0; } - rel += 4; + off += 4; } if (n) fputs ("\n", file); @@ -6790,8 +7048,12 @@ evax_bfd_get_dsc_name (unsigned int v) } static void -evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) +evax_bfd_print_desc (const unsigned char *buf, unsigned int bufsize, + int indent, FILE *file) { + if (bufsize < 8) + return; + unsigned char bclass = buf[3]; unsigned char dtype = buf[2]; unsigned int len = (unsigned)bfd_getl16 (buf); @@ -6820,38 +7082,47 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) evax_bfd_print_indent (indent, file); fprintf (file, _("non-contiguous array of %s\n"), evax_bfd_get_dsc_name (dsc->dtype)); - evax_bfd_print_indent (indent + 1, file); - fprintf (file, - /* xgettext:c-format */ - _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"), - dsc->dimct, dsc->aflags, dsc->digits, dsc->scale); - evax_bfd_print_indent (indent + 1, file); - fprintf (file, - /* xgettext:c-format */ - _("arsize: %u, a0: 0x%08x\n"), - (unsigned)bfd_getl32 (dsc->arsize), - (unsigned)bfd_getl32 (dsc->a0)); - evax_bfd_print_indent (indent + 1, file); - fprintf (file, _("Strides:\n")); - b = buf + sizeof (*dsc); - for (i = 0; i < dsc->dimct; i++) - { - evax_bfd_print_indent (indent + 2, file); - fprintf (file, "[%u]: %u\n", i + 1, - (unsigned)bfd_getl32 (b)); - b += 4; - } - evax_bfd_print_indent (indent + 1, file); - fprintf (file, _("Bounds:\n")); - b = buf + sizeof (*dsc); - for (i = 0; i < dsc->dimct; i++) + if (bufsize >= sizeof (*dsc)) { - evax_bfd_print_indent (indent + 2, file); - /* xgettext:c-format */ - fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1, - (unsigned)bfd_getl32 (b + 0), - (unsigned)bfd_getl32 (b + 4)); - b += 8; + evax_bfd_print_indent (indent + 1, file); + fprintf (file, + /* xgettext:c-format */ + _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"), + dsc->dimct, dsc->aflags, dsc->digits, dsc->scale); + evax_bfd_print_indent (indent + 1, file); + fprintf (file, + /* xgettext:c-format */ + _("arsize: %u, a0: 0x%08x\n"), + (unsigned) bfd_getl32 (dsc->arsize), + (unsigned) bfd_getl32 (dsc->a0)); + evax_bfd_print_indent (indent + 1, file); + fprintf (file, _("Strides:\n")); + b = buf + sizeof (*dsc); + bufsize -= sizeof (*dsc); + for (i = 0; i < dsc->dimct; i++) + { + if (bufsize < 4) + break; + evax_bfd_print_indent (indent + 2, file); + fprintf (file, "[%u]: %u\n", i + 1, + (unsigned) bfd_getl32 (b)); + b += 4; + bufsize -= 4; + } + evax_bfd_print_indent (indent + 1, file); + fprintf (file, _("Bounds:\n")); + for (i = 0; i < dsc->dimct; i++) + { + if (bufsize < 8) + break; + evax_bfd_print_indent (indent + 2, file); + /* xgettext:c-format */ + fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1, + (unsigned) bfd_getl32 (b + 0), + (unsigned) bfd_getl32 (b + 4)); + b += 8; + bufsize -= 8; + } } } break; @@ -6862,12 +7133,15 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) evax_bfd_print_indent (indent, file); fprintf (file, _("unaligned bit-string of %s\n"), evax_bfd_get_dsc_name (ubs->dtype)); - evax_bfd_print_indent (indent + 1, file); - fprintf (file, - /* xgettext:c-format */ - _("base: %u, pos: %u\n"), - (unsigned)bfd_getl32 (ubs->base), - (unsigned)bfd_getl32 (ubs->pos)); + if (bufsize >= sizeof (*ubs)) + { + evax_bfd_print_indent (indent + 1, file); + fprintf (file, + /* xgettext:c-format */ + _("base: %u, pos: %u\n"), + (unsigned) bfd_getl32 (ubs->base), + (unsigned) bfd_getl32 (ubs->pos)); + } } break; default: @@ -6878,16 +7152,21 @@ evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file) } static unsigned int -evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) +evax_bfd_print_valspec (const unsigned char *buf, unsigned int bufsize, + int indent, FILE *file) { + if (bufsize < 5) + return bufsize; + unsigned int vflags = buf[0]; - unsigned int value = (unsigned)bfd_getl32 (buf + 1); + unsigned int value = (unsigned) bfd_getl32 (buf + 1); unsigned int len = 5; evax_bfd_print_indent (indent, file); /* xgettext:c-format */ fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value); buf += 5; + bufsize -= 5; switch (vflags) { @@ -6902,7 +7181,8 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) break; case DST__K_VFLAGS_DSC: fprintf (file, _("(descriptor)\n")); - evax_bfd_print_desc (buf + value, indent + 1, file); + if (value <= bufsize) + evax_bfd_print_desc (buf + value, bufsize - value, indent + 1, file); break; case DST__K_VFLAGS_TVS: fprintf (file, _("(trailing value)\n")); @@ -6941,29 +7221,36 @@ evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file) } static void -evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file) +evax_bfd_print_typspec (const unsigned char *buf, unsigned int bufsize, + int indent, FILE *file) { + if (bufsize < 3) + return; + unsigned char kind = buf[2]; - unsigned int len = (unsigned)bfd_getl16 (buf); + unsigned int len = (unsigned) bfd_getl16 (buf); evax_bfd_print_indent (indent, file); /* xgettext:c-format */ fprintf (file, _("len: %2u, kind: %2u "), len, kind); buf += 3; + bufsize -= 3; switch (kind) { case DST__K_TS_ATOM: /* xgettext:c-format */ - fprintf (file, _("atomic, type=0x%02x %s\n"), - buf[0], evax_bfd_get_dsc_name (buf[0])); + if (bufsize >= 1) + fprintf (file, _("atomic, type=0x%02x %s\n"), + buf[0], evax_bfd_get_dsc_name (buf[0])); break; case DST__K_TS_IND: - fprintf (file, _("indirect, defined at 0x%08x\n"), - (unsigned)bfd_getl32 (buf)); + if (bufsize >= 4) + fprintf (file, _("indirect, defined at 0x%08x\n"), + (unsigned) bfd_getl32 (buf)); break; case DST__K_TS_TPTR: fprintf (file, _("typed pointer\n")); - evax_bfd_print_typspec (buf, indent + 1, file); + evax_bfd_print_typspec (buf, bufsize, indent + 1, file); break; case DST__K_TS_PTR: fprintf (file, _("pointer\n")); @@ -6971,29 +7258,51 @@ evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file) case DST__K_TS_ARRAY: { const unsigned char *vs; + unsigned int vs_len; unsigned int vec_len; unsigned int i; + if (bufsize == 0) + return; fprintf (file, _("array, dim: %u, bitmap: "), buf[0]); + --bufsize; vec_len = (buf[0] + 1 + 7) / 8; for (i = 0; i < vec_len; i++) - fprintf (file, " %02x", buf[i + 1]); + { + if (bufsize == 0) + break; + fprintf (file, " %02x", buf[i + 1]); + --bufsize; + } fputc ('\n', file); + if (bufsize == 0) + return; vs = buf + 1 + vec_len; evax_bfd_print_indent (indent, file); fprintf (file, _("array descriptor:\n")); - vs += evax_bfd_print_valspec (vs, indent + 1, file); - for (i = 0; i < buf[0] + 1U; i++) - if (buf[1 + i / 8] & (1 << (i % 8))) - { - evax_bfd_print_indent (indent, file); - if (i == 0) - fprintf (file, _("type spec for element:\n")); - else - fprintf (file, _("type spec for subscript %u:\n"), i); - evax_bfd_print_typspec (vs, indent + 1, file); - vs += bfd_getl16 (vs); - } + vs_len = evax_bfd_print_valspec (vs, bufsize, indent + 1, file); + vs += vs_len; + if (bufsize > vs_len) + { + bufsize -= vs_len; + for (i = 0; i < buf[0] + 1U; i++) + if (buf[1 + i / 8] & (1 << (i % 8))) + { + evax_bfd_print_indent (indent, file); + if (i == 0) + fprintf (file, _("type spec for element:\n")); + else + fprintf (file, _("type spec for subscript %u:\n"), i); + evax_bfd_print_typspec (vs, bufsize, indent + 1, file); + if (bufsize < 2) + break; + vs_len = bfd_getl16 (vs); + if (bufsize <= vs_len) + break; + vs += vs_len; + bufsize -= vs_len; + } + } } break; default: @@ -7027,20 +7336,24 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) /* xgettext:c-format */ fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "), type, len, off); - if (len == 0) + if (len < sizeof (dsth)) { fputc ('\n', file); break; } - len++; dst_size -= len; off += len; len -= sizeof (dsth); - buf = bfd_malloc (len); - if (bfd_bread (buf, len, abfd) != len) + if (len == 0) + buf = NULL; + else { - fprintf (file, _("cannot read DST symbol\n")); - return; + buf = _bfd_malloc_and_read (abfd, len, len); + if (buf == NULL) + { + fprintf (file, _("cannot read DST symbol\n")); + return; + } } switch (type) { @@ -7084,15 +7397,19 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) case DSC__K_DTYPE_VT2: fprintf (file, _("standard data: %s\n"), evax_bfd_get_dsc_name (type)); - evax_bfd_print_valspec (buf, 4, file); - fprintf (file, _(" name: %.*s\n"), buf[5], buf + 6); + evax_bfd_print_valspec (buf, len, 4, file); + if (len > 6) + fprintf (file, _(" name: %.*s\n"), + buf[5] > len - 6 ? len - 6 : buf[5], buf + 6); break; case DST__K_MODBEG: { struct vms_dst_modbeg *dst = (void *)buf; - const char *name = (const char *)buf + sizeof (*dst); + unsigned char *name = buf + sizeof (*dst); fprintf (file, _("modbeg\n")); + if (len < sizeof (*dst)) + break; /* xgettext:c-format */ fprintf (file, _(" flags: %d, language: %u, " "major: %u, minor: %u\n"), @@ -7100,11 +7417,21 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) (unsigned)bfd_getl32 (dst->language), (unsigned)bfd_getl16 (dst->major), (unsigned)bfd_getl16 (dst->minor)); - fprintf (file, _(" module name: %.*s\n"), - name[0], name + 1); - name += name[0] + 1; - fprintf (file, _(" compiler : %.*s\n"), - name[0], name + 1); + len -= sizeof (*dst); + if (len > 0) + { + int nlen = len - 1; + fprintf (file, _(" module name: %.*s\n"), + name[0] > nlen ? nlen : name[0], name + 1); + if (name[0] < nlen) + { + len -= name[0] + 1; + name += name[0] + 1; + nlen = len - 1; + fprintf (file, _(" compiler : %.*s\n"), + name[0] > nlen ? nlen : name[0], name + 1); + } + } } break; case DST__K_MODEND: @@ -7113,98 +7440,142 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) case DST__K_RTNBEG: { struct vms_dst_rtnbeg *dst = (void *)buf; - const char *name = (const char *)buf + sizeof (*dst); + unsigned char *name = buf + sizeof (*dst); fputs (_("rtnbeg\n"), file); - /* xgettext:c-format */ - fprintf (file, _(" flags: %u, address: 0x%08x, " - "pd-address: 0x%08x\n"), - dst->flags, - (unsigned)bfd_getl32 (dst->address), - (unsigned)bfd_getl32 (dst->pd_address)); - fprintf (file, _(" routine name: %.*s\n"), - name[0], name + 1); + if (len >= sizeof (*dst)) + { + /* xgettext:c-format */ + fprintf (file, _(" flags: %u, address: 0x%08x, " + "pd-address: 0x%08x\n"), + dst->flags, + (unsigned) bfd_getl32 (dst->address), + (unsigned) bfd_getl32 (dst->pd_address)); + len -= sizeof (*dst); + if (len > 0) + { + int nlen = len - 1; + fprintf (file, _(" routine name: %.*s\n"), + name[0] > nlen ? nlen : name[0], name + 1); + } + } } break; case DST__K_RTNEND: { struct vms_dst_rtnend *dst = (void *)buf; - fprintf (file, _("rtnend: size 0x%08x\n"), - (unsigned)bfd_getl32 (dst->size)); + if (len >= sizeof (*dst)) + fprintf (file, _("rtnend: size 0x%08x\n"), + (unsigned) bfd_getl32 (dst->size)); } break; case DST__K_PROLOG: { struct vms_dst_prolog *dst = (void *)buf; - fprintf (file, _("prolog: bkpt address 0x%08x\n"), - (unsigned)bfd_getl32 (dst->bkpt_addr)); + if (len >= sizeof (*dst)) + /* xgettext:c-format */ + fprintf (file, _("prolog: bkpt address 0x%08x\n"), + (unsigned) bfd_getl32 (dst->bkpt_addr)); } break; case DST__K_EPILOG: { struct vms_dst_epilog *dst = (void *)buf; - /* xgettext:c-format */ - fprintf (file, _("epilog: flags: %u, count: %u\n"), - dst->flags, (unsigned)bfd_getl32 (dst->count)); + if (len >= sizeof (*dst)) + /* xgettext:c-format */ + fprintf (file, _("epilog: flags: %u, count: %u\n"), + dst->flags, (unsigned) bfd_getl32 (dst->count)); } break; case DST__K_BLKBEG: { struct vms_dst_blkbeg *dst = (void *)buf; - const char *name = (const char *)buf + sizeof (*dst); + unsigned char *name = buf + sizeof (*dst); - /* xgettext:c-format */ - fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"), - (unsigned)bfd_getl32 (dst->address), - name[0], name + 1); + if (len > sizeof (*dst)) + { + int nlen; + len -= sizeof (*dst); + nlen = len - 1; + /* xgettext:c-format */ + fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"), + (unsigned) bfd_getl32 (dst->address), + name[0] > nlen ? nlen : name[0], name + 1); + } } break; case DST__K_BLKEND: { struct vms_dst_blkend *dst = (void *)buf; - fprintf (file, _("blkend: size: 0x%08x\n"), - (unsigned)bfd_getl32 (dst->size)); + if (len >= sizeof (*dst)) + /* xgettext:c-format */ + fprintf (file, _("blkend: size: 0x%08x\n"), + (unsigned) bfd_getl32 (dst->size)); } break; case DST__K_TYPSPEC: { fprintf (file, _("typspec (len: %u)\n"), len); - fprintf (file, _(" name: %.*s\n"), buf[0], buf + 1); - evax_bfd_print_typspec (buf + 1 + buf[0], 5, file); + if (len >= 1) + { + int nlen = len - 1; + fprintf (file, _(" name: %.*s\n"), + buf[0] > nlen ? nlen : buf[0], buf + 1); + if (nlen > buf[0]) + evax_bfd_print_typspec (buf + 1 + buf[0], len - (1 + buf[0]), + 5, file); + } } break; case DST__K_SEPTYP: { - fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6); - evax_bfd_print_valspec (buf, 4, file); + if (len >= 6) + { + fprintf (file, _("septyp, name: %.*s\n"), + buf[5] > len - 6 ? len - 6 : buf[5], buf + 6); + evax_bfd_print_valspec (buf, len, 4, file); + } } break; case DST__K_RECBEG: { struct vms_dst_recbeg *recbeg = (void *)buf; - const char *name = (const char *)buf + sizeof (*recbeg); + unsigned char *name = buf + sizeof (*recbeg); - fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1); - evax_bfd_print_valspec (buf, 4, file); - fprintf (file, _(" len: %u bits\n"), - (unsigned)bfd_getl32 (name + 1 + name[0])); + if (len > sizeof (*recbeg)) + { + int nlen = len - sizeof (*recbeg) - 1; + if (name[0] < nlen) + nlen = name[0]; + fprintf (file, _("recbeg: name: %.*s\n"), nlen, name + 1); + evax_bfd_print_valspec (buf, len, 4, file); + len -= 1 + nlen; + if (len >= 4) + fprintf (file, _(" len: %u bits\n"), + (unsigned) bfd_getl32 (name + 1 + nlen)); + } } break; case DST__K_RECEND: fprintf (file, _("recend\n")); break; case DST__K_ENUMBEG: - /* xgettext:c-format */ - fprintf (file, _("enumbeg, len: %u, name: %.*s\n"), - buf[0], buf[1], buf + 2); + if (len >= 2) + /* xgettext:c-format */ + fprintf (file, _("enumbeg, len: %u, name: %.*s\n"), + buf[0], buf[1] > len - 2 ? len - 2 : buf[1], buf + 2); break; case DST__K_ENUMELT: - fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6); - evax_bfd_print_valspec (buf, 4, file); + if (len >= 6) + { + fprintf (file, _("enumelt, name: %.*s\n"), + buf[5] > len - 6 ? len - 6 : buf[5], buf + 6); + evax_bfd_print_valspec (buf, len, 4, file); + } break; case DST__K_ENUMEND: fprintf (file, _("enumend\n")); @@ -7212,26 +7583,36 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) case DST__K_LABEL: { struct vms_dst_label *lab = (void *)buf; - fprintf (file, _("label, name: %.*s\n"), - lab->name[0], lab->name + 1); - fprintf (file, _(" address: 0x%08x\n"), - (unsigned)bfd_getl32 (lab->value)); + if (len >= sizeof (*lab)) + { + fprintf (file, _("label, name: %.*s\n"), + lab->name[0] > len - 1 ? len - 1 : lab->name[0], + lab->name + 1); + fprintf (file, _(" address: 0x%08x\n"), + (unsigned) bfd_getl32 (lab->value)); + } } break; case DST__K_DIS_RANGE: - { - unsigned int cnt = bfd_getl32 (buf); - unsigned char *rng = buf + 4; - unsigned int i; - - fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt); - for (i = 0; i < cnt; i++, rng += 8) - /* xgettext:c-format */ - fprintf (file, _(" address: 0x%08x, size: %u\n"), - (unsigned)bfd_getl32 (rng), - (unsigned)bfd_getl32 (rng + 4)); + if (len >= 4) + { + unsigned int cnt = bfd_getl32 (buf); + unsigned char *rng = buf + 4; + unsigned int i; - } + fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt); + len -= 4; + for (i = 0; i < cnt; i++, rng += 8) + { + if (len < 8) + break; + /* xgettext:c-format */ + fprintf (file, _(" address: 0x%08x, size: %u\n"), + (unsigned) bfd_getl32 (rng), + (unsigned) bfd_getl32 (rng + 4)); + len -= 8; + } + } break; case DST__K_LINE_NUM: { @@ -7241,79 +7622,101 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) while (len > 0) { - signed char cmd; - unsigned char cmdlen; + int cmd; unsigned int val; + int cmdlen = -1; - cmd = buf[0]; - cmdlen = 0; + cmd = *buf++; + len--; fputs (" ", file); switch (cmd) { case DST__K_DELTA_PC_W: - val = bfd_getl16 (buf + 1); + if (len < 2) + break; + val = bfd_getl16 (buf); fprintf (file, _("delta_pc_w %u\n"), val); pc += val; line++; - cmdlen = 3; + cmdlen = 2; break; case DST__K_INCR_LINUM: - val = buf[1]; + if (len < 1) + break; + val = *buf; fprintf (file, _("incr_linum(b): +%u\n"), val); line += val; - cmdlen = 2; + cmdlen = 1; break; case DST__K_INCR_LINUM_W: - val = bfd_getl16 (buf + 1); + if (len < 2) + break; + val = bfd_getl16 (buf); fprintf (file, _("incr_linum_w: +%u\n"), val); line += val; - cmdlen = 3; + cmdlen = 2; break; case DST__K_INCR_LINUM_L: - val = bfd_getl32 (buf + 1); + if (len < 4) + break; + val = bfd_getl32 (buf); fprintf (file, _("incr_linum_l: +%u\n"), val); line += val; - cmdlen = 5; + cmdlen = 4; break; case DST__K_SET_LINUM: - line = bfd_getl16 (buf + 1); + if (len < 2) + break; + line = bfd_getl16 (buf); fprintf (file, _("set_line_num(w) %u\n"), line); - cmdlen = 3; + cmdlen = 2; break; case DST__K_SET_LINUM_B: - line = buf[1]; + if (len < 1) + break; + line = *buf; fprintf (file, _("set_line_num_b %u\n"), line); - cmdlen = 2; + cmdlen = 1; break; case DST__K_SET_LINUM_L: - line = bfd_getl32 (buf + 1); + if (len < 4) + break; + line = bfd_getl32 (buf); fprintf (file, _("set_line_num_l %u\n"), line); - cmdlen = 5; + cmdlen = 4; break; case DST__K_SET_ABS_PC: - pc = bfd_getl32 (buf + 1); + if (len < 4) + break; + pc = bfd_getl32 (buf); fprintf (file, _("set_abs_pc: 0x%08x\n"), pc); - cmdlen = 5; + cmdlen = 4; break; case DST__K_DELTA_PC_L: + if (len < 4) + break; fprintf (file, _("delta_pc_l: +0x%08x\n"), - (unsigned)bfd_getl32 (buf + 1)); - cmdlen = 5; + (unsigned) bfd_getl32 (buf)); + cmdlen = 4; break; case DST__K_TERM: - fprintf (file, _("term(b): 0x%02x"), buf[1]); - pc += buf[1]; + if (len < 1) + break; + fprintf (file, _("term(b): 0x%02x"), *buf); + pc += *buf; fprintf (file, _(" pc: 0x%08x\n"), pc); - cmdlen = 2; + cmdlen = 1; break; case DST__K_TERM_W: - val = bfd_getl16 (buf + 1); + if (len < 2) + break; + val = bfd_getl16 (buf); fprintf (file, _("term_w: 0x%04x"), val); pc += val; fprintf (file, _(" pc: 0x%08x\n"), pc); - cmdlen = 3; + cmdlen = 2; break; default: if (cmd <= 0) @@ -7324,13 +7727,13 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) /* xgettext:c-format */ fprintf (file, _(" pc: 0x%08x line: %5u\n"), pc, line); - cmdlen = 1; + cmdlen = 0; } else fprintf (file, _(" *unhandled* cmd %u\n"), cmd); break; } - if (cmdlen == 0) + if (cmdlen < 0) break; len -= cmdlen; buf += cmdlen; @@ -7346,16 +7749,20 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) while (len > 0) { - signed char cmd = buf[0]; - unsigned char cmdlen = 0; + int cmd = *buf++; + int cmdlen = -1; + len--; switch (cmd) { case DST__K_SRC_DECLFILE: { - struct vms_dst_src_decl_src *src = (void *)(buf + 1); - const char *name; + struct vms_dst_src_decl_src *src = (void *) buf; + unsigned char *name; + int nlen; + if (len < sizeof (*src)) + break; /* xgettext:c-format */ fprintf (file, _(" declfile: len: %u, flags: %u, " "fileid: %u\n"), @@ -7370,58 +7777,80 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file) (unsigned)bfd_getl32 (src->rms_ebk), (unsigned)bfd_getl16 (src->rms_ffb), src->rms_rfo); - name = (const char *)buf + 1 + sizeof (*src); + if (src->length > len || src->length <= sizeof (*src)) + break; + nlen = src->length - sizeof (*src) - 1; + name = buf + sizeof (*src); fprintf (file, _(" filename : %.*s\n"), - name[0], name + 1); + name[0] > nlen ? nlen : name[0], name + 1); + if (name[0] >= nlen) + break; + nlen -= name[0] + 1; name += name[0] + 1; fprintf (file, _(" module name: %.*s\n"), - name[0], name + 1); - cmdlen = 2 + src->length; + name[0] > nlen ? nlen : name[0], name + 1); + if (name[0] > nlen) + break; + cmdlen = src->length; } break; case DST__K_SRC_SETFILE: + if (len < 2) + break; fprintf (file, _(" setfile %u\n"), - (unsigned)bfd_getl16 (buf + 1)); - cmdlen = 3; + (unsigned) bfd_getl16 (buf)); + cmdlen = 2; break; case DST__K_SRC_SETREC_W: + if (len < 2) + break; fprintf (file, _(" setrec %u\n"), - (unsigned)bfd_getl16 (buf + 1)); - cmdlen = 3; + (unsigned) bfd_getl16 (buf)); + cmdlen = 2; break; case DST__K_SRC_SETREC_L: + if (len < 4) + break; fprintf (file, _(" setrec %u\n"), - (unsigned)bfd_getl32 (buf + 1)); - cmdlen = 5; + (unsigned) bfd_getl32 (buf)); + cmdlen = 4; break; case DST__K_SRC_SETLNUM_W: + if (len < 2) + break; fprintf (file, _(" setlnum %u\n"), - (unsigned)bfd_getl16 (buf + 1)); - cmdlen = 3; + (unsigned) bfd_getl16 (buf)); + cmdlen = 2; break; case DST__K_SRC_SETLNUM_L: + if (len < 4) + break; fprintf (file, _(" setlnum %u\n"), - (unsigned)bfd_getl32 (buf + 1)); - cmdlen = 5; + (unsigned) bfd_getl32 (buf)); + cmdlen = 4; break; case DST__K_SRC_DEFLINES_W: + if (len < 2) + break; fprintf (file, _(" deflines %u\n"), - (unsigned)bfd_getl16 (buf + 1)); - cmdlen = 3; + (unsigned) bfd_getl16 (buf)); + cmdlen = 2; break; case DST__K_SRC_DEFLINES_B: - fprintf (file, _(" deflines %u\n"), buf[1]); - cmdlen = 2; + if (len < 1) + break; + fprintf (file, _(" deflines %u\n"), *buf); + cmdlen = 1; break; case DST__K_SRC_FORMFEED: fprintf (file, _(" formfeed\n")); - cmdlen = 1; + cmdlen = 0; break; default: fprintf (file, _(" *unhandled* cmd %u\n"), cmd); break; } - if (cmdlen == 0) + if (cmdlen < 0) break; len -= cmdlen; buf += cmdlen; @@ -7595,7 +8024,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } mask = bfd_getl32 (eihvn.subsystem_mask); for (j = 0; j < 32; j++) - if (mask & (1 << j)) + if (mask & (1u << j)) { struct vms_eihvn_subversion ver; if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver)) @@ -7939,7 +8368,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) fprintf (file, _("Global symbol table:\n")); evax_bfd_print_eobj (abfd, file); } - if (eiaf_vbn != 0) + if (eiaf_vbn != 0 && eiaf_size >= sizeof (struct vms_eiaf)) { unsigned char *buf; struct vms_eiaf *eiaf; @@ -7952,14 +8381,12 @@ evax_bfd_print_image (bfd *abfd, FILE *file) unsigned int codeadroff; unsigned int lpfixoff; unsigned int chgprtoff; + file_ptr f_off = (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE; - buf = bfd_malloc (eiaf_size); - - if (bfd_seek (abfd, (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) - || bfd_bread (buf, eiaf_size, abfd) != eiaf_size) + if (bfd_seek (abfd, f_off, SEEK_SET) != 0 + || (buf = _bfd_malloc_and_read (abfd, eiaf_size, eiaf_size)) == NULL) { fprintf (file, _("cannot read EIHA\n")); - free (buf); return; } eiaf = (struct vms_eiaf *)buf; @@ -8013,12 +8440,14 @@ evax_bfd_print_image (bfd *abfd, FILE *file) if (shlstoff) { - struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff); unsigned int j; fprintf (file, _(" Shareable images:\n")); - for (j = 0; j < shrimgcnt; j++, shl++) + for (j = 0; + j < shrimgcnt && shlstoff <= eiaf_size - sizeof (struct vms_shl); + j++, shlstoff += sizeof (struct vms_shl)) { + struct vms_shl *shl = (struct vms_shl *) (buf + shlstoff); fprintf (file, /* xgettext:c-format */ _(" %u: size: %u, flags: 0x%02x, name: %.*s\n"), @@ -8029,50 +8458,54 @@ evax_bfd_print_image (bfd *abfd, FILE *file) if (qrelfixoff != 0) { fprintf (file, _(" quad-word relocation fixups:\n")); - evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8); + evax_bfd_print_relocation_records (file, buf, eiaf_size, + qrelfixoff, 8); } if (lrelfixoff != 0) { fprintf (file, _(" long-word relocation fixups:\n")); - evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4); + evax_bfd_print_relocation_records (file, buf, eiaf_size, + lrelfixoff, 4); } if (qdotadroff != 0) { fprintf (file, _(" quad-word .address reference fixups:\n")); - evax_bfd_print_address_fixups (file, buf + qdotadroff); + evax_bfd_print_address_fixups (file, buf, eiaf_size, qdotadroff); } if (ldotadroff != 0) { fprintf (file, _(" long-word .address reference fixups:\n")); - evax_bfd_print_address_fixups (file, buf + ldotadroff); + evax_bfd_print_address_fixups (file, buf, eiaf_size, ldotadroff); } if (codeadroff != 0) { fprintf (file, _(" Code Address Reference Fixups:\n")); - evax_bfd_print_reference_fixups (file, buf + codeadroff); + evax_bfd_print_reference_fixups (file, buf, eiaf_size, codeadroff); } if (lpfixoff != 0) { fprintf (file, _(" Linkage Pairs Reference Fixups:\n")); - evax_bfd_print_reference_fixups (file, buf + lpfixoff); + evax_bfd_print_reference_fixups (file, buf, eiaf_size, lpfixoff); } - if (chgprtoff) + if (chgprtoff && chgprtoff <= eiaf_size - 4) { - unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff); - struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4); + unsigned int count = (unsigned) bfd_getl32 (buf + chgprtoff); unsigned int j; fprintf (file, _(" Change Protection (%u entries):\n"), count); - for (j = 0; j < count; j++, eicp++) + for (j = 0, chgprtoff += 4; + j < count && chgprtoff <= eiaf_size - sizeof (struct vms_eicp); + j++, chgprtoff += sizeof (struct vms_eicp)) { + struct vms_eicp *eicp = (struct vms_eicp *) (buf + chgprtoff); unsigned int prot = bfd_getl32 (eicp->newprt); fprintf (file, /* xgettext:c-format */ _(" base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "), - (unsigned)bfd_getl32 (eicp->baseva + 4), - (unsigned)bfd_getl32 (eicp->baseva + 0), - (unsigned)bfd_getl32 (eicp->size), - (unsigned)bfd_getl32 (eicp->newprt)); + (unsigned) bfd_getl32 (eicp->baseva + 4), + (unsigned) bfd_getl32 (eicp->baseva + 0), + (unsigned) bfd_getl32 (eicp->size), + (unsigned) bfd_getl32 (eicp->newprt)); switch (prot) { case PRT__C_NA: @@ -8134,7 +8567,7 @@ evax_bfd_print_image (bfd *abfd, FILE *file) } } -static bfd_boolean +static bool vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr) { FILE *file = (FILE *)ptr; @@ -8144,17 +8577,17 @@ vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr) else { if (bfd_seek (abfd, 0, SEEK_SET)) - return FALSE; + return false; evax_bfd_print_eobj (abfd, file); } - return TRUE; + return true; } /* Linking. */ /* Slurp ETIR/EDBG/ETBT VMS object records. */ -static bfd_boolean +static bool alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) { asection *cur_section; @@ -8163,7 +8596,7 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) file_ptr dst_offset; if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return FALSE; + return false; cur_section = NULL; cur_offset = 0; @@ -8188,13 +8621,13 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) while (1) { int type; - bfd_boolean res; + bool res; type = _bfd_vms_get_object_record (abfd); if (type < 0) { vms_debug2 ((2, "next_record failed\n")); - return FALSE; + return false; } switch (type) { @@ -8215,14 +8648,14 @@ alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info) dst_offset = PRIV (image_offset); break; case EOBJ__C_EEOM: - return TRUE; + return true; default: continue; } if (!res) { vms_debug2 ((2, "slurp eobj type %d failed\n", type)); - return FALSE; + return false; } } } @@ -8236,41 +8669,49 @@ alpha_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, /* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */ -static void +static bool alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib) { struct alpha_vms_shlib_el *sl; asection *sect = PRIV2 (src, image_section); file_ptr offset = PRIV2 (src, image_offset); + bfd_vma *p; sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs, struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index)); - sl->has_fixups = TRUE; - VEC_APPEND_EL (sl->lp, bfd_vma, - sect->output_section->vma + sect->output_offset + offset); + sl->has_fixups = true; + p = VEC_APPEND (sl->lp, bfd_vma); + if (p == NULL) + return false; + *p = sect->output_section->vma + sect->output_offset + offset; sect->output_section->flags |= SEC_RELOC; + return true; } /* Add a code address fixup at address SECT + OFFSET to SHLIB. */ -static void +static bool alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib) { struct alpha_vms_shlib_el *sl; asection *sect = PRIV2 (src, image_section); file_ptr offset = PRIV2 (src, image_offset); + bfd_vma *p; sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs, struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index)); - sl->has_fixups = TRUE; - VEC_APPEND_EL (sl->ca, bfd_vma, - sect->output_section->vma + sect->output_offset + offset); + sl->has_fixups = true; + p = VEC_APPEND (sl->ca, bfd_vma); + if (p == NULL) + return false; + *p = sect->output_section->vma + sect->output_offset + offset; sect->output_section->flags |= SEC_RELOC; + return true; } /* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */ -static void +static bool alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src, bfd *shlib, bfd_vma vec) { @@ -8281,32 +8722,37 @@ alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src, sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs, struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index)); - sl->has_fixups = TRUE; + sl->has_fixups = true; r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref); + if (r == NULL) + return false; r->vma = sect->output_section->vma + sect->output_offset + offset; r->ref = vec; sect->output_section->flags |= SEC_RELOC; + return true; } -static void +static bool alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED, unsigned int shr ATTRIBUTE_UNUSED, bfd_vma vec ATTRIBUTE_UNUSED) { /* Not yet supported. */ - abort (); + return false; } /* Add relocation. FIXME: Not yet emitted. */ -static void +static bool alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED) { + return false; } -static void +static bool alpha_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED) { + return false; } static struct bfd_hash_entry * @@ -8336,13 +8782,34 @@ alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry, return (struct bfd_hash_entry *) ret; } +static void +alpha_vms_bfd_link_hash_table_free (bfd *abfd) +{ + struct alpha_vms_link_hash_table *t; + unsigned i; + + t = (struct alpha_vms_link_hash_table *) abfd->link.hash; + for (i = 0; i < VEC_COUNT (t->shrlibs); i++) + { + struct alpha_vms_shlib_el *shlib; + + shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i); + free (&VEC_EL (shlib->ca, bfd_vma, 0)); + free (&VEC_EL (shlib->lp, bfd_vma, 0)); + free (&VEC_EL (shlib->qr, struct alpha_vms_vma_ref, 0)); + } + free (&VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, 0)); + + _bfd_generic_link_hash_table_free (abfd); +} + /* Create an Alpha/VMS link hash table. */ static struct bfd_link_hash_table * alpha_vms_bfd_link_hash_table_create (bfd *abfd) { struct alpha_vms_link_hash_table *ret; - bfd_size_type amt = sizeof (struct alpha_vms_link_hash_table); + size_t amt = sizeof (struct alpha_vms_link_hash_table); ret = (struct alpha_vms_link_hash_table *) bfd_malloc (amt); if (ret == NULL) @@ -8357,11 +8824,12 @@ alpha_vms_bfd_link_hash_table_create (bfd *abfd) VEC_INIT (ret->shrlibs); ret->fixup = NULL; + ret->root.hash_table_free = alpha_vms_bfd_link_hash_table_free; return &ret->root; } -static bfd_boolean +static bool alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) { unsigned int i; @@ -8374,14 +8842,14 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) asymbol sym; if (!alpha_vms_convert_symbol (abfd, e, &sym)) - return FALSE; + return false; if ((e->flags & EGSY__V_DEF) && abfd->selective_search) { /* In selective_search mode, only add definition that are required. */ h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup - (info->hash, sym.name, FALSE, FALSE, FALSE); + (info->hash, sym.name, false, false, false); if (h == NULL || h->root.type != bfd_link_hash_undefined) continue; } @@ -8391,8 +8859,8 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) h_root = (struct bfd_link_hash_entry *) h; if (!_bfd_generic_link_add_one_symbol (info, abfd, sym.name, sym.flags, sym.section, sym.value, NULL, - FALSE, FALSE, &h_root)) - return FALSE; + false, false, &h_root)) + return false; h = (struct alpha_vms_link_hash_entry *) h_root; if ((e->flags & EGSY__V_DEF) @@ -8411,6 +8879,8 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) shlib = VEC_APPEND (alpha_vms_link_hash (info)->shrlibs, struct alpha_vms_shlib_el); + if (shlib == NULL) + return false; shlib->abfd = abfd; VEC_INIT (shlib->ca); VEC_INIT (shlib->lp); @@ -8418,10 +8888,10 @@ alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) PRIV (shr_index) = VEC_COUNT (alpha_vms_link_hash (info)->shrlibs) - 1; } - return TRUE; + return true; } -static bfd_boolean +static bool alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) { int pass; @@ -8432,7 +8902,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (info->output_bfd->xvec != abfd->xvec) { bfd_set_error (bfd_error_wrong_format); - return FALSE; + return false; } /* The archive_pass field in the archive itself is used to @@ -8479,7 +8949,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) element = bfd_get_elt_at_index (abfd, symidx); if (element == NULL) - return FALSE; + return false; if (element->archive_pass == -1 || element->archive_pass == pass) { @@ -8490,7 +8960,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (! bfd_check_format (element, bfd_object)) { element->archive_pass = -1; - return FALSE; + return false; } orig_element = element; @@ -8500,7 +8970,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (element == NULL || !bfd_check_format (element, bfd_object)) { orig_element->archive_pass = -1; - return FALSE; + return false; } } @@ -8511,15 +8981,15 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) ->add_archive_element) (info, element, h->root.string, &element)) continue; if (!alpha_vms_link_add_object_symbols (element, info)) - return FALSE; + return false; orig_element->archive_pass = pass; } - return TRUE; + return true; } -static bfd_boolean +static bool alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { switch (bfd_get_format (abfd)) @@ -8536,11 +9006,11 @@ alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) break; default: bfd_set_error (bfd_error_wrong_format); - return FALSE; + return false; } } -static bfd_boolean +static bool alpha_vms_build_fixups (struct bfd_link_info *info) { struct alpha_vms_link_hash_table *t = alpha_vms_link_hash (info); @@ -8598,7 +9068,7 @@ alpha_vms_build_fixups (struct bfd_link_info *info) /* Finish now if there is no content. */ if (ca_sz + lp_sz + qr_sz == 0) - return TRUE; + return true; /* Add an eicp entry for the fixup itself. */ chgprt_num = 1; @@ -8617,7 +9087,7 @@ alpha_vms_build_fixups (struct bfd_link_info *info) sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1); content = bfd_zalloc (info->output_bfd, sz); if (content == NULL) - return FALSE; + return false; sec = alpha_vms_link_hash (info)->fixup; sec->contents = content; @@ -8805,13 +9275,13 @@ alpha_vms_build_fixups (struct bfd_link_info *info) off += sizeof (struct vms_eicp); } - return TRUE; + return true; } /* Called by bfd_hash_traverse to fill the symbol table. Return FALSE in case of failure. */ -static bfd_boolean +static bool alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) { struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh; @@ -8823,19 +9293,19 @@ alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) { hc = hc->u.i.link; if (hc->type == bfd_link_hash_new) - return TRUE; + return true; } h = (struct alpha_vms_link_hash_entry *) hc; switch (h->root.type) { case bfd_link_hash_undefined: - return TRUE; + return true; case bfd_link_hash_new: case bfd_link_hash_warning: abort (); case bfd_link_hash_undefweak: - return TRUE; + return true; case bfd_link_hash_defined: case bfd_link_hash_defweak: { @@ -8843,23 +9313,23 @@ alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) /* FIXME: this is certainly a symbol from a dynamic library. */ if (bfd_is_abs_section (sec)) - return TRUE; + return true; if (sec->owner->flags & DYNAMIC) - return TRUE; + return true; } break; case bfd_link_hash_common: break; case bfd_link_hash_indirect: - return TRUE; + return true; } /* Do not write not kept symbols. */ if (info->strip == strip_some && bfd_hash_lookup (info->keep_hash, h->root.root.string, - FALSE, FALSE) != NULL) - return TRUE; + false, false) != NULL) + return true; if (h->sym == NULL) { @@ -8887,12 +9357,12 @@ alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov) sym = h->sym; if (!add_symbol_entry (info->output_bfd, sym)) - return FALSE; + return false; - return TRUE; + return true; } -static bfd_boolean +static bool alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) { asection *o; @@ -8909,17 +9379,17 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) /* FIXME: we do not yet support relocatable link. It is not obvious how to do it for debug infos. */ (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n")); - return FALSE; + return false; } - bfd_get_outsymbols (abfd) = NULL; - bfd_get_symcount (abfd) = 0; + abfd->outsymbols = NULL; + abfd->symcount = 0; /* Mark all sections which will be included in the output file. */ for (o = abfd->sections; o != NULL; o = o->next) for (p = o->map_head.link_order; p != NULL; p = p->next) if (p->type == bfd_indirect_link_order) - p->u.indirect.section->linker_mark = TRUE; + p->u.indirect.section->linker_mark = true; #if 0 /* Handle all the link order information for the sections. */ @@ -9006,7 +9476,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) i = 0; PRIV (transfer_address[i++]) = 0xffffffff00000340ULL; /* SYS$IMGACT */ - h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", FALSE, FALSE, TRUE); + h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", false, false, true); if (h != NULL && h->type == bfd_link_hash_defined) PRIV (transfer_address[i++]) = alpha_vms_get_sym_value (h->u.def.section, h->u.def.value); @@ -9025,7 +9495,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) { o->contents = bfd_alloc (abfd, o->size); if (o->contents == NULL) - return FALSE; + return false; } if (o->flags & SEC_LOAD) { @@ -9044,7 +9514,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) (info->output_bfd, "$FIXUP$", SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); if (fixupsec == NULL) - return FALSE; + return false; last_addr = (last_addr + 0xffff) & ~0xffff; fixupsec->vma = last_addr; @@ -9063,7 +9533,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) (info->output_bfd, "$DMT$", SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED); if (dmt == NULL) - return FALSE; + return false; } else dmt = NULL; @@ -9078,7 +9548,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) } if (!alpha_vms_read_sections_content (sub, info)) - return FALSE; + return false; } /* Handle all the link order information for the sections. @@ -9092,13 +9562,13 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) case bfd_section_reloc_link_order: case bfd_symbol_reloc_link_order: abort (); - return FALSE; + return false; case bfd_indirect_link_order: /* Already done. */ break; default: if (! _bfd_default_link_order (abfd, info, o, p)) - return FALSE; + return false; break; } } @@ -9106,7 +9576,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) /* Compute fixups. */ if (!alpha_vms_build_fixups (info)) - return FALSE; + return false; /* Compute the DMT. */ if (dmt != NULL) @@ -9172,7 +9642,7 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) { contents = bfd_zalloc (info->output_bfd, off); if (contents == NULL) - return FALSE; + return false; dmt->contents = contents; dmt->size = off; } @@ -9183,14 +9653,14 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info) } } - return TRUE; + return true; } /* Read the contents of a section. buf points to a buffer of buf_size bytes to be filled with section data (starting at offset into section) */ -static bfd_boolean +static bool alpha_vms_get_section_contents (bfd *abfd, asection *section, void *buf, file_ptr offset, bfd_size_type count) @@ -9207,7 +9677,7 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section, || offset + count > section->size) { bfd_set_error (bfd_error_invalid_operation); - return FALSE; + return false; } /* If the section is already in memory, just copy it. */ @@ -9215,10 +9685,10 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section, { BFD_ASSERT (section->contents != NULL); memcpy (buf, section->contents + offset, count); - return TRUE; + return true; } if (section->size == 0) - return TRUE; + return true; /* Alloc in memory and read ETIRs. */ for (sec = abfd->sections; sec; sec = sec->next) @@ -9229,22 +9699,22 @@ alpha_vms_get_section_contents (bfd *abfd, asection *section, { sec->contents = bfd_alloc (abfd, sec->size); if (sec->contents == NULL) - return FALSE; + return false; } } if (!alpha_vms_read_sections_content (abfd, NULL)) - return FALSE; + return false; for (sec = abfd->sections; sec; sec = sec->next) if (sec->contents) sec->flags |= SEC_IN_MEMORY; memcpy (buf, section->contents + offset, count); - return TRUE; + return true; } /* Set the format of a file being written. */ -static bfd_boolean +static bool alpha_vms_mkobject (bfd * abfd) { const bfd_arch_info_type *arch; @@ -9252,22 +9722,22 @@ alpha_vms_mkobject (bfd * abfd) vms_debug2 ((1, "alpha_vms_mkobject (%p)\n", abfd)); if (!vms_initialize (abfd)) - return FALSE; + return false; PRIV (recwr.buf) = bfd_alloc (abfd, MAX_OUTREC_SIZE); if (PRIV (recwr.buf) == NULL) - return FALSE; + return false; arch = bfd_scan_arch ("alpha"); if (arch == 0) { bfd_set_error (bfd_error_wrong_format); - return FALSE; + return false; } abfd->arch_info = arch; - return TRUE; + return true; } @@ -9275,64 +9745,53 @@ alpha_vms_mkobject (bfd * abfd) /* Called when the BFD is being closed to do any necessary cleanup. */ -static bfd_boolean +static bool vms_close_and_cleanup (bfd * abfd) { vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd)); if (abfd == NULL || abfd->tdata.any == NULL) - return TRUE; + return true; - if (abfd->format == bfd_archive) + if (abfd->format == bfd_object) { - bfd_release (abfd, abfd->tdata.any); - abfd->tdata.any = NULL; - return TRUE; - } - - if (PRIV (recrd.buf) != NULL) - free (PRIV (recrd.buf)); - - if (PRIV (sections) != NULL) - free (PRIV (sections)); - - bfd_release (abfd, abfd->tdata.any); - abfd->tdata.any = NULL; + alpha_vms_free_private (abfd); #ifdef VMS - if (abfd->direction == write_direction) - { - /* Last step on VMS is to convert the file to variable record length - format. */ - if (!bfd_cache_close (abfd)) - return FALSE; - if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename)) - return FALSE; - } + if (abfd->direction == write_direction) + { + /* Last step on VMS is to convert the file to variable record length + format. */ + if (!bfd_cache_close (abfd)) + return false; + if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename)) + return false; + } #endif + } - return TRUE; + return _bfd_generic_close_and_cleanup (abfd); } /* Called when a new section is created. */ -static bfd_boolean +static bool vms_new_section_hook (bfd * abfd, asection *section) { - bfd_size_type amt; + size_t amt; vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n", abfd, section->index, section->name)); - if (! bfd_set_section_alignment (abfd, section, 0)) - return FALSE; + if (!bfd_set_section_alignment (section, 0)) + return false; vms_debug2 ((7, "%u: %s\n", section->index, section->name)); amt = sizeof (struct vms_section_data_struct); section->used_by_bfd = bfd_zalloc (abfd, amt); if (section->used_by_bfd == NULL) - return FALSE; + return false; /* Create the section symbol. */ return _bfd_generic_new_section_hook (abfd, section); @@ -9412,11 +9871,11 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED, else if (bfd_is_ind_section (sec)) ret->type = 'I'; else if ((symbol->flags & BSF_FUNCTION) - || (bfd_get_section_flags (abfd, sec) & SEC_CODE)) + || (bfd_section_flags (sec) & SEC_CODE)) ret->type = 'T'; - else if (bfd_get_section_flags (abfd, sec) & SEC_DATA) + else if (bfd_section_flags (sec) & SEC_DATA) ret->type = 'D'; - else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) + else if (bfd_section_flags (sec) & SEC_ALLOC) ret->type = 'B'; else ret->type = '?'; @@ -9431,7 +9890,7 @@ vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED, /* Return TRUE if the given symbol sym in the BFD abfd is a compiler generated local label, else return FALSE. */ -static bfd_boolean +static bool vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, const char *name) { @@ -9449,7 +9908,7 @@ vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, SEC_HAS_CONTENTS attribute, so nothing can be written to it. o and some more too */ -static bfd_boolean +static bool _bfd_vms_set_section_contents (bfd * abfd, asection *section, const void * location, @@ -9460,25 +9919,25 @@ _bfd_vms_set_section_contents (bfd * abfd, { section->contents = bfd_alloc (abfd, section->size); if (section->contents == NULL) - return FALSE; + return false; memcpy (section->contents + offset, location, (size_t) count); } - return TRUE; + return true; } /* Set the architecture and machine type in BFD abfd to arch and mach. Find the correct pointer to a structure and insert it into the arch_info pointer. */ -static bfd_boolean +static bool alpha_vms_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach) { if (arch != bfd_arch_alpha && arch != bfd_arch_unknown) - return FALSE; + return false; return bfd_default_set_arch_mach (abfd, arch, mach); } @@ -9591,6 +10050,7 @@ const bfd_target alpha_vms_vec = ' ', /* ar_pad_char. */ 15, /* ar_max_namelen. */ 0, /* match priority. */ + TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16,