| OLD | NEW |
| 1 /* BFD back-end for VMS archive files. | 1 /* BFD back-end for VMS archive files. |
| 2 | 2 |
| 3 Copyright 2010, 2011 Free Software Foundation, Inc. | 3 Copyright 2010, 2011 Free Software Foundation, Inc. |
| 4 Written by Tristan Gingold <gingold@adacore.com>, AdaCore. | 4 Written by Tristan Gingold <gingold@adacore.com>, AdaCore. |
| 5 | 5 |
| 6 This file is part of BFD, the Binary File Descriptor library. | 6 This file is part of BFD, the Binary File Descriptor library. |
| 7 | 7 |
| 8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
| 9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
| 10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "vms.h" | 28 #include "vms.h" |
| 29 #include "vms/lbr.h" | 29 #include "vms/lbr.h" |
| 30 #include "vms/dcx.h" | 30 #include "vms/dcx.h" |
| 31 | 31 |
| 32 /* The standard VMS disk block size. */ | 32 /* The standard VMS disk block size. */ |
| 33 #ifndef VMS_BLOCK_SIZE | 33 #ifndef VMS_BLOCK_SIZE |
| 34 #define VMS_BLOCK_SIZE 512 | 34 #define VMS_BLOCK_SIZE 512 |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 /* Maximum key length (which is also the maximum symbol length in archive). */ | 37 /* Maximum key length (which is also the maximum symbol length in archive). */ |
| 38 #define MAX_KEYLEN 129 | 38 #define MAX_KEYLEN 128 |
| 39 #define MAX_EKEYLEN 1024 |
| 39 | 40 |
| 40 /* DCX Submaps. */ | 41 /* DCX Submaps. */ |
| 41 | 42 |
| 42 struct dcxsbm_desc | 43 struct dcxsbm_desc |
| 43 { | 44 { |
| 44 unsigned char min_char; | 45 unsigned char min_char; |
| 45 unsigned char max_char; | 46 unsigned char max_char; |
| 46 unsigned char *flags; | 47 unsigned char *flags; |
| 47 unsigned char *nodes; | 48 unsigned char *nodes; |
| 48 unsigned short *next; | 49 unsigned short *next; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 flags = ridx->flags; | 271 flags = ridx->flags; |
| 271 keyname = ridx->keyname; | 272 keyname = ridx->keyname; |
| 272 } | 273 } |
| 273 else | 274 else |
| 274 return FALSE; | 275 return FALSE; |
| 275 | 276 |
| 276 /* Illegal value. */ | 277 /* Illegal value. */ |
| 277 if (idx_vbn == 0) | 278 if (idx_vbn == 0) |
| 278 return FALSE; | 279 return FALSE; |
| 279 | 280 |
| 281 /* Point to the next index entry. */ |
| 282 p = keyname + keylen; |
| 283 |
| 280 if (idx_off == RFADEF__C_INDEX) | 284 if (idx_off == RFADEF__C_INDEX) |
| 281 { | 285 { |
| 282 /* Indirect entry. Recurse. */ | 286 /* Indirect entry. Recurse. */ |
| 283 if (!vms_traverse_index (abfd, idx_vbn, cs)) | 287 if (!vms_traverse_index (abfd, idx_vbn, cs)) |
| 284 return FALSE; | 288 return FALSE; |
| 285 } | 289 } |
| 286 else | 290 else |
| 287 { | 291 { |
| 288 /* Add a new entry. */ | 292 /* Add a new entry. */ |
| 289 char *name; | 293 char *name; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 return FALSE; | 365 return FALSE; |
| 362 if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa)) | 366 if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa)) |
| 363 return FALSE; | 367 return FALSE; |
| 364 } | 368 } |
| 365 else | 369 else |
| 366 { | 370 { |
| 367 if (!vms_add_index (cs, name, idx_vbn, idx_off)) | 371 if (!vms_add_index (cs, name, idx_vbn, idx_off)) |
| 368 return FALSE; | 372 return FALSE; |
| 369 } | 373 } |
| 370 } | 374 } |
| 371 | |
| 372 /* Point to the next index entry. */ | |
| 373 p = keyname + keylen; | |
| 374 } | 375 } |
| 375 | 376 |
| 376 return TRUE; | 377 return TRUE; |
| 377 } | 378 } |
| 378 | 379 |
| 379 /* Read index #IDX, which must have NBREL entries. */ | 380 /* Read index #IDX, which must have NBREL entries. */ |
| 380 | 381 |
| 381 static struct carsym * | 382 static struct carsym * |
| 382 vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel) | 383 vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel) |
| 383 { | 384 { |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 } | 1289 } |
| 1289 | 1290 |
| 1290 /* Get member MODIDX. Return NULL in case of error. */ | 1291 /* Get member MODIDX. Return NULL in case of error. */ |
| 1291 | 1292 |
| 1292 static bfd * | 1293 static bfd * |
| 1293 _bfd_vms_lib_get_module (bfd *abfd, unsigned int modidx) | 1294 _bfd_vms_lib_get_module (bfd *abfd, unsigned int modidx) |
| 1294 { | 1295 { |
| 1295 struct lib_tdata *tdata = bfd_libdata (abfd); | 1296 struct lib_tdata *tdata = bfd_libdata (abfd); |
| 1296 bfd *res; | 1297 bfd *res; |
| 1297 file_ptr file_off; | 1298 file_ptr file_off; |
| 1299 char *name; |
| 1298 | 1300 |
| 1299 /* Sanity check. */ | 1301 /* Sanity check. */ |
| 1300 if (modidx >= tdata->nbr_modules) | 1302 if (modidx >= tdata->nbr_modules) |
| 1301 return NULL; | 1303 return NULL; |
| 1302 | 1304 |
| 1303 /* Already loaded. */ | 1305 /* Already loaded. */ |
| 1304 if (tdata->cache[modidx]) | 1306 if (tdata->cache[modidx]) |
| 1305 return tdata->cache[modidx]; | 1307 return tdata->cache[modidx]; |
| 1306 | 1308 |
| 1307 /* Build it. */ | 1309 /* Build it. */ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 res->mtime = vms_rawtime_to_time_t (mhd->datim); | 1351 res->mtime = vms_rawtime_to_time_t (mhd->datim); |
| 1350 res->mtime_set = TRUE; | 1352 res->mtime_set = TRUE; |
| 1351 | 1353 |
| 1352 arelt->parsed_size = bfd_getl32 (mhd->modsize); | 1354 arelt->parsed_size = bfd_getl32 (mhd->modsize); |
| 1353 | 1355 |
| 1354 /* No need for a special reader as members are stored linearly. | 1356 /* No need for a special reader as members are stored linearly. |
| 1355 Just skip the MHD. */ | 1357 Just skip the MHD. */ |
| 1356 res->origin = file_off + tdata->mhd_size; | 1358 res->origin = file_off + tdata->mhd_size; |
| 1357 } | 1359 } |
| 1358 | 1360 |
| 1359 res->filename = tdata->modules[modidx].name; | 1361 /* Set filename. */ |
| 1362 name = tdata->modules[modidx].name; |
| 1363 switch (tdata->type) |
| 1364 { |
| 1365 case LBR__C_TYP_IOBJ: |
| 1366 case LBR__C_TYP_EOBJ: |
| 1367 /* For object archives, append .obj to mimic standard behaviour. */ |
| 1368 { |
| 1369 » size_t namelen = strlen (name); |
| 1370 » char *name1 = bfd_alloc (res, namelen + 4 + 1); |
| 1371 » memcpy (name1, name, namelen); |
| 1372 » strcpy (name1 + namelen, ".obj"); |
| 1373 » name = name1; |
| 1374 } |
| 1375 break; |
| 1376 default: |
| 1377 break; |
| 1378 } |
| 1379 res->filename = name; |
| 1360 | 1380 |
| 1361 tdata->cache[modidx] = res; | 1381 tdata->cache[modidx] = res; |
| 1362 | 1382 |
| 1363 return res; | 1383 return res; |
| 1364 } | 1384 } |
| 1365 | 1385 |
| 1366 /* Standard function: get member at IDX. */ | 1386 /* Standard function: get member at IDX. */ |
| 1367 | 1387 |
| 1368 bfd * | 1388 bfd * |
| 1369 _bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex symidx) | 1389 _bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex symidx) |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 Can be called with ABFD set to NULL just to size the index. | 1580 Can be called with ABFD set to NULL just to size the index. |
| 1561 If not null, TOPVBN will be assigned to the vbn of the root index tree. | 1581 If not null, TOPVBN will be assigned to the vbn of the root index tree. |
| 1562 IS_ELFIDX is true for elfidx (ie ia64) indexes layout. | 1582 IS_ELFIDX is true for elfidx (ie ia64) indexes layout. |
| 1563 Return TRUE on success. */ | 1583 Return TRUE on success. */ |
| 1564 | 1584 |
| 1565 static bfd_boolean | 1585 static bfd_boolean |
| 1566 vms_write_index (bfd *abfd, | 1586 vms_write_index (bfd *abfd, |
| 1567 struct lib_index *idx, unsigned int nbr, unsigned int *vbn, | 1587 struct lib_index *idx, unsigned int nbr, unsigned int *vbn, |
| 1568 unsigned int *topvbn, bfd_boolean is_elfidx) | 1588 unsigned int *topvbn, bfd_boolean is_elfidx) |
| 1569 { | 1589 { |
| 1590 /* The index is organized as a tree. This function implements a naive |
| 1591 algorithm to balance the tree: it fills the leaves, and create a new |
| 1592 branch when all upper leaves and branches are full. We only keep in |
| 1593 memory a path to the current leaf. */ |
| 1570 unsigned int i; | 1594 unsigned int i; |
| 1571 int j; | 1595 int j; |
| 1572 int level; | 1596 int level; |
| 1597 /* Disk blocks for the current path. */ |
| 1573 struct vms_indexdef *rblk[MAX_LEVEL]; | 1598 struct vms_indexdef *rblk[MAX_LEVEL]; |
| 1599 /* Info on the current blocks. */ |
| 1574 struct idxblk | 1600 struct idxblk |
| 1575 { | 1601 { |
| 1576 unsigned int vbn; | 1602 unsigned int vbn;» » /* VBN of the block. */ |
| 1577 unsigned short len; | 1603 /* The last entry is identified so that it could be copied to the |
| 1578 unsigned short lastlen; | 1604 parent block. */ |
| 1605 unsigned short len;»» /* Length up to the last entry. */ |
| 1606 unsigned short lastlen;» /* Length of the last entry. */ |
| 1579 } blk[MAX_LEVEL]; | 1607 } blk[MAX_LEVEL]; |
| 1580 | 1608 |
| 1581 /* The kbn blocks are used to store long symbol names. */ | 1609 /* The kbn blocks are used to store long symbol names. */ |
| 1582 unsigned int kbn_sz = 0; /* Number of bytes available in the kbn block. */ | 1610 unsigned int kbn_sz = 0; /* Number of bytes available in the kbn block. */ |
| 1583 unsigned int kbn_vbn = 0; /* VBN of the kbn block. */ | 1611 unsigned int kbn_vbn = 0; /* VBN of the kbn block. */ |
| 1584 unsigned char *kbn_blk = NULL; /* Contents of the kbn block. */ | 1612 unsigned char *kbn_blk = NULL; /* Contents of the kbn block. */ |
| 1585 | 1613 |
| 1586 if (nbr == 0) | 1614 if (nbr == 0) |
| 1587 { | 1615 { |
| 1588 /* No entries. Very easy to handle. */ | 1616 /* No entries. Very easy to handle. */ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1607 | 1635 |
| 1608 for (i = 0; i < nbr; i++, idx++) | 1636 for (i = 0; i < nbr; i++, idx++) |
| 1609 { | 1637 { |
| 1610 unsigned int idxlen; | 1638 unsigned int idxlen; |
| 1611 int flush = 0; | 1639 int flush = 0; |
| 1612 unsigned int key_vbn = 0; | 1640 unsigned int key_vbn = 0; |
| 1613 unsigned int key_off = 0; | 1641 unsigned int key_off = 0; |
| 1614 | 1642 |
| 1615 idxlen = get_idxlen (idx, is_elfidx); | 1643 idxlen = get_idxlen (idx, is_elfidx); |
| 1616 | 1644 |
| 1617 if (is_elfidx && idx->namlen >= MAX_KEYLEN) | 1645 if (is_elfidx && idx->namlen > MAX_KEYLEN) |
| 1618 { | 1646 { |
| 1619 /* If the key (ie name) is too long, write it in the kbn block. */ | 1647 /* If the key (ie name) is too long, write it in the kbn block. */ |
| 1620 unsigned int kl = idx->namlen; | 1648 unsigned int kl = idx->namlen; |
| 1621 unsigned int kl_chunk; | 1649 unsigned int kl_chunk; |
| 1622 const char *key = idx->name; | 1650 const char *key = idx->name; |
| 1623 | 1651 |
| 1624 /* Write the key in the kbn, chunk after chunk. */ | 1652 /* Write the key in the kbn, chunk after chunk. */ |
| 1625 do | 1653 do |
| 1626 { | 1654 { |
| 1627 if (kbn_sz < sizeof (struct vms_kbn)) | 1655 if (kbn_sz < sizeof (struct vms_kbn)) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */ | 1714 kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */ |
| 1687 kbn_sz -= kl_chunk + sizeof (struct vms_kbn); | 1715 kbn_sz -= kl_chunk + sizeof (struct vms_kbn); |
| 1688 } | 1716 } |
| 1689 while (kl > 0); | 1717 while (kl > 0); |
| 1690 } | 1718 } |
| 1691 | 1719 |
| 1692 /* Check if a block might overflow. In this case we will flush this | 1720 /* Check if a block might overflow. In this case we will flush this |
| 1693 block and all the blocks below it. */ | 1721 block and all the blocks below it. */ |
| 1694 for (j = 0; j < level; j++) | 1722 for (j = 0; j < level; j++) |
| 1695 if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ) | 1723 if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ) |
| 1696 flush = j + 1; | 1724 » flush = j + 1; |
| 1697 | 1725 |
| 1698 for (j = 0; j < level; j++) | 1726 for (j = 0; j < level; j++) |
| 1699 { | 1727 { |
| 1700 if (j < flush) | 1728 if (j < flush) |
| 1701 { | 1729 { |
| 1702 /* There is not enough room to write the new entry in this | 1730 /* There is not enough room to write the new entry in this |
| 1703 block or in a parent block. */ | 1731 block or in a parent block. */ |
| 1704 | 1732 |
| 1705 if (j + 1 == level) | 1733 if (j + 1 == level) |
| 1706 { | 1734 { |
| 1707 BFD_ASSERT (level < MAX_LEVEL); | 1735 BFD_ASSERT (level < MAX_LEVEL); |
| 1708 | 1736 |
| 1709 /* Need to create a parent. */ | 1737 /* Need to create a parent. */ |
| 1710 if (abfd != NULL) | 1738 if (abfd != NULL) |
| 1711 { | 1739 { |
| 1712 rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef)); | 1740 rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef)); |
| 1713 bfd_putl32 (*vbn, rblk[j]->parent); | 1741 bfd_putl32 (*vbn, rblk[j]->parent); |
| 1714 } | 1742 } |
| 1715 blk[level].vbn = (*vbn)++; | 1743 blk[level].vbn = (*vbn)++; |
| 1716 blk[level].len = 0; | 1744 blk[level].len = 0; |
| 1717 blk[level].lastlen = 0; | 1745 blk[level].lastlen = blk[j].lastlen; |
| 1718 | 1746 |
| 1719 level++; | 1747 level++; |
| 1720 } | 1748 } |
| 1721 | 1749 |
| 1722 /* Update parent block: write the new entry. */ | 1750 /* Update parent block: write the last entry from the current |
| 1751 » » block. */ |
| 1723 if (abfd != NULL) | 1752 if (abfd != NULL) |
| 1724 { | 1753 { |
| 1725 struct vms_rfa *rfa; | 1754 struct vms_rfa *rfa; |
| 1726 | 1755 |
| 1756 /* Pointer to the last entry in parent block. */ |
| 1757 rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len); |
| 1758 |
| 1727 /* Copy the whole entry. */ | 1759 /* Copy the whole entry. */ |
| 1728 memcpy (rblk[j + 1]->keys + blk[j + 1].len, | 1760 » » BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen); |
| 1729 rblk[j]->keys + blk[j].len, | 1761 memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen); |
| 1730 blk[j].lastlen); | |
| 1731 /* Fix the entry (which in always the first field of an | 1762 /* Fix the entry (which in always the first field of an |
| 1732 entry. */ | 1763 entry. */ |
| 1733 rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len); | |
| 1734 bfd_putl32 (blk[j].vbn, rfa->vbn); | 1764 bfd_putl32 (blk[j].vbn, rfa->vbn); |
| 1735 bfd_putl16 (RFADEF__C_INDEX, rfa->offset); | 1765 bfd_putl16 (RFADEF__C_INDEX, rfa->offset); |
| 1736 } | 1766 } |
| 1737 | 1767 |
| 1738 if (j + 1 == flush) | 1768 if (j + 1 == flush) |
| 1739 { | 1769 { |
| 1740 /* And allocate it. Do it only on the block that won't be | 1770 /* And allocate it. Do it only on the block that won't be |
| 1741 flushed (so that the parent of the parent can be | 1771 flushed (so that the parent of the parent can be |
| 1742 updated too). */ | 1772 updated too). */ |
| 1743 blk[j + 1].len += blk[j].lastlen; | 1773 blk[j + 1].len += blk[j + 1].lastlen; |
| 1744 blk[j + 1].lastlen = 0; | 1774 blk[j + 1].lastlen = 0; |
| 1745 } | 1775 } |
| 1746 | 1776 |
| 1747 /* Write this block on the disk. */ | 1777 /* Write this block on the disk. */ |
| 1748 if (abfd != NULL) | 1778 if (abfd != NULL) |
| 1749 { | 1779 { |
| 1750 bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); | 1780 bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
| 1751 if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) | 1781 if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) |
| 1752 return FALSE; | 1782 return FALSE; |
| 1753 } | 1783 } |
| 1754 | 1784 |
| 1755 /* Reset this block. */ | 1785 /* Reset this block. */ |
| 1756 blk[j].len = 0; | 1786 blk[j].len = 0; |
| 1757 blk[j].lastlen = 0; | 1787 blk[j].lastlen = 0; |
| 1758 blk[j].vbn = (*vbn)++; | 1788 blk[j].vbn = (*vbn)++; |
| 1759 } | 1789 } |
| 1760 | 1790 |
| 1761 /* Append it to the block. */ | 1791 /* Append it to the block. */ |
| 1762 if (j == 0) | 1792 if (j == 0) |
| 1763 { | 1793 { |
| 1794 /* Keep the previous last entry. */ |
| 1764 blk[j].len += blk[j].lastlen; | 1795 blk[j].len += blk[j].lastlen; |
| 1765 | 1796 |
| 1766 if (abfd != NULL) | 1797 if (abfd != NULL) |
| 1767 { | 1798 { |
| 1768 struct vms_rfa *rfa; | 1799 struct vms_rfa *rfa; |
| 1769 | 1800 |
| 1770 rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len); | 1801 rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len); |
| 1771 bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1, | 1802 bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1, |
| 1772 rfa->vbn); | 1803 rfa->vbn); |
| 1773 bfd_putl16 | 1804 bfd_putl16 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1798 } | 1829 } |
| 1799 } | 1830 } |
| 1800 else | 1831 else |
| 1801 { | 1832 { |
| 1802 /* Use idx format. */ | 1833 /* Use idx format. */ |
| 1803 struct vms_idx *en = (struct vms_idx *)rfa; | 1834 struct vms_idx *en = (struct vms_idx *)rfa; |
| 1804 en->keylen = idx->namlen; | 1835 en->keylen = idx->namlen; |
| 1805 memcpy (en->keyname, idx->name, idx->namlen); | 1836 memcpy (en->keyname, idx->name, idx->namlen); |
| 1806 } | 1837 } |
| 1807 } | 1838 } |
| 1808 } | 1839 » } |
| 1809 | 1840 » /* The last added key can now be the last one all blocks in the |
| 1810 blk[j].lastlen = idxlen; | 1841 » path. */ |
| 1842 » blk[j].lastlen = idxlen; |
| 1811 } | 1843 } |
| 1812 } | 1844 } |
| 1813 | 1845 |
| 1846 /* Save VBN of the root. */ |
| 1814 if (topvbn != NULL) | 1847 if (topvbn != NULL) |
| 1815 *topvbn = blk[level - 1].vbn; | 1848 *topvbn = blk[level - 1].vbn; |
| 1816 | 1849 |
| 1817 if (abfd == NULL) | 1850 if (abfd == NULL) |
| 1818 return TRUE; | 1851 return TRUE; |
| 1819 | 1852 |
| 1820 /* Flush. */ | 1853 /* Flush. */ |
| 1821 for (j = 1; j < level; j++) | 1854 for (j = 1; j < level; j++) |
| 1822 { | 1855 { |
| 1823 /* Update parent block: write the new entry. */ | 1856 /* Update parent block: write the new entry. */ |
| 1824 unsigned char *en; | 1857 unsigned char *en; |
| 1825 unsigned char *par; | 1858 unsigned char *par; |
| 1826 struct vms_rfa *rfa; | 1859 struct vms_rfa *rfa; |
| 1827 | 1860 |
| 1828 en = rblk[j - 1]->keys + blk[j - 1].len; | 1861 en = rblk[j - 1]->keys + blk[j - 1].len; |
| 1829 par = rblk[j]->keys + blk[j].len; | 1862 par = rblk[j]->keys + blk[j].len; |
| 1863 BFD_ASSERT (blk[j].lastlen == blk[j - 1].lastlen); |
| 1830 memcpy (par, en, blk[j - 1].lastlen); | 1864 memcpy (par, en, blk[j - 1].lastlen); |
| 1831 rfa = (struct vms_rfa *)par; | 1865 rfa = (struct vms_rfa *)par; |
| 1832 bfd_putl32 (blk[j - 1].vbn, rfa->vbn); | 1866 bfd_putl32 (blk[j - 1].vbn, rfa->vbn); |
| 1833 bfd_putl16 (RFADEF__C_INDEX, rfa->offset); | 1867 bfd_putl16 (RFADEF__C_INDEX, rfa->offset); |
| 1834 } | 1868 } |
| 1835 | 1869 |
| 1836 for (j = 0; j < level; j++) | 1870 for (j = 0; j < level; j++) |
| 1837 { | 1871 { |
| 1838 /* Write this block on the disk. */ | 1872 /* Write this block on the disk. */ |
| 1839 bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); | 1873 bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used); |
| 1840 if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) | 1874 if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE) |
| 1841 return FALSE; | 1875 return FALSE; |
| 1842 | 1876 |
| 1843 free (rblk[j]); | 1877 free (rblk[j]); |
| 1844 } | 1878 } |
| 1845 | 1879 |
| 1846 /* Write the last kbn (if any). */ | 1880 /* Write the last kbn (if any). */ |
| 1847 if (kbn_vbn != 0) | 1881 if (kbn_vbn != 0) |
| 1848 { | 1882 { |
| 1849 if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE) | 1883 if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE) |
| 1850 return FALSE; | 1884 return FALSE; |
| 1885 free (kbn_blk); |
| 1851 } | 1886 } |
| 1852 | 1887 |
| 1853 return TRUE; | 1888 return TRUE; |
| 1854 } | 1889 } |
| 1855 | 1890 |
| 1856 /* Append data to the data block DATA. Force write if PAD is true. */ | 1891 /* Append data to the data block DATA. Force write if PAD is true. */ |
| 1857 | 1892 |
| 1858 static bfd_boolean | 1893 static bfd_boolean |
| 1859 vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off, | 1894 vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off, |
| 1860 const unsigned char *buf, unsigned int len, int pad) | 1895 const unsigned char *buf, unsigned int len, int pad) |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 struct lib_index *symbols; | 2034 struct lib_index *symbols; |
| 2000 struct lib_tdata *tdata = bfd_libdata (arch); | 2035 struct lib_tdata *tdata = bfd_libdata (arch); |
| 2001 unsigned int i; | 2036 unsigned int i; |
| 2002 file_ptr off; | 2037 file_ptr off; |
| 2003 unsigned int nbr_mod_iblk; | 2038 unsigned int nbr_mod_iblk; |
| 2004 unsigned int nbr_sym_iblk; | 2039 unsigned int nbr_sym_iblk; |
| 2005 unsigned int vbn; | 2040 unsigned int vbn; |
| 2006 unsigned int mod_idx_vbn; | 2041 unsigned int mod_idx_vbn; |
| 2007 unsigned int sym_idx_vbn; | 2042 unsigned int sym_idx_vbn; |
| 2008 bfd_boolean is_elfidx = tdata->kind == vms_lib_ia64; | 2043 bfd_boolean is_elfidx = tdata->kind == vms_lib_ia64; |
| 2044 unsigned int max_keylen = is_elfidx ? MAX_EKEYLEN : MAX_KEYLEN; |
| 2009 | 2045 |
| 2010 /* Count the number of modules (and do a first sanity check). */ | 2046 /* Count the number of modules (and do a first sanity check). */ |
| 2011 nbr_modules = 0; | 2047 nbr_modules = 0; |
| 2012 for (current = arch->archive_head; | 2048 for (current = arch->archive_head; |
| 2013 current != NULL; | 2049 current != NULL; |
| 2014 current = current->archive_next) | 2050 current = current->archive_next) |
| 2015 { | 2051 { |
| 2016 /* This check is checking the bfds for the objects we're reading | 2052 /* This check is checking the bfds for the objects we're reading |
| 2017 from (which are usually either an object file or archive on | 2053 from (which are usually either an object file or archive on |
| 2018 disk), not the archive entries we're writing to. We don't | 2054 disk), not the archive entries we're writing to. We don't |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2030 /* Build the modules list. */ | 2066 /* Build the modules list. */ |
| 2031 BFD_ASSERT (tdata->modules == NULL); | 2067 BFD_ASSERT (tdata->modules == NULL); |
| 2032 modules = bfd_alloc (arch, nbr_modules * sizeof (struct lib_index)); | 2068 modules = bfd_alloc (arch, nbr_modules * sizeof (struct lib_index)); |
| 2033 if (modules == NULL) | 2069 if (modules == NULL) |
| 2034 return FALSE; | 2070 return FALSE; |
| 2035 | 2071 |
| 2036 for (current = arch->archive_head, i = 0; | 2072 for (current = arch->archive_head, i = 0; |
| 2037 current != NULL; | 2073 current != NULL; |
| 2038 current = current->archive_next, i++) | 2074 current = current->archive_next, i++) |
| 2039 { | 2075 { |
| 2040 int nl; | 2076 unsigned int nl; |
| 2041 | 2077 |
| 2042 modules[i].abfd = current; | 2078 modules[i].abfd = current; |
| 2043 modules[i].name = vms_get_module_name (current->filename, FALSE); | 2079 modules[i].name = vms_get_module_name (current->filename, FALSE); |
| 2044 modules[i].ref = 1; | 2080 modules[i].ref = 1; |
| 2045 | 2081 |
| 2046 /* FIXME: silently truncate long names ? */ | 2082 /* FIXME: silently truncate long names ? */ |
| 2047 nl = strlen (modules[i].name); | 2083 nl = strlen (modules[i].name); |
| 2048 modules[i].namlen = (nl > MAX_KEYLEN ? MAX_KEYLEN : nl); | 2084 modules[i].namlen = (nl > max_keylen ? max_keylen : nl); |
| 2049 } | 2085 } |
| 2050 | 2086 |
| 2051 /* Create the module index. */ | 2087 /* Create the module index. */ |
| 2052 vbn = 0; | 2088 vbn = 0; |
| 2053 if (!vms_write_index (NULL, modules, nbr_modules, &vbn, NULL, is_elfidx)) | 2089 if (!vms_write_index (NULL, modules, nbr_modules, &vbn, NULL, is_elfidx)) |
| 2054 return FALSE; | 2090 return FALSE; |
| 2055 nbr_mod_iblk = vbn; | 2091 nbr_mod_iblk = vbn; |
| 2056 | 2092 |
| 2057 /* Create symbol index. */ | 2093 /* Create symbol index. */ |
| 2058 if (!_bfd_vms_lib_build_map (nbr_modules, modules, &nbr_symbols, &symbols)) | 2094 if (!_bfd_vms_lib_build_map (nbr_modules, modules, &nbr_symbols, &symbols)) |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 bfd_putl32 (tdata->credat_lo, lhd->credat + 0); | 2265 bfd_putl32 (tdata->credat_lo, lhd->credat + 0); |
| 2230 bfd_putl32 (tdata->credat_hi, lhd->credat + 4); | 2266 bfd_putl32 (tdata->credat_hi, lhd->credat + 4); |
| 2231 vms_raw_get_time (lhd->updtim); | 2267 vms_raw_get_time (lhd->updtim); |
| 2232 | 2268 |
| 2233 lhd->mhdusz = tdata->mhd_size - MHD__C_USRDAT; | 2269 lhd->mhdusz = tdata->mhd_size - MHD__C_USRDAT; |
| 2234 | 2270 |
| 2235 bfd_putl32 (nbr_modules + nbr_symbols, lhd->idxcnt); | 2271 bfd_putl32 (nbr_modules + nbr_symbols, lhd->idxcnt); |
| 2236 bfd_putl32 (nbr_modules, lhd->modcnt); | 2272 bfd_putl32 (nbr_modules, lhd->modcnt); |
| 2237 bfd_putl32 (nbr_modules, lhd->modhdrs); | 2273 bfd_putl32 (nbr_modules, lhd->modhdrs); |
| 2238 | 2274 |
| 2275 /* Number of blocks for index. */ |
| 2276 bfd_putl32 (nbr_mod_iblk + nbr_sym_iblk, lhd->idxblks); |
| 2239 bfd_putl32 (vbn - 1, lhd->hipreal); | 2277 bfd_putl32 (vbn - 1, lhd->hipreal); |
| 2240 bfd_putl32 (vbn - 1, lhd->hiprusd); | 2278 bfd_putl32 (vbn - 1, lhd->hiprusd); |
| 2241 | 2279 |
| 2280 /* VBN of the next free block. */ |
| 2281 bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextvbn); |
| 2282 bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextrfa + 0); |
| 2283 bfd_putl16 (0, lhd->nextrfa + 4); |
| 2284 |
| 2242 /* First index (modules name). */ | 2285 /* First index (modules name). */ |
| 2243 idd_flags = IDD__FLAGS_ASCII | IDD__FLAGS_VARLENIDX | 2286 idd_flags = IDD__FLAGS_ASCII | IDD__FLAGS_VARLENIDX |
| 2244 | IDD__FLAGS_NOCASECMP | IDD__FLAGS_NOCASENTR; | 2287 | IDD__FLAGS_NOCASECMP | IDD__FLAGS_NOCASENTR; |
| 2245 bfd_putl16 (idd_flags, idd->flags); | 2288 bfd_putl16 (idd_flags, idd->flags); |
| 2246 bfd_putl16 (MAX_KEYLEN, idd->keylen); | 2289 bfd_putl16 (max_keylen + 1, idd->keylen); |
| 2247 bfd_putl16 (mod_idx_vbn, idd->vbn); | 2290 bfd_putl16 (mod_idx_vbn, idd->vbn); |
| 2248 idd++; | 2291 idd++; |
| 2249 | 2292 |
| 2250 /* Second index (symbols name). */ | 2293 /* Second index (symbols name). */ |
| 2251 bfd_putl16 (idd_flags, idd->flags); | 2294 bfd_putl16 (idd_flags, idd->flags); |
| 2252 bfd_putl16 (MAX_KEYLEN, idd->keylen); | 2295 bfd_putl16 (max_keylen + 1, idd->keylen); |
| 2253 bfd_putl16 (sym_idx_vbn, idd->vbn); | 2296 bfd_putl16 (sym_idx_vbn, idd->vbn); |
| 2254 idd++; | 2297 idd++; |
| 2255 | 2298 |
| 2256 if (vms_write_block (arch, 1, blk) != TRUE) | 2299 if (vms_write_block (arch, 1, blk) != TRUE) |
| 2257 return FALSE; | 2300 return FALSE; |
| 2258 } | 2301 } |
| 2259 | 2302 |
| 2260 return TRUE; | 2303 return TRUE; |
| 2261 | 2304 |
| 2262 input_err: | 2305 input_err: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2296 BFD_JUMP_TABLE_CORE (_bfd_nocore), | 2339 BFD_JUMP_TABLE_CORE (_bfd_nocore), |
| 2297 BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib), | 2340 BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib), |
| 2298 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), | 2341 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), |
| 2299 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), | 2342 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), |
| 2300 BFD_JUMP_TABLE_WRITE (_bfd_nowrite), | 2343 BFD_JUMP_TABLE_WRITE (_bfd_nowrite), |
| 2301 BFD_JUMP_TABLE_LINK (_bfd_nolink), | 2344 BFD_JUMP_TABLE_LINK (_bfd_nolink), |
| 2302 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), | 2345 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), |
| 2303 | 2346 |
| 2304 NULL, | 2347 NULL, |
| 2305 | 2348 |
| 2306 (PTR) 0 | 2349 NULL |
| 2307 }; | 2350 }; |
| OLD | NEW |