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_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;
}
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];