version 1.5, 2018/04/14 15:49:39 |
version 1.6, 2020/04/03 17:51:05 |
|
|
/* BFD back-end for VMS archive files. |
/* BFD back-end for VMS archive files. |
|
|
Copyright (C) 2010-2016 Free Software Foundation, Inc. |
Copyright (C) 2010-2018 Free Software Foundation, Inc. |
Written by Tristan Gingold <gingold@adacore.com>, AdaCore. |
Written by Tristan Gingold <gingold@adacore.com>, AdaCore. |
|
|
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
Line 129 struct carsym_mem |
|
Line 129 struct carsym_mem |
|
|
|
static bfd_boolean |
static bfd_boolean |
vms_add_index (struct carsym_mem *cs, char *name, |
vms_add_index (struct carsym_mem *cs, char *name, |
unsigned int idx_vbn, unsigned int idx_off) |
unsigned int idx_vbn, unsigned int idx_off) |
{ |
{ |
if (cs->nbr == cs->max) |
if (cs->nbr == cs->max) |
{ |
{ |
Line 138 vms_add_index (struct carsym_mem *cs, ch |
|
Line 138 vms_add_index (struct carsym_mem *cs, ch |
|
cs->max = 2 * cs->max + 32; |
cs->max = 2 * cs->max + 32; |
|
|
if (!cs->realloced) |
if (!cs->realloced) |
{ |
{ |
n = bfd_malloc2 (cs->max, sizeof (struct carsym)); |
n = bfd_malloc2 (cs->max, sizeof (struct carsym)); |
if (n == NULL) |
if (n == NULL) |
return FALSE; |
return FALSE; |
memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym)); |
memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym)); |
/* And unfortunately we can't free cs->idx. */ |
/* And unfortunately we can't free cs->idx. */ |
} |
} |
else |
else |
{ |
{ |
n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym)); |
n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym)); |
if (n == NULL) |
if (n == NULL) |
return FALSE; |
return FALSE; |
} |
} |
cs->idx = n; |
cs->idx = n; |
cs->realloced = TRUE; |
cs->realloced = TRUE; |
} |
} |
Line 165 vms_add_index (struct carsym_mem *cs, ch |
|
Line 165 vms_add_index (struct carsym_mem *cs, ch |
|
|
|
static bfd_boolean |
static bfd_boolean |
vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name, |
vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name, |
struct vms_rfa *rfa) |
struct vms_rfa *rfa) |
{ |
{ |
struct vms_lns lns; |
struct vms_lns lns; |
unsigned int vbn; |
unsigned int vbn; |
Line 175 vms_add_indexes_from_list (bfd *abfd, st |
|
Line 175 vms_add_indexes_from_list (bfd *abfd, st |
|
{ |
{ |
vbn = bfd_getl32 (rfa->vbn); |
vbn = bfd_getl32 (rfa->vbn); |
if (vbn == 0) |
if (vbn == 0) |
return TRUE; |
return TRUE; |
|
|
/* Read the LHS. */ |
/* Read the LHS. */ |
off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset); |
off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset); |
if (bfd_seek (abfd, off, SEEK_SET) != 0 |
if (bfd_seek (abfd, off, SEEK_SET) != 0 |
|| bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns)) |
|| bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns)) |
return FALSE; |
return FALSE; |
|
|
if (!vms_add_index (cs, name, |
if (!vms_add_index (cs, name, |
bfd_getl32 (lns.modrfa.vbn), |
bfd_getl32 (lns.modrfa.vbn), |
bfd_getl16 (lns.modrfa.offset))) |
bfd_getl16 (lns.modrfa.offset))) |
return FALSE; |
return FALSE; |
|
|
rfa = &lns.nxtrfa; |
rfa = &lns.nxtrfa; |
} |
} |
Line 251 vms_traverse_index (bfd *abfd, unsigned |
|
Line 251 vms_traverse_index (bfd *abfd, unsigned |
|
|
|
/* Extract key length. */ |
/* Extract key length. */ |
if (bfd_libdata (abfd)->ver == LBR_MAJORID) |
if (bfd_libdata (abfd)->ver == LBR_MAJORID) |
{ |
{ |
struct vms_idx *ridx = (struct vms_idx *)p; |
struct vms_idx *ridx = (struct vms_idx *)p; |
|
|
idx_vbn = bfd_getl32 (ridx->rfa.vbn); |
idx_vbn = bfd_getl32 (ridx->rfa.vbn); |
idx_off = bfd_getl16 (ridx->rfa.offset); |
idx_off = bfd_getl16 (ridx->rfa.offset); |
|
|
keylen = ridx->keylen; |
keylen = ridx->keylen; |
flags = 0; |
flags = 0; |
keyname = ridx->keyname; |
keyname = ridx->keyname; |
} |
} |
else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID) |
else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID) |
{ |
{ |
struct vms_elfidx *ridx = (struct vms_elfidx *)p; |
struct vms_elfidx *ridx = (struct vms_elfidx *)p; |
|
|
idx_vbn = bfd_getl32 (ridx->rfa.vbn); |
idx_vbn = bfd_getl32 (ridx->rfa.vbn); |
idx_off = bfd_getl16 (ridx->rfa.offset); |
idx_off = bfd_getl16 (ridx->rfa.offset); |
|
|
keylen = bfd_getl16 (ridx->keylen); |
keylen = bfd_getl16 (ridx->keylen); |
flags = ridx->flags; |
flags = ridx->flags; |
keyname = ridx->keyname; |
keyname = ridx->keyname; |
} |
} |
else |
else |
return FALSE; |
return FALSE; |
|
|
/* Illegal value. */ |
/* Illegal value. */ |
if (idx_vbn == 0) |
if (idx_vbn == 0) |
return FALSE; |
return FALSE; |
|
|
/* Point to the next index entry. */ |
/* Point to the next index entry. */ |
p = keyname + keylen; |
p = keyname + keylen; |
|
|
if (idx_off == RFADEF__C_INDEX) |
if (idx_off == RFADEF__C_INDEX) |
{ |
{ |
/* Indirect entry. Recurse. */ |
/* Indirect entry. Recurse. */ |
if (!vms_traverse_index (abfd, idx_vbn, cs)) |
if (!vms_traverse_index (abfd, idx_vbn, cs)) |
return FALSE; |
return FALSE; |
} |
} |
else |
else |
{ |
{ |
/* Add a new entry. */ |
/* Add a new entry. */ |
char *name; |
char *name; |
|
|
if (flags & ELFIDX__SYMESC) |
if (flags & ELFIDX__SYMESC) |
{ |
{ |
/* Extended key name. */ |
/* Extended key name. */ |
unsigned int noff = 0; |
unsigned int noff = 0; |
unsigned int koff; |
unsigned int koff; |
unsigned int kvbn; |
unsigned int kvbn; |
struct vms_kbn *kbn; |
struct vms_kbn *kbn; |
unsigned char kblk[VMS_BLOCK_SIZE]; |
unsigned char kblk[VMS_BLOCK_SIZE]; |
|
|
/* Sanity check. */ |
/* Sanity check. */ |
if (keylen != sizeof (struct vms_kbn)) |
if (keylen != sizeof (struct vms_kbn)) |
return FALSE; |
return FALSE; |
|
|
kbn = (struct vms_kbn *)keyname; |
kbn = (struct vms_kbn *)keyname; |
keylen = bfd_getl16 (kbn->keylen); |
keylen = bfd_getl16 (kbn->keylen); |
|
|
name = bfd_alloc (abfd, keylen + 1); |
name = bfd_alloc (abfd, keylen + 1); |
if (name == NULL) |
if (name == NULL) |
return FALSE; |
return FALSE; |
kvbn = bfd_getl32 (kbn->rfa.vbn); |
kvbn = bfd_getl32 (kbn->rfa.vbn); |
koff = bfd_getl16 (kbn->rfa.offset); |
koff = bfd_getl16 (kbn->rfa.offset); |
|
|
/* Read the key, chunk by chunk. */ |
/* Read the key, chunk by chunk. */ |
do |
do |
{ |
{ |
unsigned int klen; |
unsigned int klen; |
|
|
if (!vms_read_block (abfd, kvbn, kblk)) |
if (!vms_read_block (abfd, kvbn, kblk)) |
return FALSE; |
return FALSE; |
kbn = (struct vms_kbn *)(kblk + koff); |
kbn = (struct vms_kbn *)(kblk + koff); |
klen = bfd_getl16 (kbn->keylen); |
klen = bfd_getl16 (kbn->keylen); |
kvbn = bfd_getl32 (kbn->rfa.vbn); |
kvbn = bfd_getl32 (kbn->rfa.vbn); |
koff = bfd_getl16 (kbn->rfa.offset); |
koff = bfd_getl16 (kbn->rfa.offset); |
|
|
memcpy (name + noff, kbn + 1, klen); |
memcpy (name + noff, kbn + 1, klen); |
noff += klen; |
noff += klen; |
} |
} |
while (kvbn != 0); |
while (kvbn != 0); |
|
|
/* Sanity check. */ |
/* Sanity check. */ |
if (noff != keylen) |
if (noff != keylen) |
return FALSE; |
return FALSE; |
} |
} |
else |
else |
{ |
{ |
/* Usual key name. */ |
/* Usual key name. */ |
name = bfd_alloc (abfd, keylen + 1); |
name = bfd_alloc (abfd, keylen + 1); |
if (name == NULL) |
if (name == NULL) |
return FALSE; |
return FALSE; |
|
|
memcpy (name, keyname, keylen); |
memcpy (name, keyname, keylen); |
} |
} |
name[keylen] = 0; |
name[keylen] = 0; |
|
|
if (flags & ELFIDX__LISTRFA) |
if (flags & ELFIDX__LISTRFA) |
{ |
{ |
struct vms_lhs lhs; |
struct vms_lhs lhs; |
|
|
/* Read the LHS. */ |
/* Read the LHS. */ |
off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off; |
off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off; |
if (bfd_seek (abfd, off, SEEK_SET) != 0 |
if (bfd_seek (abfd, off, SEEK_SET) != 0 |
|| bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs)) |
|| bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs)) |
return FALSE; |
return FALSE; |
|
|
/* FIXME: this adds extra entries that were not accounted. */ |
/* FIXME: this adds extra entries that were not accounted. */ |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa)) |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa)) |
return FALSE; |
return FALSE; |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa)) |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa)) |
return FALSE; |
return FALSE; |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa)) |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa)) |
return FALSE; |
return FALSE; |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa)) |
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa)) |
return FALSE; |
return FALSE; |
} |
} |
else |
else |
{ |
{ |
if (!vms_add_index (cs, name, idx_vbn, idx_off)) |
if (!vms_add_index (cs, name, idx_vbn, idx_off)) |
return FALSE; |
return FALSE; |
} |
} |
} |
} |
} |
} |
|
|
return TRUE; |
return TRUE; |
Line 414 vms_lib_read_index (bfd *abfd, int idx, |
|
Line 414 vms_lib_read_index (bfd *abfd, int idx, |
|
if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm)) |
if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm)) |
{ |
{ |
if (csm.realloced && csm.idx != NULL) |
if (csm.realloced && csm.idx != NULL) |
free (csm.idx); |
free (csm.idx); |
|
|
/* Note: in case of error, we can free what was allocated on the |
/* Note: in case of error, we can free what was allocated on the |
BFD's objalloc. */ |
BFD's objalloc. */ |
bfd_release (abfd, csbuf); |
bfd_release (abfd, csbuf); |
return NULL; |
return NULL; |
} |
} |
Line 425 vms_lib_read_index (bfd *abfd, int idx, |
|
Line 425 vms_lib_read_index (bfd *abfd, int idx, |
|
if (csm.realloced) |
if (csm.realloced) |
{ |
{ |
/* There are more entries than the first estimate. Allocate on |
/* There are more entries than the first estimate. Allocate on |
the BFD's objalloc. */ |
the BFD's objalloc. */ |
csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym)); |
csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym)); |
if (csbuf == NULL) |
if (csbuf == NULL) |
return NULL; |
return NULL; |
memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym)); |
memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym)); |
free (csm.idx); |
free (csm.idx); |
*nbrel = csm.nbr; |
*nbrel = csm.nbr; |
Line 460 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
Line 460 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
/* Check sanity (= magic) number. */ |
/* Check sanity (= magic) number. */ |
sanity = bfd_getl32 (lhd.sanity); |
sanity = bfd_getl32 (lhd.sanity); |
if (!(sanity == LHD_SANEID3 |
if (!(sanity == LHD_SANEID3 |
|| sanity == LHD_SANEID6 |
|| sanity == LHD_SANEID6 |
|| sanity == LHD_SANEID_DCX)) |
|| sanity == LHD_SANEID_DCX)) |
{ |
{ |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
return NULL; |
return NULL; |
Line 473 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
Line 473 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
{ |
{ |
case vms_lib_alpha: |
case vms_lib_alpha: |
if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB) |
if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB) |
|| majorid != LBR_MAJORID |
|| majorid != LBR_MAJORID |
|| lhd.nindex != 2) |
|| lhd.nindex != 2) |
{ |
{ |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
return NULL; |
return NULL; |
} |
} |
break; |
break; |
case vms_lib_ia64: |
case vms_lib_ia64: |
if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB) |
if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB) |
|| majorid != LBR_ELFMAJORID |
|| majorid != LBR_ELFMAJORID |
|| lhd.nindex != 2) |
|| lhd.nindex != 2) |
{ |
{ |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
return NULL; |
return NULL; |
} |
} |
break; |
break; |
case vms_lib_txt: |
case vms_lib_txt: |
if ((lhd.type != LBR__C_TYP_TXT |
if ((lhd.type != LBR__C_TYP_TXT |
&& lhd.type != LBR__C_TYP_MLB |
&& lhd.type != LBR__C_TYP_MLB |
&& lhd.type != LBR__C_TYP_HLP) |
&& lhd.type != LBR__C_TYP_HLP) |
|| majorid != LBR_MAJORID |
|| majorid != LBR_MAJORID |
|| lhd.nindex != 1) |
|| lhd.nindex != 1) |
{ |
{ |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
return NULL; |
return NULL; |
} |
} |
break; |
break; |
default: |
default: |
abort (); |
abort (); |
Line 529 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
Line 529 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
nbr_ent = tdata->artdata.symdef_count; |
nbr_ent = tdata->artdata.symdef_count; |
tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent); |
tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent); |
if (tdata->artdata.symdefs == NULL) |
if (tdata->artdata.symdefs == NULL) |
goto err; |
goto err; |
/* Only IA64 archives may have more entries in the index that what |
/* Only IA64 archives may have more entries in the index that what |
was declared. */ |
was declared. */ |
if (nbr_ent != tdata->artdata.symdef_count |
if (nbr_ent != tdata->artdata.symdef_count |
&& kind != vms_lib_ia64) |
&& kind != vms_lib_ia64) |
goto err; |
goto err; |
tdata->artdata.symdef_count = nbr_ent; |
tdata->artdata.symdef_count = nbr_ent; |
} |
} |
tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules); |
tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules); |
Line 553 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
Line 553 _bfd_vms_lib_archive_p (bfd *abfd, enum |
|
unsigned int i; |
unsigned int i; |
|
|
if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0 |
if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0 |
|| bfd_bread (buf_reclen, sizeof (buf_reclen), abfd) |
|| bfd_bread (buf_reclen, sizeof (buf_reclen), abfd) |
!= sizeof (buf_reclen)) |
!= sizeof (buf_reclen)) |
goto err; |
goto err; |
reclen = bfd_getl32 (buf_reclen); |
reclen = bfd_getl32 (buf_reclen); |
buf = bfd_malloc (reclen); |
buf = bfd_malloc (reclen); |
if (buf == NULL) |
if (buf == NULL) |
goto err; |
goto err; |
if (bfd_bread (buf, reclen, abfd) != reclen) |
if (bfd_bread (buf, reclen, abfd) != reclen) |
{ |
{ |
free (buf); |
free (buf); |
goto err; |
goto err; |
} |
} |
map = (struct vms_dcxmap *)buf; |
map = (struct vms_dcxmap *)buf; |
tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs); |
tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs); |
sbm_off = bfd_getl16 (map->sub0); |
sbm_off = bfd_getl16 (map->sub0); |
tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc |
tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc |
(abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc)); |
(abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc)); |
for (i = 0; i < tdata->nbr_dcxsbm; i++) |
for (i = 0; i < tdata->nbr_dcxsbm; i++) |
{ |
{ |
struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off); |
struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off); |
struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i]; |
struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i]; |
unsigned int sbm_len; |
unsigned int sbm_len; |
unsigned int sbm_sz; |
unsigned int sbm_sz; |
unsigned int off; |
unsigned int off; |
unsigned char *data = (unsigned char *)sbm; |
unsigned char *data = (unsigned char *)sbm; |
unsigned char *buf1; |
unsigned char *buf1; |
unsigned int l, j; |
unsigned int l, j; |
|
|
sbm_sz = bfd_getl16 (sbm->size); |
sbm_sz = bfd_getl16 (sbm->size); |
sbm_off += sbm_sz; |
sbm_off += sbm_sz; |
BFD_ASSERT (sbm_off <= reclen); |
BFD_ASSERT (sbm_off <= reclen); |
|
|
sbmdesc->min_char = sbm->min_char; |
sbmdesc->min_char = sbm->min_char; |
BFD_ASSERT (sbmdesc->min_char == 0); |
BFD_ASSERT (sbmdesc->min_char == 0); |
sbmdesc->max_char = sbm->max_char; |
sbmdesc->max_char = sbm->max_char; |
sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1; |
sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1; |
l = (2 * sbm_len + 7) / 8; |
l = (2 * sbm_len + 7) / 8; |
BFD_ASSERT |
BFD_ASSERT |
(sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len |
(sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len |
|| (tdata->nbr_dcxsbm == 1 |
|| (tdata->nbr_dcxsbm == 1 |
&& sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len)); |
&& sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len)); |
sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l); |
sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l); |
memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l); |
memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l); |
sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len); |
sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len); |
memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len); |
memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len); |
off = bfd_getl16 (sbm->next); |
off = bfd_getl16 (sbm->next); |
if (off != 0) |
if (off != 0) |
{ |
{ |
/* Read the 'next' array. */ |
/* Read the 'next' array. */ |
sbmdesc->next = (unsigned short *)bfd_alloc |
sbmdesc->next = (unsigned short *)bfd_alloc |
(abfd, sbm_len * sizeof (unsigned short)); |
(abfd, sbm_len * sizeof (unsigned short)); |
buf1 = data + off; |
buf1 = data + off; |
for (j = 0; j < sbm_len; j++) |
for (j = 0; j < sbm_len; j++) |
sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2); |
sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2); |
} |
} |
else |
else |
{ |
{ |
/* There is no next array if there is only one submap. */ |
/* There is no next array if there is only one submap. */ |
BFD_ASSERT (tdata->nbr_dcxsbm == 1); |
BFD_ASSERT (tdata->nbr_dcxsbm == 1); |
sbmdesc->next = NULL; |
sbmdesc->next = NULL; |
} |
} |
} |
} |
free (buf); |
free (buf); |
} |
} |
else |
else |
Line 731 _bfd_vms_lib_find_symbol (bfd *abfd, con |
|
Line 731 _bfd_vms_lib_find_symbol (bfd *abfd, con |
|
|
|
diff = (char)(name[0] - syms[mid].name[0]); |
diff = (char)(name[0] - syms[mid].name[0]); |
if (diff == 0) |
if (diff == 0) |
diff = strcmp (name, syms[mid].name); |
diff = strcmp (name, syms[mid].name); |
if (diff == 0) |
if (diff == 0) |
return mid; |
return mid; |
else if (diff < 0) |
else if (diff < 0) |
hi = mid - 1; |
hi = mid - 1; |
else |
else |
lo = mid + 1; |
lo = mid + 1; |
} |
} |
return BFD_NO_MORE_SYMBOLS; |
return BFD_NO_MORE_SYMBOLS; |
} |
} |
Line 821 vms_lib_read_block (struct bfd *abfd) |
|
Line 821 vms_lib_read_block (struct bfd *abfd) |
|
|
|
/* Read next block. */ |
/* Read next block. */ |
if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0) |
if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0) |
return FALSE; |
return FALSE; |
if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr)) |
if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr)) |
return FALSE; |
return FALSE; |
vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE; |
vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE; |
vec->blk_off = sizeof (hdr); |
vec->blk_off = sizeof (hdr); |
} |
} |
Line 847 vms_lib_bread_raw (struct bfd *abfd, uns |
|
Line 847 vms_lib_bread_raw (struct bfd *abfd, uns |
|
|
|
/* Be sure the current data block is read. */ |
/* Be sure the current data block is read. */ |
if (!vms_lib_read_block (abfd)) |
if (!vms_lib_read_block (abfd)) |
return -1; |
return -1; |
|
|
/* Do not read past the data block, do not read more than requested. */ |
/* Do not read past the data block, do not read more than requested. */ |
l = DATA__LENGTH - vec->blk_off; |
l = DATA__LENGTH - vec->blk_off; |
if (l > nbytes) |
if (l > nbytes) |
l = nbytes; |
l = nbytes; |
if (l == 0) |
if (l == 0) |
return 0; |
return 0; |
if (buf != NULL) |
if (buf != NULL) |
{ |
{ |
/* Really read into BUF. */ |
/* Really read into BUF. */ |
if (bfd_bread (buf, l, abfd->my_archive) != l) |
if (bfd_bread (buf, l, abfd->my_archive) != l) |
return -1; |
return -1; |
} |
} |
else |
else |
{ |
{ |
/* Make as if we are reading. */ |
/* Make as if we are reading. */ |
if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0) |
if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0) |
return -1; |
return -1; |
} |
} |
|
|
if (buf != NULL) |
if (buf != NULL) |
buf += l; |
buf += l; |
vec->blk_off += l; |
vec->blk_off += l; |
nbytes -= l; |
nbytes -= l; |
res += l; |
res += l; |
Line 902 vms_lib_dcx (struct vms_lib_iovec *vec, |
|
Line 902 vms_lib_dcx (struct vms_lib_iovec *vec, |
|
unsigned char b = vec->dcx_buf[i]; |
unsigned char b = vec->dcx_buf[i]; |
|
|
for (; j < 8; j++) |
for (; j < 8; j++) |
{ |
{ |
if (b & (1 << j)) |
if (b & (1 << j)) |
offset++; |
offset++; |
if (!(sbm->flags[offset >> 3] & (1 << (offset & 7)))) |
if (!(sbm->flags[offset >> 3] & (1 << (offset & 7)))) |
{ |
{ |
unsigned int n_offset = sbm->nodes[offset]; |
unsigned int n_offset = sbm->nodes[offset]; |
if (n_offset == 0) |
if (n_offset == 0) |
{ |
{ |
/* End of buffer. Stay where we are. */ |
/* End of buffer. Stay where we are. */ |
vec->dcx_pos = (i << 3) + j; |
vec->dcx_pos = (i << 3) + j; |
if (b & (1 << j)) |
if (b & (1 << j)) |
offset--; |
offset--; |
vec->dcx_offset = offset; |
vec->dcx_offset = offset; |
vec->dcx_sbm = sbm; |
vec->dcx_sbm = sbm; |
return res; |
return res; |
} |
} |
offset = 2 * n_offset; |
offset = 2 * n_offset; |
} |
} |
else |
else |
{ |
{ |
unsigned char v = sbm->nodes[offset]; |
unsigned char v = sbm->nodes[offset]; |
|
|
if (sbm->next != NULL) |
if (sbm->next != NULL) |
sbm = vec->dcxsbms + sbm->next[v]; |
sbm = vec->dcxsbms + sbm->next[v]; |
offset = 0; |
offset = 0; |
res++; |
res++; |
|
|
if (buf) |
if (buf) |
{ |
{ |
*buf++ = v; |
*buf++ = v; |
nbytes--; |
nbytes--; |
|
|
if (nbytes == 0) |
if (nbytes == 0) |
{ |
{ |
vec->dcx_pos = (i << 3) + j + 1; |
vec->dcx_pos = (i << 3) + j + 1; |
vec->dcx_offset = offset; |
vec->dcx_offset = offset; |
vec->dcx_sbm = sbm; |
vec->dcx_sbm = sbm; |
|
|
return res; |
return res; |
} |
} |
} |
} |
} |
} |
} |
} |
j = 0; |
j = 0; |
} |
} |
return -1; |
return -1; |
Line 968 vms_lib_bread (struct bfd *abfd, void *v |
|
Line 968 vms_lib_bread (struct bfd *abfd, void *v |
|
while (nbytes > 0) |
while (nbytes > 0) |
{ |
{ |
if (vec->rec_rem == 0) |
if (vec->rec_rem == 0) |
{ |
{ |
unsigned char blen[2]; |
unsigned char blen[2]; |
|
|
/* Read record length. */ |
/* Read record length. */ |
if (vms_lib_bread_raw (abfd, blen, sizeof (blen)) != sizeof (blen)) |
if (vms_lib_bread_raw (abfd, blen, sizeof (blen)) != sizeof (blen)) |
return -1; |
return -1; |
vec->rec_len = bfd_getl16 (blen); |
vec->rec_len = bfd_getl16 (blen); |
if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt) |
if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt) |
{ |
{ |
/* Discard record size and align byte. */ |
/* Discard record size and align byte. */ |
vec->rec_pos = 0; |
vec->rec_pos = 0; |
vec->rec_rem = vec->rec_len; |
vec->rec_rem = vec->rec_len; |
} |
} |
else |
else |
{ |
{ |
/* Prepend record size. */ |
/* Prepend record size. */ |
vec->rec_pos = REC_POS_LEN0; |
vec->rec_pos = REC_POS_LEN0; |
vec->rec_rem = (vec->rec_len + 1) & ~1; /* With align byte. */ |
vec->rec_rem = (vec->rec_len + 1) & ~1; /* With align byte. */ |
} |
} |
if (vec->rec_len == 3) |
if (vec->rec_len == 3) |
{ |
{ |
/* Possibly end of file. Check the pattern. */ |
/* Possibly end of file. Check the pattern. */ |
if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4) |
if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4) |
return -1; |
return -1; |
if (!memcmp (vec->pattern, eotdesc + 2, 3)) |
if (!memcmp (vec->pattern, eotdesc + 2, 3)) |
{ |
{ |
/* This is really an EOF. */ |
/* This is really an EOF. */ |
vec->where += res; |
vec->where += res; |
vec->file_len = vec->where; |
vec->file_len = vec->where; |
return res; |
return res; |
} |
} |
} |
} |
|
|
if (vec->dcxsbms != NULL) |
if (vec->dcxsbms != NULL) |
{ |
{ |
/* This is a compressed member. */ |
/* This is a compressed member. */ |
unsigned int len; |
unsigned int len; |
file_ptr elen; |
file_ptr elen; |
|
|
/* Be sure there is enough room for the expansion. */ |
/* Be sure there is enough room for the expansion. */ |
len = (vec->rec_len + 1) & ~1; |
len = (vec->rec_len + 1) & ~1; |
if (len > vec->dcx_max) |
if (len > vec->dcx_max) |
{ |
{ |
while (len > vec->dcx_max) |
while (len > vec->dcx_max) |
vec->dcx_max *= 2; |
vec->dcx_max *= 2; |
vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max); |
vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max); |
if (vec->dcx_buf == NULL) |
if (vec->dcx_buf == NULL) |
return -1; |
return -1; |
} |
} |
|
|
/* Read the compressed record. */ |
/* Read the compressed record. */ |
vec->dcx_rlen = len; |
vec->dcx_rlen = len; |
if (vec->rec_len == 3) |
if (vec->rec_len == 3) |
{ |
{ |
/* Already read. */ |
/* Already read. */ |
memcpy (vec->dcx_buf, vec->pattern, 3); |
memcpy (vec->dcx_buf, vec->pattern, 3); |
} |
} |
else |
else |
{ |
{ |
elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len); |
elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len); |
if (elen != len) |
if (elen != len) |
return -1; |
return -1; |
} |
} |
|
|
/* Dummy expansion to get the expanded length. */ |
/* Dummy expansion to get the expanded length. */ |
vec->dcx_offset = 0; |
vec->dcx_offset = 0; |
vec->dcx_sbm = vec->dcxsbms; |
vec->dcx_sbm = vec->dcxsbms; |
vec->dcx_pos = 0; |
vec->dcx_pos = 0; |
elen = vms_lib_dcx (vec, NULL, 0x10000); |
elen = vms_lib_dcx (vec, NULL, 0x10000); |
if (elen < 0) |
if (elen < 0) |
return -1; |
return -1; |
vec->rec_len = elen; |
vec->rec_len = elen; |
vec->rec_rem = elen; |
vec->rec_rem = elen; |
|
|
/* Reset the state. */ |
/* Reset the state. */ |
vec->dcx_offset = 0; |
vec->dcx_offset = 0; |
vec->dcx_sbm = vec->dcxsbms; |
vec->dcx_sbm = vec->dcxsbms; |
vec->dcx_pos = 0; |
vec->dcx_pos = 0; |
} |
} |
} |
} |
if (vec->rec_pos < 0) |
if (vec->rec_pos < 0) |
{ |
{ |
unsigned char c; |
unsigned char c; |
switch (vec->rec_pos) |
switch (vec->rec_pos) |
{ |
{ |
case REC_POS_LEN0: |
case REC_POS_LEN0: |
c = vec->rec_len & 0xff; |
c = vec->rec_len & 0xff; |
vec->rec_pos = REC_POS_LEN1; |
vec->rec_pos = REC_POS_LEN1; |
break; |
break; |
case REC_POS_LEN1: |
case REC_POS_LEN1: |
c = (vec->rec_len >> 8) & 0xff; |
c = (vec->rec_len >> 8) & 0xff; |
vec->rec_pos = 0; |
vec->rec_pos = 0; |
break; |
break; |
case REC_POS_PAD: |
case REC_POS_PAD: |
c = 0; |
c = 0; |
vec->rec_rem = 0; |
vec->rec_rem = 0; |
break; |
break; |
case REC_POS_NL: |
case REC_POS_NL: |
c = '\n'; |
c = '\n'; |
vec->rec_rem = 0; |
vec->rec_rem = 0; |
break; |
break; |
default: |
default: |
abort (); |
abort (); |
} |
} |
if (buf != NULL) |
if (buf != NULL) |
{ |
{ |
*buf = c; |
*buf = c; |
buf++; |
buf++; |
} |
} |
nbytes--; |
nbytes--; |
res++; |
res++; |
continue; |
continue; |
} |
} |
|
|
if (nbytes > vec->rec_rem) |
if (nbytes > vec->rec_rem) |
chunk = vec->rec_rem; |
chunk = vec->rec_rem; |
else |
else |
chunk = nbytes; |
chunk = nbytes; |
|
|
if (vec->dcxsbms != NULL) |
if (vec->dcxsbms != NULL) |
{ |
{ |
/* Optimize the stat() case: no need to decompress again as we |
/* Optimize the stat() case: no need to decompress again as we |
know the length. */ |
know the length. */ |
if (!(buf == NULL && chunk == vec->rec_rem)) |
if (!(buf == NULL && chunk == vec->rec_rem)) |
chunk = vms_lib_dcx (vec, buf, chunk); |
chunk = vms_lib_dcx (vec, buf, chunk); |
} |
} |
else |
else |
{ |
{ |
if (vec->rec_len == 3) |
if (vec->rec_len == 3) |
{ |
{ |
if (buf != NULL) |
if (buf != NULL) |
memcpy (buf, vec->pattern + vec->rec_pos, chunk); |
memcpy (buf, vec->pattern + vec->rec_pos, chunk); |
} |
} |
else |
else |
chunk = vms_lib_bread_raw (abfd, buf, chunk); |
chunk = vms_lib_bread_raw (abfd, buf, chunk); |
} |
} |
if (chunk < 0) |
if (chunk < 0) |
return -1; |
return -1; |
res += chunk; |
res += chunk; |
if (buf != NULL) |
if (buf != NULL) |
buf += chunk; |
buf += chunk; |
nbytes -= chunk; |
nbytes -= chunk; |
vec->rec_pos += chunk; |
vec->rec_pos += chunk; |
vec->rec_rem -= chunk; |
vec->rec_rem -= chunk; |
|
|
if (vec->rec_rem == 0) |
if (vec->rec_rem == 0) |
{ |
{ |
/* End of record reached. */ |
/* End of record reached. */ |
if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt) |
if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt) |
{ |
{ |
if ((vec->rec_len & 1) == 1 |
if ((vec->rec_len & 1) == 1 |
&& vec->rec_len != 3 |
&& vec->rec_len != 3 |
&& vec->dcxsbms == NULL) |
&& vec->dcxsbms == NULL) |
{ |
{ |
/* Eat the pad byte. */ |
/* Eat the pad byte. */ |
unsigned char pad; |
unsigned char pad; |
if (vms_lib_bread_raw (abfd, &pad, 1) != 1) |
if (vms_lib_bread_raw (abfd, &pad, 1) != 1) |
return -1; |
return -1; |
} |
} |
vec->rec_pos = REC_POS_NL; |
vec->rec_pos = REC_POS_NL; |
vec->rec_rem = 1; |
vec->rec_rem = 1; |
} |
} |
else |
else |
{ |
{ |
if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL) |
if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL) |
{ |
{ |
vec->rec_pos = REC_POS_PAD; |
vec->rec_pos = REC_POS_PAD; |
vec->rec_rem = 1; |
vec->rec_rem = 1; |
} |
} |
} |
} |
} |
} |
} |
} |
vec->where += res; |
vec->where += res; |
return res; |
return res; |
Line 1160 vms_lib_bseek (struct bfd *abfd, file_pt |
|
Line 1160 vms_lib_bseek (struct bfd *abfd, file_pt |
|
vec->next_block = vec->init_next_block; |
vec->next_block = vec->init_next_block; |
|
|
if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0) |
if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0) |
return -1; |
return -1; |
} |
} |
else |
else |
abort (); |
abort (); |
Line 1190 vms_lib_bflush (struct bfd *abfd ATTRIBU |
|
Line 1190 vms_lib_bflush (struct bfd *abfd ATTRIBU |
|
|
|
static int |
static int |
vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, |
vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, |
struct stat *sb ATTRIBUTE_UNUSED) |
struct stat *sb ATTRIBUTE_UNUSED) |
{ |
{ |
/* Not supported. */ |
/* Not supported. */ |
return 0; |
return 0; |
Line 1198 vms_lib_bstat (struct bfd *abfd ATTRIBUT |
|
Line 1198 vms_lib_bstat (struct bfd *abfd ATTRIBUT |
|
|
|
static void * |
static void * |
vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, |
vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, |
void *addr ATTRIBUTE_UNUSED, |
void *addr ATTRIBUTE_UNUSED, |
bfd_size_type len ATTRIBUTE_UNUSED, |
bfd_size_type len ATTRIBUTE_UNUSED, |
int prot ATTRIBUTE_UNUSED, |
int prot ATTRIBUTE_UNUSED, |
int flags ATTRIBUTE_UNUSED, |
int flags ATTRIBUTE_UNUSED, |
file_ptr offset ATTRIBUTE_UNUSED, |
file_ptr offset ATTRIBUTE_UNUSED, |
void **map_addr ATTRIBUTE_UNUSED, |
void **map_addr ATTRIBUTE_UNUSED, |
bfd_size_type *map_len ATTRIBUTE_UNUSED) |
bfd_size_type *map_len ATTRIBUTE_UNUSED) |
{ |
{ |
return (void *) -1; |
return (void *) -1; |
} |
} |
Line 1284 vms_lib_bopen (bfd *el, file_ptr filepos |
|
Line 1284 vms_lib_bopen (bfd *el, file_ptr filepos |
|
vec->dcx_buf = bfd_alloc (el, vec->dcx_max); |
vec->dcx_buf = bfd_alloc (el, vec->dcx_max); |
vec->dcx_pos = -1; |
vec->dcx_pos = -1; |
if (vec->dcx_buf == NULL) |
if (vec->dcx_buf == NULL) |
return -1; |
return -1; |
} |
} |
return TRUE; |
return TRUE; |
} |
} |
Line 1313 _bfd_vms_lib_get_module (bfd *abfd, unsi |
|
Line 1313 _bfd_vms_lib_get_module (bfd *abfd, unsi |
|
{ |
{ |
res = _bfd_create_empty_archive_element_shell (abfd); |
res = _bfd_create_empty_archive_element_shell (abfd); |
if (res == NULL) |
if (res == NULL) |
return NULL; |
return NULL; |
|
|
/* Special reader to deal with data blocks. */ |
/* Special reader to deal with data blocks. */ |
if (!vms_lib_bopen (res, file_off)) |
if (!vms_lib_bopen (res, file_off)) |
return NULL; |
return NULL; |
} |
} |
else |
else |
{ |
{ |
Line 1327 _bfd_vms_lib_get_module (bfd *abfd, unsi |
|
Line 1327 _bfd_vms_lib_get_module (bfd *abfd, unsi |
|
|
|
/* Sanity check. The MHD must be big enough to contain module size. */ |
/* Sanity check. The MHD must be big enough to contain module size. */ |
if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4) |
if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4) |
return NULL; |
return NULL; |
|
|
/* Read the MHD now. */ |
/* Read the MHD now. */ |
if (bfd_seek (abfd, file_off, SEEK_SET) != 0) |
if (bfd_seek (abfd, file_off, SEEK_SET) != 0) |
return NULL; |
return NULL; |
if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size) |
if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size) |
return NULL; |
return NULL; |
|
|
res = _bfd_create_empty_archive_element_shell (abfd); |
res = _bfd_create_empty_archive_element_shell (abfd); |
if (res == NULL) |
if (res == NULL) |
return NULL; |
return NULL; |
arelt = bfd_zmalloc (sizeof (*arelt)); |
arelt = bfd_zmalloc (sizeof (*arelt)); |
if (arelt == NULL) |
if (arelt == NULL) |
return NULL; |
return NULL; |
res->arelt_data = arelt; |
res->arelt_data = arelt; |
|
|
/* Get info from mhd. */ |
/* Get info from mhd. */ |
mhd = (struct vms_mhd *)buf; |
mhd = (struct vms_mhd *)buf; |
if (mhd->id != MHD__C_MHDID) |
if (mhd->id != MHD__C_MHDID) |
return NULL; |
return NULL; |
if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1) |
if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1) |
res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0; |
res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0; |
res->mtime = vms_rawtime_to_time_t (mhd->datim); |
res->mtime = vms_rawtime_to_time_t (mhd->datim); |
res->mtime_set = TRUE; |
res->mtime_set = TRUE; |
|
|
arelt->parsed_size = bfd_getl32 (mhd->modsize); |
arelt->parsed_size = bfd_getl32 (mhd->modsize); |
|
|
/* No need for a special reader as members are stored linearly. |
/* No need for a special reader as members are stored linearly. |
Just skip the MHD. */ |
Just skip the MHD. */ |
res->origin = file_off + tdata->mhd_size; |
res->origin = file_off + tdata->mhd_size; |
} |
} |
|
|
Line 1402 _bfd_vms_lib_get_elt_at_index (bfd *abfd |
|
Line 1402 _bfd_vms_lib_get_elt_at_index (bfd *abfd |
|
for (modidx = 0; modidx < tdata->nbr_modules; modidx++) |
for (modidx = 0; modidx < tdata->nbr_modules; modidx++) |
{ |
{ |
if (tdata->modules[modidx].file_offset == file_off) |
if (tdata->modules[modidx].file_offset == file_off) |
break; |
break; |
} |
} |
if (modidx >= tdata->nbr_modules) |
if (modidx >= tdata->nbr_modules) |
return NULL; |
return NULL; |
Line 1441 _bfd_vms_lib_get_imagelib_file (bfd *el) |
|
Line 1441 _bfd_vms_lib_get_imagelib_file (bfd *el) |
|
|
|
if (res == NULL) |
if (res == NULL) |
{ |
{ |
(*_bfd_error_handler)(_("could not open shared image '%s' from '%s'"), |
/* xgettext:c-format */ |
filename, archive->filename); |
_bfd_error_handler(_("could not open shared image '%s' from '%s'"), |
|
filename, archive->filename); |
bfd_release (archive, filename); |
bfd_release (archive, filename); |
return NULL; |
return NULL; |
} |
} |
Line 1455 _bfd_vms_lib_get_imagelib_file (bfd *el) |
|
Line 1456 _bfd_vms_lib_get_imagelib_file (bfd *el) |
|
|
|
bfd * |
bfd * |
_bfd_vms_lib_openr_next_archived_file (bfd *archive, |
_bfd_vms_lib_openr_next_archived_file (bfd *archive, |
bfd *last_file) |
bfd *last_file) |
{ |
{ |
unsigned int idx; |
unsigned int idx; |
bfd *res; |
bfd *res; |
Line 1498 _bfd_vms_lib_generic_stat_arch_elt (bfd |
|
Line 1499 _bfd_vms_lib_generic_stat_arch_elt (bfd |
|
struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream; |
struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream; |
|
|
if (vec->file_len == (ufile_ptr)-1) |
if (vec->file_len == (ufile_ptr)-1) |
{ |
{ |
if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0) |
if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0) |
return -1; |
return -1; |
|
|
/* Compute length. */ |
/* Compute length. */ |
while (vms_lib_bread (abfd, NULL, 1 << 20) > 0) |
while (vms_lib_bread (abfd, NULL, 1 << 20) > 0) |
; |
; |
} |
} |
st->st_size = vec->file_len; |
st->st_size = vec->file_len; |
} |
} |
else |
else |
Line 1565 get_idxlen (struct lib_index *idx, bfd_b |
|
Line 1566 get_idxlen (struct lib_index *idx, bfd_b |
|
{ |
{ |
/* 9 is the size of struct vms_elfidx without keyname. */ |
/* 9 is the size of struct vms_elfidx without keyname. */ |
if (idx->namlen > MAX_KEYLEN) |
if (idx->namlen > MAX_KEYLEN) |
return 9 + sizeof (struct vms_kbn); |
return 9 + sizeof (struct vms_kbn); |
else |
else |
return 9 + idx->namlen; |
return 9 + idx->namlen; |
} |
} |
else |
else |
{ |
{ |
Line 1585 get_idxlen (struct lib_index *idx, bfd_b |
|
Line 1586 get_idxlen (struct lib_index *idx, bfd_b |
|
|
|
static bfd_boolean |
static bfd_boolean |
vms_write_index (bfd *abfd, |
vms_write_index (bfd *abfd, |
struct lib_index *idx, unsigned int nbr, unsigned int *vbn, |
struct lib_index *idx, unsigned int nbr, unsigned int *vbn, |
unsigned int *topvbn, bfd_boolean is_elfidx) |
unsigned int *topvbn, bfd_boolean is_elfidx) |
{ |
{ |
/* The index is organized as a tree. This function implements a naive |
/* The index is organized as a tree. This function implements a naive |
algorithm to balance the tree: it fills the leaves, and create a new |
algorithm to balance the tree: it fills the leaves, and create a new |
Line 1616 vms_write_index (bfd *abfd, |
|
Line 1617 vms_write_index (bfd *abfd, |
|
{ |
{ |
/* No entries. Very easy to handle. */ |
/* No entries. Very easy to handle. */ |
if (topvbn != NULL) |
if (topvbn != NULL) |
*topvbn = 0; |
*topvbn = 0; |
return TRUE; |
return TRUE; |
} |
} |
|
|
Line 1644 vms_write_index (bfd *abfd, |
|
Line 1645 vms_write_index (bfd *abfd, |
|
idxlen = get_idxlen (idx, is_elfidx); |
idxlen = get_idxlen (idx, is_elfidx); |
|
|
if (is_elfidx && idx->namlen > MAX_KEYLEN) |
if (is_elfidx && idx->namlen > MAX_KEYLEN) |
{ |
{ |
/* If the key (ie name) is too long, write it in the kbn block. */ |
/* If the key (ie name) is too long, write it in the kbn block. */ |
unsigned int kl = idx->namlen; |
unsigned int kl = idx->namlen; |
unsigned int kl_chunk; |
unsigned int kl_chunk; |
const char *key = idx->name; |
const char *key = idx->name; |
|
|
/* Write the key in the kbn, chunk after chunk. */ |
/* Write the key in the kbn, chunk after chunk. */ |
do |
do |
{ |
{ |
if (kbn_sz < sizeof (struct vms_kbn)) |
if (kbn_sz < sizeof (struct vms_kbn)) |
{ |
{ |
/* Not enough room in the kbn block. */ |
/* Not enough room in the kbn block. */ |
if (abfd != NULL) |
if (abfd != NULL) |
{ |
{ |
/* Write it to the disk (if there is one). */ |
/* Write it to the disk (if there is one). */ |
if (kbn_vbn != 0) |
if (kbn_vbn != 0) |
{ |
{ |
if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE) |
if (!vms_write_block (abfd, kbn_vbn, kbn_blk)) |
return FALSE; |
return FALSE; |
} |
} |
else |
else |
{ |
{ |
kbn_blk = bfd_malloc (VMS_BLOCK_SIZE); |
kbn_blk = bfd_malloc (VMS_BLOCK_SIZE); |
if (kbn_blk == NULL) |
if (kbn_blk == NULL) |
return FALSE; |
return FALSE; |
} |
} |
*(unsigned short *)kbn_blk = 0; |
*(unsigned short *)kbn_blk = 0; |
} |
} |
/* Allocate a new block for the keys. */ |
/* Allocate a new block for the keys. */ |
kbn_vbn = (*vbn)++; |
kbn_vbn = (*vbn)++; |
kbn_sz = VMS_BLOCK_SIZE - 2; |
kbn_sz = VMS_BLOCK_SIZE - 2; |
} |
} |
/* Size of the chunk written to the current key block. */ |
/* Size of the chunk written to the current key block. */ |
if (kl + sizeof (struct vms_kbn) > kbn_sz) |
if (kl + sizeof (struct vms_kbn) > kbn_sz) |
kl_chunk = kbn_sz - sizeof (struct vms_kbn); |
kl_chunk = kbn_sz - sizeof (struct vms_kbn); |
else |
else |
kl_chunk = kl; |
kl_chunk = kl; |
|
|
if (kbn_blk != NULL) |
if (kbn_blk != NULL) |
{ |
{ |
struct vms_kbn *kbn; |
struct vms_kbn *kbn; |
|
|
kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz); |
kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz); |
|
|
if (key_vbn == 0) |
if (key_vbn == 0) |
{ |
{ |
/* Save the rfa of the first chunk. */ |
/* Save the rfa of the first chunk. */ |
key_vbn = kbn_vbn; |
key_vbn = kbn_vbn; |
key_off = VMS_BLOCK_SIZE - kbn_sz; |
key_off = VMS_BLOCK_SIZE - kbn_sz; |
} |
} |
|
|
bfd_putl16 (kl_chunk, kbn->keylen); |
bfd_putl16 (kl_chunk, kbn->keylen); |
if (kl_chunk == kl) |
if (kl_chunk == kl) |
{ |
{ |
/* No next chunk. */ |
/* No next chunk. */ |
bfd_putl32 (0, kbn->rfa.vbn); |
bfd_putl32 (0, kbn->rfa.vbn); |
bfd_putl16 (0, kbn->rfa.offset); |
bfd_putl16 (0, kbn->rfa.offset); |
} |
} |
else |
else |
{ |
{ |
/* Next chunk will be at the start of the next block. */ |
/* Next chunk will be at the start of the next block. */ |
bfd_putl32 (*vbn, kbn->rfa.vbn); |
bfd_putl32 (*vbn, kbn->rfa.vbn); |
bfd_putl16 (2, kbn->rfa.offset); |
bfd_putl16 (2, kbn->rfa.offset); |
} |
} |
memcpy ((char *)(kbn + 1), key, kl_chunk); |
memcpy ((char *)(kbn + 1), key, kl_chunk); |
key += kl_chunk; |
key += kl_chunk; |
} |
} |
kl -= kl_chunk; |
kl -= kl_chunk; |
kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */ |
kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */ |
kbn_sz -= kl_chunk + sizeof (struct vms_kbn); |
kbn_sz -= kl_chunk + sizeof (struct vms_kbn); |
} |
} |
while (kl > 0); |
while (kl > 0); |
} |
} |
|
|
/* Check if a block might overflow. In this case we will flush this |
/* Check if a block might overflow. In this case we will flush this |
block and all the blocks below it. */ |
block and all the blocks below it. */ |
for (j = 0; j < level; j++) |
for (j = 0; j < level; j++) |
if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ) |
if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ) |
flush = j + 1; |
flush = j + 1; |
|
|
for (j = 0; j < level; j++) |
for (j = 0; j < level; j++) |
{ |
{ |
if (j < flush) |
if (j < flush) |
{ |
{ |
/* There is not enough room to write the new entry in this |
/* There is not enough room to write the new entry in this |
block or in a parent block. */ |
block or in a parent block. */ |
|
|
if (j + 1 == level) |
if (j + 1 == level) |
{ |
{ |
BFD_ASSERT (level < MAX_LEVEL); |
BFD_ASSERT (level < MAX_LEVEL); |
|
|
/* Need to create a parent. */ |
/* Need to create a parent. */ |
if (abfd != NULL) |
if (abfd != NULL) |
{ |
{ |
rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef)); |
rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef)); |
bfd_putl32 (*vbn, rblk[j]->parent); |
bfd_putl32 (*vbn, rblk[j]->parent); |
} |
} |
blk[level].vbn = (*vbn)++; |
blk[level].vbn = (*vbn)++; |
blk[level].len = 0; |
blk[level].len = 0; |
blk[level].lastlen = blk[j].lastlen; |
blk[level].lastlen = blk[j].lastlen; |
|
|
level++; |
level++; |
} |
} |
|
|
/* Update parent block: write the last entry from the current |
/* Update parent block: write the last entry from the current |
block. */ |
block. */ |
if (abfd != NULL) |
if (abfd != NULL) |
{ |
{ |
struct vms_rfa *rfa; |
struct vms_rfa *rfa; |
|
|
/* Pointer to the last entry in parent block. */ |
/* Pointer to the last entry in parent block. */ |
rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len); |
rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len); |
|
|
/* Copy the whole entry. */ |
/* Copy the whole entry. */ |
BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen); |
BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen); |
memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen); |
memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen); |
/* Fix the entry (which in always the first field of an |
/* Fix the entry (which in always the first field of an |
entry. */ |
entry. */ |
bfd_putl32 (blk[j].vbn, rfa->vbn); |
bfd_putl32 (blk[j].vbn, rfa->vbn); |
bfd_putl16 (RFADEF__C_INDEX, rfa->offset); |
bfd_putl16 (RFADEF__C_INDEX, rfa->offset); |
} |
} |
|
|
if (j + 1 == flush) |
if (j + 1 == flush) |
{ |
{ |
/* And allocate it. Do it only on the block that won't be |
/* And allocate it. Do it only on the block that won't be |
flushed (so that the parent of the parent can be |
flushed (so that the parent of the parent can be |
updated too). */ |
updated too). */ |
blk[j + 1].len += blk[j + 1].lastlen; |
blk[j + 1].len += blk[j + 1].lastlen; |
blk[j + 1].lastlen = 0; |
blk[j + 1].lastlen = 0; |
} |
} |
|
|
/* Write this block on the disk. */ |
/* Write this block on the disk. */ |
if (abfd != NULL) |
if (abfd != NULL) |
{ |
{ |
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) |
if (!vms_write_block (abfd, blk[j].vbn, rblk[j])) |
return FALSE; |
return FALSE; |
} |
} |
|
|
/* Reset this block. */ |
/* Reset this block. */ |
blk[j].len = 0; |
blk[j].len = 0; |
blk[j].lastlen = 0; |
blk[j].lastlen = 0; |
blk[j].vbn = (*vbn)++; |
blk[j].vbn = (*vbn)++; |
} |
} |
|
|
/* Append it to the block. */ |
/* Append it to the block. */ |
if (j == 0) |
if (j == 0) |
{ |
{ |
/* Keep the previous last entry. */ |
/* Keep the previous last entry. */ |
blk[j].len += blk[j].lastlen; |
blk[j].len += blk[j].lastlen; |
|
|
if (abfd != NULL) |
if (abfd != NULL) |
{ |
{ |
struct vms_rfa *rfa; |
struct vms_rfa *rfa; |
|
|
rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len); |
rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len); |
bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1, |
bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1, |
rfa->vbn); |
rfa->vbn); |
bfd_putl16 |
bfd_putl16 |
((idx->abfd->proxy_origin % VMS_BLOCK_SIZE) |
((idx->abfd->proxy_origin % VMS_BLOCK_SIZE) |
+ (is_elfidx ? 0 : DATA__DATA), |
+ (is_elfidx ? 0 : DATA__DATA), |
rfa->offset); |
rfa->offset); |
|
|
if (is_elfidx) |
if (is_elfidx) |
{ |
{ |
/* Use elfidx format. */ |
/* Use elfidx format. */ |
struct vms_elfidx *en = (struct vms_elfidx *)rfa; |
struct vms_elfidx *en = (struct vms_elfidx *)rfa; |
|
|
en->flags = 0; |
en->flags = 0; |
if (key_vbn != 0) |
if (key_vbn != 0) |
{ |
{ |
/* Long symbol name. */ |
/* Long symbol name. */ |
struct vms_kbn *k = (struct vms_kbn *)(en->keyname); |
struct vms_kbn *k = (struct vms_kbn *)(en->keyname); |
bfd_putl16 (sizeof (struct vms_kbn), en->keylen); |
bfd_putl16 (sizeof (struct vms_kbn), en->keylen); |
bfd_putl16 (idx->namlen, k->keylen); |
bfd_putl16 (idx->namlen, k->keylen); |
bfd_putl32 (key_vbn, k->rfa.vbn); |
bfd_putl32 (key_vbn, k->rfa.vbn); |
bfd_putl16 (key_off, k->rfa.offset); |
bfd_putl16 (key_off, k->rfa.offset); |
en->flags |= ELFIDX__SYMESC; |
en->flags |= ELFIDX__SYMESC; |
} |
} |
else |
else |
{ |
{ |
bfd_putl16 (idx->namlen, en->keylen); |
bfd_putl16 (idx->namlen, en->keylen); |
memcpy (en->keyname, idx->name, idx->namlen); |
memcpy (en->keyname, idx->name, idx->namlen); |
} |
} |
} |
} |
else |
else |
{ |
{ |
/* Use idx format. */ |
/* Use idx format. */ |
struct vms_idx *en = (struct vms_idx *)rfa; |
struct vms_idx *en = (struct vms_idx *)rfa; |
en->keylen = idx->namlen; |
en->keylen = idx->namlen; |
memcpy (en->keyname, idx->name, idx->namlen); |
memcpy (en->keyname, idx->name, idx->namlen); |
} |
} |
} |
} |
} |
} |
/* The last added key can now be the last one all blocks in the |
/* The last added key can now be the last one all blocks in the |
path. */ |
path. */ |
blk[j].lastlen = idxlen; |
blk[j].lastlen = idxlen; |
} |
} |
} |
} |
|
|
/* Save VBN of the root. */ |
/* Save VBN of the root. */ |
Line 1872 vms_write_index (bfd *abfd, |
|
Line 1873 vms_write_index (bfd *abfd, |
|
{ |
{ |
/* Write this block on the disk. */ |
/* Write this block on the disk. */ |
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) |
if (!vms_write_block (abfd, blk[j].vbn, rblk[j])) |
return FALSE; |
return FALSE; |
|
|
free (rblk[j]); |
free (rblk[j]); |
} |
} |
Line 1881 vms_write_index (bfd *abfd, |
|
Line 1882 vms_write_index (bfd *abfd, |
|
/* Write the last kbn (if any). */ |
/* Write the last kbn (if any). */ |
if (kbn_vbn != 0) |
if (kbn_vbn != 0) |
{ |
{ |
if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE) |
if (!vms_write_block (abfd, kbn_vbn, kbn_blk)) |
return FALSE; |
return FALSE; |
free (kbn_blk); |
free (kbn_blk); |
} |
} |
|
|
Line 1893 vms_write_index (bfd *abfd, |
|
Line 1894 vms_write_index (bfd *abfd, |
|
|
|
static bfd_boolean |
static bfd_boolean |
vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off, |
vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off, |
const unsigned char *buf, unsigned int len, int pad) |
const unsigned char *buf, unsigned int len, int pad) |
{ |
{ |
while (len > 0 || pad) |
while (len > 0 || pad) |
{ |
{ |
Line 1909 vms_write_data_block (bfd *arch, struct |
|
Line 1910 vms_write_data_block (bfd *arch, struct |
|
*off += l; |
*off += l; |
|
|
if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad)) |
if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad)) |
{ |
{ |
data->recs = 0; |
data->recs = 0; |
data->fill_1 = 0; |
data->fill_1 = 0; |
bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link); |
bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link); |
|
|
if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data)) |
if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data)) |
return FALSE; |
return FALSE; |
|
|
*off += DATA__LENGTH - doff; |
*off += DATA__LENGTH - doff; |
|
|
if (len == 0) |
if (len == 0) |
break; |
break; |
} |
} |
} |
} |
return TRUE; |
return TRUE; |
} |
} |
Line 1930 vms_write_data_block (bfd *arch, struct |
|
Line 1931 vms_write_data_block (bfd *arch, struct |
|
|
|
static bfd_boolean |
static bfd_boolean |
_bfd_vms_lib_build_map (unsigned int nbr_modules, |
_bfd_vms_lib_build_map (unsigned int nbr_modules, |
struct lib_index *modules, |
struct lib_index *modules, |
unsigned int *res_cnt, |
unsigned int *res_cnt, |
struct lib_index **res) |
struct lib_index **res) |
{ |
{ |
unsigned int i; |
unsigned int i; |
asymbol **syms = NULL; |
asymbol **syms = NULL; |
Line 1954 _bfd_vms_lib_build_map (unsigned int nbr |
|
Line 1955 _bfd_vms_lib_build_map (unsigned int nbr |
|
bfd *current = modules[i].abfd; |
bfd *current = modules[i].abfd; |
|
|
if ((bfd_get_file_flags (current) & HAS_SYMS) == 0) |
if ((bfd_get_file_flags (current) & HAS_SYMS) == 0) |
continue; |
continue; |
|
|
storage = bfd_get_symtab_upper_bound (current); |
storage = bfd_get_symtab_upper_bound (current); |
if (storage < 0) |
if (storage < 0) |
goto error_return; |
goto error_return; |
|
|
if (storage != 0) |
if (storage != 0) |
{ |
{ |
if (storage > syms_max) |
if (storage > syms_max) |
{ |
{ |
if (syms_max > 0) |
if (syms_max > 0) |
free (syms); |
free (syms); |
syms_max = storage; |
syms_max = storage; |
syms = (asymbol **) bfd_malloc (syms_max); |
syms = (asymbol **) bfd_malloc (syms_max); |
if (syms == NULL) |
if (syms == NULL) |
goto error_return; |
goto error_return; |
} |
} |
symcount = bfd_canonicalize_symtab (current, syms); |
symcount = bfd_canonicalize_symtab (current, syms); |
if (symcount < 0) |
if (symcount < 0) |
goto error_return; |
goto error_return; |
|
|
/* Now map over all the symbols, picking out the ones we |
/* Now map over all the symbols, picking out the ones we |
want. */ |
want. */ |
for (src_count = 0; src_count < symcount; src_count++) |
for (src_count = 0; src_count < symcount; src_count++) |
{ |
{ |
flagword flags = (syms[src_count])->flags; |
flagword flags = (syms[src_count])->flags; |
asection *sec = syms[src_count]->section; |
asection *sec = syms[src_count]->section; |
|
|
if ((flags & BSF_GLOBAL |
if ((flags & BSF_GLOBAL |
|| flags & BSF_WEAK |
|| flags & BSF_WEAK |
|| flags & BSF_INDIRECT |
|| flags & BSF_INDIRECT |
|| bfd_is_com_section (sec)) |
|| bfd_is_com_section (sec)) |
&& ! bfd_is_und_section (sec)) |
&& ! bfd_is_und_section (sec)) |
{ |
{ |
struct lib_index *new_map; |
struct lib_index *new_map; |
|
|
/* This symbol will go into the archive header. */ |
/* This symbol will go into the archive header. */ |
if (map_count == map_max) |
if (map_count == map_max) |
{ |
{ |
map_max *= 2; |
map_max *= 2; |
new_map = (struct lib_index *) |
new_map = (struct lib_index *) |
bfd_realloc (map, map_max * sizeof (struct lib_index)); |
bfd_realloc (map, map_max * sizeof (struct lib_index)); |
if (new_map == NULL) |
if (new_map == NULL) |
goto error_return; |
goto error_return; |
map = new_map; |
map = new_map; |
} |
} |
|
|
map[map_count].abfd = current; |
map[map_count].abfd = current; |
map[map_count].namlen = strlen (syms[src_count]->name); |
map[map_count].namlen = strlen (syms[src_count]->name); |
map[map_count].name = syms[src_count]->name; |
map[map_count].name = syms[src_count]->name; |
map_count++; |
map_count++; |
modules[i].ref++; |
modules[i].ref++; |
} |
} |
} |
} |
} |
} |
} |
} |
|
|
Line 2117 _bfd_vms_lib_write_archive_contents (bfd |
|
Line 2118 _bfd_vms_lib_write_archive_contents (bfd |
|
current->proxy_origin = off; |
current->proxy_origin = off; |
|
|
if (is_elfidx) |
if (is_elfidx) |
sz = 0; |
sz = 0; |
else |
else |
{ |
{ |
/* Write the MHD as a record (ie, size first). */ |
/* Write the MHD as a record (ie, size first). */ |
sz = 2; |
sz = 2; |
bfd_putl16 (tdata->mhd_size, blk); |
bfd_putl16 (tdata->mhd_size, blk); |
} |
} |
mhd = (struct vms_mhd *)(blk + sz); |
mhd = (struct vms_mhd *)(blk + sz); |
memset (mhd, 0, sizeof (struct vms_mhd)); |
memset (mhd, 0, sizeof (struct vms_mhd)); |
mhd->lbrflag = 0; |
mhd->lbrflag = 0; |
Line 2138 _bfd_vms_lib_write_archive_contents (bfd |
|
Line 2139 _bfd_vms_lib_write_archive_contents (bfd |
|
|
|
/* Rewind the member to be put into the archive. */ |
/* Rewind the member to be put into the archive. */ |
if (bfd_seek (current, 0, SEEK_SET) != 0) |
if (bfd_seek (current, 0, SEEK_SET) != 0) |
goto input_err; |
goto input_err; |
|
|
/* Copy the member into the archive. */ |
/* Copy the member into the archive. */ |
if (is_elfidx) |
if (is_elfidx) |
{ |
{ |
unsigned int modsize = 0; |
unsigned int modsize = 0; |
bfd_size_type amt; |
bfd_size_type amt; |
file_ptr off_hdr = off; |
file_ptr off_hdr = off; |
|
|
/* Read to complete the first block. */ |
/* Read to complete the first block. */ |
amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current); |
amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current); |
if (amt == (bfd_size_type)-1) |
if (amt == (bfd_size_type)-1) |
goto input_err; |
goto input_err; |
modsize = amt; |
modsize = amt; |
if (amt < VMS_BLOCK_SIZE - sz) |
if (amt < VMS_BLOCK_SIZE - sz) |
{ |
{ |
/* The member size is less than a block. Pad the block. */ |
/* The member size is less than a block. Pad the block. */ |
memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt); |
memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt); |
} |
} |
bfd_putl32 (modsize, mhd->modsize); |
bfd_putl32 (modsize, mhd->modsize); |
|
|
/* Write the first block (which contains an mhd). */ |
/* Write the first block (which contains an mhd). */ |
if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE) |
if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE) |
goto input_err; |
goto input_err; |
off += VMS_BLOCK_SIZE; |
off += VMS_BLOCK_SIZE; |
|
|
if (amt == VMS_BLOCK_SIZE - sz) |
if (amt == VMS_BLOCK_SIZE - sz) |
{ |
{ |
/* Copy the remaining. */ |
/* Copy the remaining. */ |
char buffer[DEFAULT_BUFFERSIZE]; |
char buffer[DEFAULT_BUFFERSIZE]; |
|
|
while (1) |
while (1) |
{ |
{ |
amt = bfd_bread (buffer, sizeof (buffer), current); |
amt = bfd_bread (buffer, sizeof (buffer), current); |
if (amt == (bfd_size_type)-1) |
if (amt == (bfd_size_type)-1) |
goto input_err; |
goto input_err; |
if (amt == 0) |
if (amt == 0) |
break; |
break; |
modsize += amt; |
modsize += amt; |
if (amt != sizeof (buffer)) |
if (amt != sizeof (buffer)) |
{ |
{ |
/* Clear the padding. */ |
/* Clear the padding. */ |
memset (buffer + amt, 0, sizeof (buffer) - amt); |
memset (buffer + amt, 0, sizeof (buffer) - amt); |
amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1); |
amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1); |
} |
} |
if (bfd_bwrite (buffer, amt, arch) != amt) |
if (bfd_bwrite (buffer, amt, arch) != amt) |
goto input_err; |
goto input_err; |
off += amt; |
off += amt; |
} |
} |
|
|
/* Now that the size is known, write the first block (again). */ |
/* Now that the size is known, write the first block (again). */ |
bfd_putl32 (modsize, mhd->modsize); |
bfd_putl32 (modsize, mhd->modsize); |
if (bfd_seek (arch, off_hdr, SEEK_SET) != 0 |
if (bfd_seek (arch, off_hdr, SEEK_SET) != 0 |
|| bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE) |
|| bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE) |
goto input_err; |
goto input_err; |
if (bfd_seek (arch, off, SEEK_SET) != 0) |
if (bfd_seek (arch, off, SEEK_SET) != 0) |
goto input_err; |
goto input_err; |
} |
} |
} |
} |
else |
else |
{ |
{ |
/* Write the MHD. */ |
/* Write the MHD. */ |
if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0) |
if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0) |
goto input_err; |
goto input_err; |
|
|
/* Write the member. */ |
/* Write the member. */ |
while (1) |
while (1) |
{ |
{ |
sz = bfd_bread (blk, sizeof (blk), current); |
sz = bfd_bread (blk, sizeof (blk), current); |
if (sz == 0) |
if (sz == 0) |
break; |
break; |
if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0) |
if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0) |
goto input_err; |
goto input_err; |
} |
} |
|
|
/* Write the end of module marker. */ |
/* Write the end of module marker. */ |
if (vms_write_data_block (arch, &data, &off, |
if (vms_write_data_block (arch, &data, &off, |
eotdesc, sizeof (eotdesc), 1) < 0) |
eotdesc, sizeof (eotdesc), 1) < 0) |
goto input_err; |
goto input_err; |
} |
} |
} |
} |
|
|
/* Write the indexes. */ |
/* Write the indexes. */ |
vbn = 2; |
vbn = 2; |
if (vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn, |
if (!vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn, |
is_elfidx) != TRUE) |
is_elfidx)) |
return FALSE; |
return FALSE; |
if (vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn, |
if (!vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn, |
is_elfidx) != TRUE) |
is_elfidx)) |
return FALSE; |
return FALSE; |
|
|
/* Write libary header. */ |
/* Write libary header. */ |
Line 2244 _bfd_vms_lib_write_archive_contents (bfd |
|
Line 2245 _bfd_vms_lib_write_archive_contents (bfd |
|
switch (tdata->kind) |
switch (tdata->kind) |
{ |
{ |
case vms_lib_alpha: |
case vms_lib_alpha: |
saneid = LHD_SANEID3; |
saneid = LHD_SANEID3; |
break; |
break; |
case vms_lib_ia64: |
case vms_lib_ia64: |
saneid = LHD_SANEID6; |
saneid = LHD_SANEID6; |
break; |
break; |
default: |
default: |
abort (); |
abort (); |
} |
} |
bfd_putl32 (saneid, lhd->sanity); |
bfd_putl32 (saneid, lhd->sanity); |
bfd_putl16 (tdata->ver, lhd->majorid); |
bfd_putl16 (tdata->ver, lhd->majorid); |
bfd_putl16 (0, lhd->minorid); |
bfd_putl16 (0, lhd->minorid); |
snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1, |
snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1, |
"GNU ar %u.%u.%u", |
"GNU ar %u.%u.%u", |
(unsigned)(BFD_VERSION / 100000000UL), |
(unsigned)(BFD_VERSION / 100000000UL), |
(unsigned)(BFD_VERSION / 1000000UL) % 100, |
(unsigned)(BFD_VERSION / 1000000UL) % 100, |
(unsigned)(BFD_VERSION / 10000UL) % 100); |
(unsigned)(BFD_VERSION / 10000UL) % 100); |
lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0; |
lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0; |
lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1); |
lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1); |
|
|
Line 2297 _bfd_vms_lib_write_archive_contents (bfd |
|
Line 2298 _bfd_vms_lib_write_archive_contents (bfd |
|
bfd_putl16 (sym_idx_vbn, idd->vbn); |
bfd_putl16 (sym_idx_vbn, idd->vbn); |
idd++; |
idd++; |
|
|
if (vms_write_block (arch, 1, blk) != TRUE) |
if (!vms_write_block (arch, 1, blk)) |
return FALSE; |
return FALSE; |
} |
} |
|
|
return TRUE; |
return TRUE; |
|
|
input_err: |
input_err: |
bfd_set_error (bfd_error_on_input, current, bfd_get_error ()); |
bfd_set_input_error (current, bfd_get_error ()); |
return FALSE; |
return FALSE; |
} |
} |
|
|
Line 2329 const bfd_target alpha_vms_lib_txt_vec = |
|
Line 2330 const bfd_target alpha_vms_lib_txt_vec = |
|
bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
bfd_getl32, bfd_getl_signed_32, bfd_putl32, |
bfd_getl32, bfd_getl_signed_32, bfd_putl32, |
bfd_getl16, bfd_getl_signed_16, bfd_putl16, |
bfd_getl16, bfd_getl_signed_16, bfd_putl16, |
|
{ /* bfd_check_format. */ |
{_bfd_dummy_target, _bfd_dummy_target, /* bfd_check_format. */ |
_bfd_dummy_target, |
_bfd_vms_lib_txt_archive_p, _bfd_dummy_target}, |
_bfd_dummy_target, |
{bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_set_format. */ |
_bfd_vms_lib_txt_archive_p, |
{bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_write_contents. */ |
_bfd_dummy_target |
|
}, |
|
{ /* bfd_set_format. */ |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error |
|
}, |
|
{ /* bfd_write_contents. */ |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error, |
|
_bfd_bool_bfd_false_error |
|
}, |
BFD_JUMP_TABLE_GENERIC (_bfd_generic), |
BFD_JUMP_TABLE_GENERIC (_bfd_generic), |
BFD_JUMP_TABLE_COPY (_bfd_generic), |
BFD_JUMP_TABLE_COPY (_bfd_generic), |
BFD_JUMP_TABLE_CORE (_bfd_nocore), |
BFD_JUMP_TABLE_CORE (_bfd_nocore), |