From 13a985e120647fb8664baf7eeab498c1e367b54e Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 30 Apr 2010 12:44:51 +0000 Subject: [PATCH] bfd/ 2010-04-30 Tristan Gingold * vms-lib.c (vms_read_block): New function. (vms_traverse_index): Use vms_read_block. Handle long key names. include/vms/ 2010-04-30 Tristan Gingold * lbr.h (struct vms_kbn): New structure. --- bfd/ChangeLog | 5 +++ bfd/vms-lib.c | 81 +++++++++++++++++++++++++++++++++++++------ include/vms/ChangeLog | 4 +++ include/vms/lbr.h | 13 +++++++ 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a66fc32aefc..e3a1e53f7ac 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2010-04-30 Tristan Gingold + + * vms-lib.c (vms_read_block): New function. + (vms_traverse_index): Use vms_read_block. Handle long key names. + 2010-04-30 Tristan Gingold * vms-lib.c (struct lib_tdata): Field artdata added, fields nbr_syms diff --git a/bfd/vms-lib.c b/bfd/vms-lib.c index fcfdf0fd932..bd5ecb79a4c 100644 --- a/bfd/vms-lib.c +++ b/bfd/vms-lib.c @@ -186,6 +186,22 @@ vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name, } } +/* Read block VBN from ABFD and store it into BLK. */ + +static bfd_boolean +vms_read_block (bfd *abfd, unsigned int vbn, void *blk) +{ + file_ptr off; + + /* Read the index block. */ + off = (vbn - 1) * VMS_BLOCK_SIZE; + if (bfd_seek (abfd, off, SEEK_SET) != 0 + || bfd_bread (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE) + return FALSE; + + return TRUE; +} + /* Read index block VBN and put the entry in **IDX (which is updated). If the entry is indirect, recurse. */ @@ -198,9 +214,8 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) unsigned char *endp; /* Read the index block. */ - off = (vbn - 1) * VMS_BLOCK_SIZE; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || bfd_bread (&indexdef, sizeof (indexdef), abfd) != sizeof (indexdef)) + BFD_ASSERT (sizeof (indexdef) == VMS_BLOCK_SIZE); + if (!vms_read_block (abfd, vbn, &indexdef)) return FALSE; /* Traverse it. */ @@ -244,10 +259,6 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) if (idx_vbn == 0) return FALSE; - /* Long symbol names are not yet supported. */ - if (flags & ELFIDX__SYMESC) - return FALSE; - if (idx_off == RFADEF__C_INDEX) { /* Indirect entry. Recurse. */ @@ -259,10 +270,58 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) /* Add a new entry. */ char *name; - name = bfd_alloc (abfd, keylen + 1); - if (name == NULL) - return FALSE; - memcpy (name, keyname, keylen); + if (flags & ELFIDX__SYMESC) + { + /* Extended key name. */ + unsigned int noff = 0; + unsigned int koff; + unsigned int kvbn; + struct vms_kbn *kbn; + unsigned char kblk[VMS_BLOCK_SIZE]; + + /* Sanity check. */ + if (keylen != sizeof (struct vms_kbn)) + return FALSE; + + kbn = (struct vms_kbn *)keyname; + keylen = bfd_getl16 (kbn->keylen); + + name = bfd_alloc (abfd, keylen + 1); + if (name == NULL) + return FALSE; + kvbn = bfd_getl32 (kbn->rfa.vbn); + koff = bfd_getl16 (kbn->rfa.offset); + + /* Read the key, chunk by chunk. */ + do + { + unsigned int klen; + + if (!vms_read_block (abfd, kvbn, kblk)) + return FALSE; + kbn = (struct vms_kbn *)(kblk + koff); + klen = bfd_getl16 (kbn->keylen); + kvbn = bfd_getl32 (kbn->rfa.vbn); + koff = bfd_getl16 (kbn->rfa.offset); + + memcpy (name + noff, kbn + 1, klen); + noff += klen; + } + while (kvbn != 0); + + /* Sanity check. */ + if (noff != keylen) + return FALSE; + } + else + { + /* Usual key name. */ + name = bfd_alloc (abfd, keylen + 1); + if (name == NULL) + return FALSE; + + memcpy (name, keyname, keylen); + } name[keylen] = 0; if (flags & ELFIDX__LISTRFA) diff --git a/include/vms/ChangeLog b/include/vms/ChangeLog index b7114d3cf6e..823520f220b 100644 --- a/include/vms/ChangeLog +++ b/include/vms/ChangeLog @@ -1,3 +1,7 @@ +2010-04-30 Tristan Gingold + + * lbr.h (struct vms_kbn): New structure. + 2010-04-30 Tristan Gingold * lbr.h (LBR__C_TYP_ISHSTB): Added. diff --git a/include/vms/lbr.h b/include/vms/lbr.h index 7d6f597cb07..91186ee371f 100644 --- a/include/vms/lbr.h +++ b/include/vms/lbr.h @@ -255,6 +255,19 @@ struct vms_datadef #define DATA__LENGTH 512 #define DATA__DATA 6 +/* Key name block. This is used for keys longer than 128 bytes. */ + +struct vms_kbn +{ + /* Length of the key chunk. */ + unsigned char keylen[2]; + + /* RFA of the next chunk. */ + struct vms_rfa rfa; + + /* Followed by the key chunk. */ +}; + /* Module header. */ struct vms_mhd { -- 2.30.2