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)
+ return FALSE;
bfd_flags |= SEC_COFF_SHARED_LIBRARY;
bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
}
{
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)
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:
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;
char *name;
unsigned long align_addr;
- name = _bfd_vms_save_counted_string (&egps->namlng, gsd_size - 4);
+ name = _bfd_vms_save_counted_string (abfd, &egps->namlng,
+ gsd_size - 4);
section = bfd_make_section (abfd, name);
if (!section)
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;
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;
else
nameoff = ESRF__B_NAMLNG;
- entry = add_symbol (abfd, vms_rec + nameoff);
+ if (nameoff >= gsd_size)
+ {
+ _bfd_error_handler (_("ECSD__C_SYM record is too small"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ entry = add_symbol (abfd, vms_rec + nameoff, gsd_size - nameoff);
if (entry == NULL)
return FALSE;
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)
+ {
+ _bfd_error_handler (_("ECSD__C_SYMG record is too small"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ entry = add_symbol (abfd, &egst->namlng, gsd_size - nameoff);
if (entry == NULL)
return FALSE;
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;
}
+ ptr += 4;
#if VMS_DEBUG
_bfd_vms_debug (4, "etir: %s(%d)\n",
stack 32 bit value, sign extend to 64 bit. */
case ETIR__C_STA_LW:
- if (ptr + 4 >= maxptr)
+ if (ptr + 4 > maxptr)
goto corrupt_etir;
_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE);
break;
stack 64 bit value of symbol. */
case ETIR__C_STA_QW:
- if (ptr + 8 >= maxptr)
+ if (ptr + 8 > maxptr)
goto corrupt_etir;
_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE);
break;
{
int psect;
- if (ptr + 12 >= maxptr)
+ if (ptr + 12 > maxptr)
goto corrupt_etir;
psect = bfd_getl32 (ptr);
if ((unsigned int) psect >= PRIV (section_count))
{
int size;
- if (ptr + 4 >= maxptr)
+ if (ptr + 4 > maxptr)
goto corrupt_etir;
size = bfd_getl32 (ptr);
_bfd_vms_pop (abfd, &op1, &rel1);
{
unsigned int size;
- if (ptr + 4 >= maxptr)
+ if (ptr + 4 > maxptr)
goto corrupt_etir;
size = bfd_getl32 (ptr);
image_write (abfd, ptr + 4, size);
/* Augment relocation base: increment image location counter by offset
arg: lw offset value. */
case ETIR__C_CTL_AUGRB:
- if (ptr + 4 >= maxptr)
+ if (ptr + 4 > maxptr)
goto corrupt_etir;
op1 = bfd_getl32 (ptr);
image_inc_ptr (abfd, op1);
{
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;
funcinfo = (struct funcinfo *)
bfd_zalloc (abfd, sizeof (struct funcinfo));
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;
{
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)
{
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 *
VEC_INIT (ret->shrlibs);
ret->fixup = NULL;
+ ret->root.hash_table_free = alpha_vms_bfd_link_hash_table_free;
return &ret->root;
}
if (abfd == NULL || abfd->tdata.any == NULL)
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));
+ struct module *module;
- if (PRIV (sections) != NULL)
- free (PRIV (sections));
+ free (PRIV (recrd.buf));
+ free (PRIV (sections));
+ free (PRIV (syms));
+ free (PRIV (dst_ptr_offsets));
- bfd_release (abfd, abfd->tdata.any);
- abfd->tdata.any = NULL;
+ for (module = PRIV (modules); module; module = module->next)
+ free (module->file_table);
#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. */