{
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))
{
/* 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;
}
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)
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_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 32 bit value, sign extend to 64 bit. */
case ETIR__C_STA_LW:
- if (ptr + 4 > maxptr)
+ if (cmd_length < 4)
goto corrupt_etir;
if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
return FALSE;
stack 64 bit value of symbol. */
case ETIR__C_STA_QW:
- if (ptr + 8 > maxptr)
+ if (cmd_length < 8)
goto corrupt_etir;
if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
return FALSE;
{
int psect;
- if (ptr + 12 > maxptr)
+ if (cmd_length < 12)
goto corrupt_etir;
psect = bfd_getl32 (ptr);
if ((unsigned int) psect >= PRIV (section_count))
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
{
int size;
- if (ptr + 4 > maxptr)
+ if (cmd_length < 4)
goto corrupt_etir;
size = bfd_getl32 (ptr);
+ 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)
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)
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
{
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;
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:
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)
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
/* 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);
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;
}
break;
}
- ptr += cmd_length - 4;
+ ptr += cmd_length;
}
return TRUE;
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);