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;
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 *)));
}
/* Save current DST location counter under specified index. */
-static void
+static bfd_boolean
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 bfd_boolean
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 bfd_boolean
+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
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));
+ (long) off));
#endif
if (PRIV (image_section)->contents != NULL)
+ memcpy (sec->contents + off, ptr, size);
+ else
{
- 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;
- }
-
- 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
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
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
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
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
if (rel1 != RELC_NONE)
goto bad_context;
while (op1-- > 0)
- image_write (abfd, ptr + 4, size);
+ if (!image_write (abfd, ptr + 4, size))
+ return FALSE;
}
break;
return FALSE;
}
}
- image_write_q (abfd, op1);
+ if (!image_write_q (abfd, op1))
+ return FALSE;
break;
/* Store code address: write address of entry point
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
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
if (ptr + 4 > maxptr)
goto corrupt_etir;
size = bfd_getl32 (ptr);
- image_write (abfd, ptr + 4, size);
+ if (!image_write (abfd, ptr + 4, size))
+ return FALSE;
}
break;
#if 0
abort ();
#endif
- image_write_l (abfd, op1);
+ if (!image_write_l (abfd, op1))
+ return FALSE;
break;
case ETIR__C_STO_RB:
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
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
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
return FALSE;
if (rel1 != RELC_NONE)
goto bad_context;
- if (!_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;
return FALSE;
if (rel1 != RELC_NONE || rel2 != RELC_NONE)
goto bad_context;
- if (op2 == 0)
+ 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;
}
static bfd_boolean
_bfd_vms_slurp_object_records (bfd * abfd)
{
- bfd_boolean err;
+ bfd_boolean ok;
int type;
do
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;
/* 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;
}
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.
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. */
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))
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);
bfd_set_error (bfd_error_file_too_big);
return NULL;
}
- vec->els = bfd_realloc (vec->els, amt);
+ vec->els = bfd_realloc_or_free (vec->els, amt);
}
}
if (vec->els == NULL)
/* Parse debug info for a module and internalize it. */
-static void
+static bfd_boolean
parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
int length)
{
{
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;
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. */
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;
}
{
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;
}
- 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. */
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];
dst_size -= len;
off += len;
len -= sizeof (dsth);
- buf = bfd_malloc (len);
- if (bfd_bread (buf, len, abfd) != len)
+ buf = _bfd_malloc_and_read (abfd, len, len);
+ if (buf == NULL)
{
fprintf (file, _("cannot read DST symbol\n"));
return;
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;