2010-04-30  Tristan Gingold  <gingold@adacore.com>

	* vms-lib.c (struct lib_tdata): Field artdata added, fields nbr_syms
	and syms removed.
	(struct carsym_mem): New structure.
	(vms_add_index): New function.
	(vms_add_indexes_from_list): New function.
	(vms_traverse_index): Parameter carsym changed to carsym_mem.
	Code adjusted to handle elfidx.
	(vms_lib_read_index): Adjusted for vms_traverse_index changes.
	Parameter NBREL is now a pointer.
	(_bfd_vms_lib_archive_p): Adjust for above change.  Handle ia64
	archives.
	(_bfd_vms_lib_mkarchive): Adjusted for changes in struct lib_tdata.
	(_bfd_vms_lib_find_symbol): Ditto.
	(vms_lib_bopen): Fix two typos: return FALSE in case of error,
	check MHD id.
	* vms-alpha.c (alpha_vms_link_add_archive_symbols): Adjust for
	changes of _bfd_vms_lib_find_symbol.

include/vms
2010-04-30  Tristan Gingold  <gingold@adacore.com>

	* lbr.h (LBR__C_TYP_ISHSTB): Added.
	(LHD_SANEID4): Renamed to ...
	(LHD_SANEID6): ...  this.
	(LBR_MAJORID, LBR_ELFMAJORID): New macros.
	(struct vms_rfa): New structure.
	(struct vms_idxdef): Renamed to ...
	(struct vms_idx): ... this.
	(struct vms_idxdef2): Renamed to ...
	(struct vms_elfidx): ... this.
	(ELFIDX__WEAK, ELFIDX__GROUP, ELFIDX__LISTRFA, ELFIDX__SYMESC): New
	macros.
	(struct vms_lhs, struct vms_lns): New structures.
	(struct vms_mhd): Add missing fields.
	(MHD__C_MHDLEN): New macro.
This commit is contained in:
Tristan Gingold 2010-04-30 09:40:42 +00:00
parent c24d024232
commit 8e57e1d134
5 changed files with 466 additions and 126 deletions

View File

@ -1,3 +1,29 @@
2010-04-30 Tristan Gingold <gingold@adacore.com>
* vms-lib.c (struct lib_tdata): Field artdata added, fields nbr_syms
and syms removed.
(struct carsym_mem): New structure.
(vms_add_index): New function.
(vms_add_indexes_from_list): New function.
(vms_traverse_index): Parameter carsym changed to carsym_mem.
Code adjusted to handle elfidx.
(vms_lib_read_index): Adjusted for vms_traverse_index changes.
Parameter NBREL is now a pointer.
(_bfd_vms_lib_archive_p): Adjust for above change. Handle ia64
archives.
(_bfd_vms_lib_mkarchive): Adjusted for changes in struct lib_tdata.
(_bfd_vms_lib_find_symbol): Ditto.
(vms_lib_bopen): Fix two typos: return FALSE in case of error,
check MHD id.
(_bfd_vms_lib_get_module): New function.
(_bfd_vms_lib_get_elt_at_index): Rewritten using the above
function.
(_bfd_vms_lib_openr_next_archived_file): Use _bfd_vms_lib_get_module.
(_bfd_vms_lib_generic_stat_arch_elt): Handle ia64 archives.
(vms_write_index): Adjust for structure renamed.
* vms-alpha.c (alpha_vms_link_add_archive_symbols): Adjust for
changes of _bfd_vms_lib_find_symbol.
2010-04-28 Kai Tietz <kai.tietz@onevision.com>
* config.bfd: Correct accidential reverted patch

View File

@ -8040,7 +8040,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef)
{
struct bfd_link_hash_entry *h;
file_ptr file_offset;
symindex symidx;
bfd *element;
bfd *orig_element;
@ -8066,14 +8066,14 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
}
/* Look for this symbol in the archive hash table. */
file_offset = _bfd_vms_lib_find_symbol (abfd, h->root.string);
if (file_offset == 0)
symidx = _bfd_vms_lib_find_symbol (abfd, h->root.string);
if (symidx == BFD_NO_MORE_SYMBOLS)
{
/* Nothing in this slot. */
continue;
}
element = bfd_get_elt_at_index (abfd, file_offset);
element = bfd_get_elt_at_index (abfd, symidx);
if (element == NULL)
return FALSE;

View File

@ -62,6 +62,9 @@ enum vms_lib_kind
struct lib_tdata
{
/* Standard tdata for an archive. But we don't use many fields. */
struct artdata artdata;
/* Major version. */
unsigned char ver;
@ -79,10 +82,6 @@ struct lib_tdata
struct carsym *modules;
bfd **cache;
/* Vector of symbols (archive map), already sorted. */
unsigned int nbr_syms;
struct carsym *syms;
/* DCX (decompression) data. */
unsigned int nbr_dcxsbm;
struct dcxsbm_desc *dcxsbm;
@ -94,16 +93,109 @@ struct lib_tdata
static const unsigned char eotdesc[] = { 0x03, 0x00, 0x77, 0x00, 0x77, 0x00 };
/* Describe the current state of carsym entries while building the archive
table of content. Things are simple with Alpha archives as the number
of entries is known, but with IA64 archives a entry can make a reference
to severals members. Therefore we must be able to extend the table on the
fly, but it should be allocated on the bfd - which doesn't support realloc.
To reduce the overhead, the table is initially allocated in the BFD's
objalloc and extended if necessary on the heap. In the later case, it
is finally copied to the BFD's objalloc so that it will automatically be
freed. */
struct carsym_mem
{
/* The table of content. */
struct carsym *idx;
/* Number of entries used in the table. */
unsigned int nbr;
/* Maximum number of entries. */
unsigned int max;
/* If true, the table was reallocated on the heap. If false, it is still
in the BFD's objalloc. */
bfd_boolean realloced;
};
/* Simply add a name to the index. */
static bfd_boolean
vms_add_index (struct carsym_mem *cs, char *name,
unsigned int idx_vbn, unsigned int idx_off)
{
if (cs->nbr == cs->max)
{
struct carsym *n;
cs->max = 2 * cs->max + 32;
if (!cs->realloced)
{
n = bfd_malloc2 (cs->max, sizeof (struct carsym));
if (n == NULL)
return FALSE;
memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));
/* And unfortunately we can't free cs->idx. */
}
else
{
n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym));
if (n == NULL)
return FALSE;
}
cs->idx = n;
cs->realloced = TRUE;
}
cs->idx[cs->nbr].file_offset = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
cs->idx[cs->nbr].name = name;
cs->nbr++;
return TRUE;
}
/* Follow all member of a lns list (pointed by RFA) and add indexes for
NAME. Return FALSE in case of error. */
static bfd_boolean
vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name,
struct vms_rfa *rfa)
{
struct vms_lns lns;
unsigned int vbn;
file_ptr off;
while (1)
{
vbn = bfd_getl32 (rfa->vbn);
if (vbn == 0)
return TRUE;
/* Read the LHS. */
off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset);
if (bfd_seek (abfd, off, SEEK_SET) != 0
|| bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns))
return FALSE;
if (!vms_add_index (cs, name,
bfd_getl32 (lns.modrfa.vbn),
bfd_getl16 (lns.modrfa.offset)))
return FALSE;
rfa = &lns.nxtrfa;
}
}
/* Read index block VBN and put the entry in **IDX (which is updated).
If the entry is indirect, recurse. */
static bfd_boolean
vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym **idx)
vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs)
{
struct vms_indexdef indexdef;
unsigned int used;
file_ptr off;
unsigned int i;
unsigned char *p;
unsigned char *endp;
/* Read the index block. */
off = (vbn - 1) * VMS_BLOCK_SIZE;
@ -112,44 +204,54 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym **idx)
return FALSE;
/* Traverse it. */
used = bfd_getl16 (indexdef.used);
for (i = 0; i < used;)
p = &indexdef.keys[0];
endp = p + bfd_getl16 (indexdef.used);
while (p < endp)
{
unsigned int idx_vbn;
unsigned int idx_off;
unsigned int keylen;
unsigned char *keyname;
unsigned char *ridx = (unsigned char *)&indexdef.keys[i];
unsigned int len;
unsigned int flags;
idx_vbn = bfd_getl32 (ridx);
idx_off = bfd_getl16 (ridx + 4);
/* Extract key length. */
if (bfd_libdata (abfd)->ver == LBR_MAJORID)
{
struct vms_idx *ridx = (struct vms_idx *)p;
idx_vbn = bfd_getl32 (ridx->rfa.vbn);
idx_off = bfd_getl16 (ridx->rfa.offset);
keylen = ridx->keylen;
flags = 0;
keyname = ridx->keyname;
}
else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID)
{
struct vms_elfidx *ridx = (struct vms_elfidx *)p;
idx_vbn = bfd_getl32 (ridx->rfa.vbn);
idx_off = bfd_getl16 (ridx->rfa.offset);
keylen = bfd_getl16 (ridx->keylen);
flags = ridx->flags;
keyname = ridx->keyname;
}
else
return FALSE;
/* Illegal value. */
if (idx_vbn == 0)
return FALSE;
/* Extract key length. */
if (bfd_libdata (abfd)->ver == 3)
{
keylen = ridx[6];
len = 7;
}
else if (bfd_libdata (abfd)->ver == 4)
{
keylen = bfd_getl16 (ridx + 6);
len = 9;
}
else
/* Long symbol names are not yet supported. */
if (flags & ELFIDX__SYMESC)
return FALSE;
keyname = ridx + len;
i += len + keylen;
if (idx_off == RFADEF__C_INDEX)
{
/* Indirect entry. Recurse. */
if (!vms_traverse_index (abfd, idx_vbn, idx))
if (!vms_traverse_index (abfd, idx_vbn, cs))
return FALSE;
}
else
@ -162,10 +264,36 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym **idx)
return FALSE;
memcpy (name, keyname, keylen);
name[keylen] = 0;
(*idx)->file_offset = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
(*idx)->name = name;
(*idx)++;
if (flags & ELFIDX__LISTRFA)
{
struct vms_lhs lhs;
/* Read the LHS. */
off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
if (bfd_seek (abfd, off, SEEK_SET) != 0
|| bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs))
return FALSE;
/* FIXME: this adds extra entries that were not accounted. */
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa))
return FALSE;
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa))
return FALSE;
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa))
return FALSE;
if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa))
return FALSE;
}
else
{
if (!vms_add_index (cs, name, idx_vbn, idx_off))
return FALSE;
}
}
/* Point to the next index entry. */
p = keyname + keylen;
}
return TRUE;
@ -174,13 +302,13 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym **idx)
/* Read index #IDX, which must have NBREL entries. */
static struct carsym *
vms_lib_read_index (bfd *abfd, int idx, unsigned int nbrel)
vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel)
{
struct carsym *res;
struct carsym *el;
struct vms_idd idd;
unsigned int flags;
unsigned int vbn;
struct carsym *csbuf;
struct carsym_mem csm;
/* Read index desription. */
if (bfd_seek (abfd, LHD_IDXDESC + idx * IDD_LENGTH, SEEK_SET) != 0
@ -193,28 +321,40 @@ vms_lib_read_index (bfd *abfd, int idx, unsigned int nbrel)
|| !(flags & IDD__FLAGS_VARLENIDX))
return NULL;
res = bfd_alloc (abfd, nbrel * sizeof (struct carsym));
if (res == NULL)
csbuf = bfd_alloc (abfd, *nbrel * sizeof (struct carsym));
if (csbuf == NULL)
return NULL;
el = res;
csm.max = *nbrel;
csm.nbr = 0;
csm.realloced = FALSE;
csm.idx = csbuf;
/* Note: if the index is empty, there is no block to traverse. */
vbn = bfd_getl32 (idd.vbn);
if (vbn != 0 && !vms_traverse_index (abfd, vbn, &el))
if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm))
{
bfd_release (abfd, res);
if (csm.realloced && csm.idx != NULL)
free (csm.idx);
/* Note: in case of error, we can free what was allocated on the
BFD's objalloc. */
bfd_release (abfd, csbuf);
return NULL;
}
if ((unsigned int)(el - res) != nbrel)
if (csm.realloced)
{
/* Inconsistency between the number of modules declared and the number
of modules found in the index. */
bfd_release (abfd, res);
return NULL;
/* There are more entries than the first estimate. Allocate on
the BFD's objalloc. */
csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym));
if (csbuf == NULL)
return NULL;
memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym));
free (csm.idx);
*nbrel = csm.nbr;
}
return res;
return csbuf;
}
/* Standard function. */
@ -227,6 +367,7 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
struct lib_tdata *tdata_hold;
struct lib_tdata *tdata;
unsigned int dcxvbn;
unsigned int nbr_ent;
/* Read header. */
if (bfd_bread (&lhd, sizeof (lhd), abfd) != sizeof (lhd))
@ -239,7 +380,7 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
/* Check sanity (= magic) number. */
sanity = bfd_getl32 (lhd.sanity);
if (!(sanity == LHD_SANEID3
|| sanity == LHD_SANEID4
|| sanity == LHD_SANEID6
|| sanity == LHD_SANEID_DCX))
{
bfd_set_error (bfd_error_wrong_format);
@ -258,6 +399,15 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
return NULL;
}
break;
case vms_lib_ia64:
if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB)
|| bfd_getl32 (lhd.majorid) != 6
|| lhd.nindex != 2)
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
break;
case vms_lib_txt:
if ((lhd.type != LBR__C_TYP_TXT
&& lhd.type != LBR__C_TYP_MLB
@ -286,15 +436,23 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
/* Read indexes. */
tdata->nbr_modules = bfd_getl32 (lhd.modcnt);
tdata->nbr_syms = bfd_getl32 (lhd.idxcnt) - tdata->nbr_modules;
tdata->modules = vms_lib_read_index (abfd, 0, tdata->nbr_modules);
if (tdata->modules == NULL)
tdata->artdata.symdef_count = bfd_getl32 (lhd.idxcnt) - tdata->nbr_modules;
nbr_ent = tdata->nbr_modules;
tdata->modules = vms_lib_read_index (abfd, 0, &nbr_ent);
if (tdata->modules == NULL || nbr_ent != tdata->nbr_modules)
goto err;
if (lhd.nindex == 2)
{
tdata->syms = vms_lib_read_index (abfd, 1, tdata->nbr_syms);
if (tdata->syms == NULL)
nbr_ent = tdata->artdata.symdef_count;
tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent);
if (tdata->artdata.symdefs == NULL)
goto err;
/* Only IA64 archives may have more entries in the index that what
was declared. */
if (nbr_ent != tdata->artdata.symdef_count
&& kind != vms_lib_ia64)
goto err;
tdata->artdata.symdef_count = nbr_ent;
}
tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules);
if (tdata->cache == NULL)
@ -368,7 +526,7 @@ _bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
/* The map is always present. Also mark shared image library. */
abfd->has_armap = TRUE;
if (tdata->type == LBR__C_TYP_ESHSTB)
if (tdata->type == LBR__C_TYP_ESHSTB || tdata->type == LBR__C_TYP_ISHSTB)
abfd->is_thin_archive = TRUE;
return abfd->xvec;
@ -412,9 +570,9 @@ _bfd_vms_lib_mkarchive (bfd *abfd)
tdata->type = LBR__C_TYP_EOBJ;
tdata->nbr_modules = 0;
tdata->nbr_syms = 0;
tdata->artdata.symdef_count = 0;
tdata->modules = NULL;
tdata->syms = NULL;
tdata->artdata.symdefs = NULL;
tdata->cache = NULL;
return TRUE;
@ -426,28 +584,29 @@ symindex
_bfd_vms_lib_find_symbol (bfd *abfd, const char *name)
{
struct lib_tdata *tdata = bfd_libdata (abfd);
carsym *syms = tdata->artdata.symdefs;
int lo, hi;
/* Open-coded binary search for speed. */
lo = 0;
hi = tdata->nbr_syms - 1;
hi = tdata->artdata.symdef_count - 1;
while (lo <= hi)
{
int mid = lo + (hi - lo) / 2;
int diff;
diff = (char)(name[0] - tdata->syms[mid].name[0]);
diff = (char)(name[0] - syms[mid].name[0]);
if (diff == 0)
diff = strcmp (name, tdata->syms[mid].name);
diff = strcmp (name, syms[mid].name);
if (diff == 0)
return tdata->syms[mid].file_offset;
return mid;
else if (diff < 0)
hi = mid - 1;
else
lo = mid + 1;
}
return 0;
return BFD_NO_MORE_SYMBOLS;
}
/* IO vector for archive member. Need that because members are not linearly
@ -955,16 +1114,19 @@ vms_lib_bopen (bfd *el, file_ptr filepos)
/* Read Record length + MHD + align byte. */
len = tdata->mhd_size;
if (vms_lib_bread_raw (el, buf, 2) != 2)
return -1;
return FALSE;
if (bfd_getl16 (buf) != len)
return -1;
return FALSE;
len = (len + 1) & ~1;
BFD_ASSERT (len <= sizeof (buf));
if (vms_lib_bread_raw (el, buf, len) != len)
return -1;
return FALSE;
/* Get info from mhd. */
mhd = (struct vms_mhd *)buf;
/* Check id. */
if (mhd->id != MHD__C_MHDID)
return FALSE;
if (len >= sizeof (struct vms_mhd))
el->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
el->mtime = vms_rawtime_to_time_t (mhd->datim);
@ -990,41 +1152,108 @@ vms_lib_bopen (bfd *el, file_ptr filepos)
return TRUE;
}
/* Standard function: get member at IDX. */
/* Get member MODIDX. Return NULL in case of error. */
bfd *
_bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex idx)
static bfd *
_bfd_vms_lib_get_module (bfd *abfd, unsigned int modidx)
{
struct lib_tdata *tdata = bfd_libdata (abfd);
bfd *res;
unsigned int i;
file_ptr file_off;
/* Linear-scan. */
for (i = 0; i < tdata->nbr_modules; i++)
{
if (tdata->modules[i].file_offset == (file_ptr)idx)
break;
}
/* Invalid index. */
if (i >= tdata->nbr_modules)
/* Sanity check. */
if (modidx >= tdata->nbr_modules)
return NULL;
/* Already loaded. */
if (tdata->cache[i])
return tdata->cache[i];
if (tdata->cache[modidx])
return tdata->cache[modidx];
/* Build it. */
res = _bfd_create_empty_archive_element_shell (abfd);
if (!vms_lib_bopen (res, idx))
return NULL;
res->filename = tdata->modules[i].name;
file_off = tdata->modules[modidx].file_offset;
if (tdata->type != LBR__C_TYP_IOBJ)
{
res = _bfd_create_empty_archive_element_shell (abfd);
if (res == NULL)
return NULL;
tdata->cache[i] = res;
/* Special reader to deal with data blocks. */
if (!vms_lib_bopen (res, file_off))
return NULL;
}
else
{
char buf[256];
struct vms_mhd *mhd;
struct areltdata *arelt;
/* Sanity check. The MHD must be big enough to contain module size. */
if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4)
return NULL;
/* Read the MHD now. */
if (bfd_seek (abfd, file_off, SEEK_SET) != 0)
return NULL;
if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size)
return NULL;
res = _bfd_create_empty_archive_element_shell (abfd);
if (res == NULL)
return NULL;
arelt = bfd_zalloc (res, sizeof (*arelt));
if (arelt == NULL)
return NULL;
res->arelt_data = arelt;
/* Get info from mhd. */
mhd = (struct vms_mhd *)buf;
if (mhd->id != MHD__C_MHDID)
return NULL;
if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1)
res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
res->mtime = vms_rawtime_to_time_t (mhd->datim);
res->mtime_set = TRUE;
arelt->parsed_size = bfd_getl32 (mhd->modsize);
/* No need for a special reader as members are stored linearly.
Just skip the MHD. */
res->origin = file_off + tdata->mhd_size;
}
res->filename = tdata->modules[modidx].name;
tdata->cache[modidx] = res;
return res;
}
/* Standard function: get member at IDX. */
bfd *
_bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex symidx)
{
struct lib_tdata *tdata = bfd_libdata (abfd);
file_ptr file_off;
unsigned int modidx;
/* Check symidx. */
if (symidx > tdata->artdata.symdef_count)
return NULL;
file_off = tdata->artdata.symdefs[symidx].file_offset;
/* Linear-scan. */
for (modidx = 0; modidx < tdata->nbr_modules; modidx++)
{
if (tdata->modules[modidx].file_offset == file_off)
break;
}
if (modidx >= tdata->nbr_modules)
return NULL;
return _bfd_vms_lib_get_module (abfd, modidx);
}
/* Elements of an imagelib are stubs. You can get the real image with this
function. */
@ -1086,8 +1315,7 @@ _bfd_vms_lib_openr_next_archived_file (bfd *archive,
return NULL;
}
res = _bfd_vms_lib_get_elt_at_index
(archive, bfd_libdata (archive)->modules[idx].file_offset);
res = _bfd_vms_lib_get_module (archive, idx);
if (res == NULL)
return res;
res->proxy_origin = idx;
@ -1099,25 +1327,36 @@ _bfd_vms_lib_openr_next_archived_file (bfd *archive,
int
_bfd_vms_lib_generic_stat_arch_elt (bfd *abfd, struct stat *st)
{
struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
struct lib_tdata *tdata;
/* Sanity check. */
if (abfd->my_archive == NULL)
{
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
if (vec->file_len == (ufile_ptr)-1)
tdata = bfd_libdata (abfd->my_archive);
if (tdata->type != LBR__C_TYP_IOBJ)
{
if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)
return -1;
struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
/* Compute length. */
while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)
;
if (vec->file_len == (ufile_ptr)-1)
{
if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)
return -1;
/* Compute length. */
while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)
;
}
st->st_size = vec->file_len;
}
else
{
st->st_size = ((struct areltdata *)abfd->arelt_data)->parsed_size;
}
st->st_size = vec->file_len;
if (abfd->mtime_set)
st->st_mtime = abfd->mtime;
else
@ -1213,7 +1452,7 @@ vms_write_index (bfd *abfd,
for (i = 0; i < nbr; i++, idx++)
{
unsigned int idxlen = get_idxlen (idx);
struct vms_idxdef *en;
struct vms_idx *en;
int flush = 0;
/* Check if a block might overflow. In this case we will flush this
@ -1249,13 +1488,12 @@ vms_write_index (bfd *abfd,
/* Update parent block: write the new entry. */
if (abfd != NULL)
{
en = (struct vms_idxdef *)(rblk[j]->keys + blk[j].len);
en = (struct vms_idx *)(rblk[j]->keys + blk[j].len);
memcpy (rblk[j + 1]->keys + blk[j + 1].len, en,
blk[j].lastlen);
en = (struct vms_idxdef *)
(rblk[j + 1]->keys + blk[j + 1].len);
bfd_putl32 (blk[j].vbn, en->vbn);
bfd_putl16 (RFADEF__C_INDEX, en->offset);
en = (struct vms_idx *)(rblk[j + 1]->keys + blk[j + 1].len);
bfd_putl32 (blk[j].vbn, en->rfa.vbn);
bfd_putl16 (RFADEF__C_INDEX, en->rfa.offset);
}
if (j + 1 == flush)
@ -1292,12 +1530,12 @@ vms_write_index (bfd *abfd,
if (abfd != NULL)
{
en = (struct vms_idxdef *)(rblk[j]->keys + blk[j].len);
en = (struct vms_idx *)(rblk[j]->keys + blk[j].len);
bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1,
en->vbn);
en->rfa.vbn);
bfd_putl16
((idx->abfd->proxy_origin % VMS_BLOCK_SIZE) + DATA__DATA,
en->offset);
en->rfa.offset);
en->keylen = idx->namlen;
memcpy (en->keyname, idx->name, idx->namlen);
}
@ -1319,14 +1557,14 @@ vms_write_index (bfd *abfd,
if (j > 0)
{
/* Update parent block: write the new entry. */
struct vms_idxdef *en;
struct vms_idxdef *par;
struct vms_idx *en;
struct vms_idx *par;
en = (struct vms_idxdef *)(rblk[j - 1]->keys + blk[j - 1].len);
par = (struct vms_idxdef *)(rblk[j]->keys + blk[j].len);
en = (struct vms_idx *)(rblk[j - 1]->keys + blk[j - 1].len);
par = (struct vms_idx *)(rblk[j]->keys + blk[j].len);
memcpy (par, en, blk[j - 1].lastlen);
bfd_putl32 (blk[j - 1].vbn, par->vbn);
bfd_putl16 (RFADEF__C_INDEX, par->offset);
bfd_putl32 (blk[j - 1].vbn, par->rfa.vbn);
bfd_putl16 (RFADEF__C_INDEX, par->rfa.offset);
}
/* Write this block on the disk. */

View File

@ -1,3 +1,20 @@
2010-04-30 Tristan Gingold <gingold@adacore.com>
* lbr.h (LBR__C_TYP_ISHSTB): Added.
(LHD_SANEID4): Renamed to ...
(LHD_SANEID6): ... this.
(LBR_MAJORID, LBR_ELFMAJORID): New macros.
(struct vms_rfa): New structure.
(struct vms_idxdef): Renamed to ...
(struct vms_idx): ... this.
(struct vms_idxdef2): Renamed to ...
(struct vms_elfidx): ... this.
(ELFIDX__WEAK, ELFIDX__GROUP, ELFIDX__LISTRFA, ELFIDX__SYMESC): New
macros.
(struct vms_lhs, struct vms_lns): New structures.
(struct vms_mhd): Add missing fields.
(MHD__C_MHDLEN): New macro.
2010-03-31 Tristan Gingold <gingold@adacore.com>
* dcx.h: New file.

View File

@ -25,9 +25,11 @@
/* Libray HeaDer. */
/* Magic numbers. Should match the major version. */
#define LHD_SANEID_DCX 319232342
#define LHD_SANEID3 233579905
#define LHD_SANEID4 233579911
#define LHD_SANEID6 233579911
/* Library type. */
#define LBR__C_TYP_UNK 0 /* Unknown / unspecified. */
@ -40,6 +42,7 @@
#define LBR__C_TYP_EOBJ 7 /* Alpha object. */
#define LBR__C_TYP_ESHSTB 8 /* Alpha shareable image. */
#define LBR__C_TYP_IOBJ 9 /* IA-64 object. */
#define LBR__C_TYP_ISHSTB 10 /* IA-64 shareable image. */
struct vms_lhd
{
@ -120,6 +123,10 @@ struct vms_lhd
unsigned char fill_4[4 * 13];
};
/* Known major ids. */
#define LBR_MAJORID 3 /* Alpha libraries. */
#define LBR_ELFMAJORID 6 /* Elf libraries (new index, new data). */
/* Offset of the first IDD. */
#define LHD_IDXDESC 196
@ -158,34 +165,80 @@ struct vms_indexdef
unsigned char parent[4];
unsigned char fill_1[6];
/* The key field contains vms_idxdef/vms_idxdef2 structures, which are
simply a key (= a string) and a rfa. */
unsigned char keys[INDEXDEF__BLKSIZ];
};
/* Index keys. */
struct vms_idxdef
{
unsigned char vbn[4];
unsigned char offset[2];
/* An offset in a file. */
unsigned char keylen;
unsigned char keyname[256];
struct vms_rfa
{
/* Logical block number, 1 based.
0 means that the field is absent. Block size is 512. */
unsigned char vbn[4];
/* Offset within the block. */
unsigned char offset[2];
};
struct vms_idxdef2
{
unsigned char vbn[4];
/* Index keys. For version 3. */
struct vms_idx
{
/* Offset from the start of the vbn, so minimum should be
DATA__DATA (ie 6). */
unsigned char offset[2];
struct vms_rfa rfa;
unsigned char keylen[2];
unsigned char fill_1;
unsigned char keylen;
/* The length of this field is in fact keylen. */
unsigned char keyname[256];
};
/* Index keys, for version 4 and later. */
struct vms_elfidx
{
struct vms_rfa rfa;
unsigned char keylen[2];
unsigned char flags;
unsigned char keyname[256];
};
/* Flags of elfidx. */
#define ELFIDX__WEAK 0x01 /* Weak symbol. */
#define ELFIDX__GROUP 0x02 /* Group symbol. */
#define ELFIDX__LISTRFA 0x04 /* RFA field points to an LHS. */
#define ELFIDX__SYMESC 0x08 /* Long symbol. */
#define RFADEF__C_INDEX 0xffff
/* List head structure. That's what is pointed by rfa when LISTRFA flag
is set in elfidx. */
struct vms_lhs
{
struct vms_rfa ng_g_rfa; /* Non-group global. */
struct vms_rfa ng_wk_rfa; /* Non-group weak. */
struct vms_rfa g_g_rfa; /* Group global. */
struct vms_rfa g_wk_rfa; /* Group weak. */
unsigned char flags;
};
/* List node structure. Fields of LHS point to this structure. */
struct vms_lns
{
/* Next node in the list. */
struct vms_rfa nxtrfa;
/* Module associated with the key. */
struct vms_rfa modrfa;
};
struct vms_datadef
{
/* Number of records in this block. */
@ -216,9 +269,15 @@ struct vms_mhd
/* Ident or GSMATCH. */
unsigned char objidlng;
unsigned char objid[31];
unsigned char pad1[3];
unsigned char otherefcnt[4];
unsigned char modsize[4];
unsigned char pad2[4];
};
#define MHD__C_MHDID 0xad /* Value for id. */
#define MHD__C_MHDLEN 16 /* Fixed part length. */
#define MHD__C_USRDAT 16
#define MHD__M_SELSRC 0x1
#define MHD__M_OBJTIR 0x2