(root)/
binutils-2.41/
bfd/
pdb.c
       1  /* BFD back-end for PDB Multi-Stream Format archives.
       2     Copyright (C) 2022-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of BFD, the Binary File Descriptor library.
       5  
       6     This program is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3 of the License, or
       9     (at your option) any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program; if not, write to the Free Software
      18     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      19     MA 02110-1301, USA.  */
      20  
      21  /* This describes the MSF file archive format, which is used for the
      22     PDB debug info generated by MSVC. See https://llvm.org/docs/PDB/MsfFile.html
      23     for a full description of the format.  */
      24  
      25  #include "sysdep.h"
      26  #include "bfd.h"
      27  #include "libbfd.h"
      28  
      29  /* "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0\0" */
      30  static const uint8_t pdb_magic[] =
      31  { 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
      32    0x74, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, 0x20,
      33    0x4d, 0x53, 0x46, 0x20, 0x37, 0x2e, 0x30, 0x30,
      34    0x0d, 0x0a, 0x1a, 0x44, 0x53, 0x00, 0x00, 0x00 };
      35  
      36  #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
      37  
      38  static bfd_cleanup
      39  pdb_archive_p (bfd *abfd)
      40  {
      41    int ret;
      42    char magic[sizeof (pdb_magic)];
      43  
      44    ret = bfd_bread (magic, sizeof (magic), abfd);
      45    if (ret != sizeof (magic))
      46      {
      47        bfd_set_error (bfd_error_wrong_format);
      48        return NULL;
      49      }
      50  
      51    if (memcmp (magic, pdb_magic, sizeof (magic)))
      52      {
      53        bfd_set_error (bfd_error_wrong_format);
      54        return NULL;
      55      }
      56  
      57    void *tdata = bfd_zalloc (abfd, sizeof (struct artdata));
      58    if (tdata == NULL)
      59      return NULL;
      60    bfd_ardata (abfd) = tdata;
      61  
      62    return _bfd_no_cleanup;
      63  }
      64  
      65  static bfd *
      66  pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
      67  {
      68    char int_buf[sizeof (uint32_t)];
      69    uint32_t block_size, block_map_addr, block, num_files;
      70    uint32_t first_dir_block, dir_offset, file_size, block_off, left;
      71    char name[10];
      72    bfd *file;
      73    char *buf;
      74  
      75    /* Get block_size.  */
      76  
      77    if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
      78      return NULL;
      79  
      80    if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
      81      {
      82        bfd_set_error (bfd_error_malformed_archive);
      83        return NULL;
      84      }
      85  
      86    block_size = bfd_getl32 (int_buf);
      87    if ((block_size & -block_size) != block_size
      88        || block_size < 512
      89        || block_size > 4096)
      90      {
      91        bfd_set_error (bfd_error_malformed_archive);
      92        return NULL;
      93      }
      94  
      95    /* Get block_map_addr.  */
      96  
      97    if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
      98      return NULL;
      99  
     100    if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     101      {
     102        bfd_set_error (bfd_error_malformed_archive);
     103        return NULL;
     104      }
     105  
     106    block_map_addr = bfd_getl32 (int_buf);
     107  
     108    /* Get num_files.  */
     109  
     110    if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
     111      return NULL;
     112  
     113    if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     114      {
     115        bfd_set_error (bfd_error_malformed_archive);
     116        return NULL;
     117      }
     118  
     119    first_dir_block = bfd_getl32 (int_buf);
     120  
     121    if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
     122      return NULL;
     123  
     124    if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     125      {
     126        bfd_set_error (bfd_error_malformed_archive);
     127        return NULL;
     128      }
     129  
     130    num_files = bfd_getl32 (int_buf);
     131  
     132    if (sym_index >= num_files)
     133      {
     134        bfd_set_error (bfd_error_no_more_archived_files);
     135        return NULL;
     136      }
     137  
     138    /* Read file size.  */
     139  
     140    dir_offset = sizeof (uint32_t) * (sym_index + 1);
     141  
     142    if (dir_offset >= block_size)
     143      {
     144        uint32_t block_map_addr_off;
     145  
     146        block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
     147  
     148        if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
     149  		    SEEK_SET))
     150  	return NULL;
     151  
     152        if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     153  	{
     154  	  bfd_set_error (bfd_error_malformed_archive);
     155  	  return NULL;
     156  	}
     157  
     158        block = bfd_getl32 (int_buf);
     159      }
     160    else
     161      {
     162        block = first_dir_block;
     163      }
     164  
     165    if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
     166  		SEEK_SET))
     167      return NULL;
     168  
     169    if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     170      {
     171        bfd_set_error (bfd_error_malformed_archive);
     172        return NULL;
     173      }
     174  
     175    file_size = bfd_getl32 (int_buf);
     176  
     177    /* Undocumented? Seen on PDBs created by MSVC 2022.  */
     178    if (file_size == 0xffffffff)
     179      file_size = 0;
     180  
     181    /* Create BFD. */
     182  
     183    /* Four hex digits is enough - even though MSF allows for 32 bits, the
     184       PDB format itself only uses 16 bits for stream numbers.  */
     185    sprintf (name, "%04lx", sym_index);
     186  
     187    file = bfd_create (name, abfd);
     188  
     189    if (!file)
     190      return NULL;
     191  
     192    if (!bfd_make_writable (file))
     193      goto fail;
     194  
     195    file->arelt_data =
     196      (struct areltdata *) bfd_zmalloc (sizeof (struct areltdata));
     197  
     198    if (!file->arelt_data)
     199      goto fail;
     200  
     201    arch_eltdata (file)->parsed_size = file_size;
     202    arch_eltdata (file)->key = sym_index;
     203  
     204    if (file_size == 0)
     205      return file;
     206  
     207    block_off = 0;
     208  
     209    /* Sum number of blocks in previous files.  */
     210  
     211    if (sym_index != 0)
     212      {
     213        dir_offset = sizeof (uint32_t);
     214  
     215        if (bfd_seek (abfd, (first_dir_block * block_size) + sizeof (uint32_t),
     216  		    SEEK_SET))
     217  	goto fail;
     218  
     219        for (symindex i = 0; i < sym_index; i++)
     220  	{
     221  	  uint32_t size, num_blocks;
     222  
     223  	  if ((dir_offset % block_size) == 0)
     224  	    {
     225  	      uint32_t block_map_addr_off;
     226  
     227  	      block_map_addr_off =
     228  		((dir_offset / block_size) * sizeof (uint32_t));
     229  
     230  	      if (bfd_seek
     231  		  (abfd, (block_map_addr * block_size) + block_map_addr_off,
     232  		   SEEK_SET))
     233  		goto fail;
     234  
     235  	      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
     236  		  sizeof (uint32_t))
     237  		{
     238  		  bfd_set_error (bfd_error_malformed_archive);
     239  		  goto fail;
     240  		}
     241  
     242  	      block = bfd_getl32 (int_buf);
     243  
     244  	      if (bfd_seek (abfd, block * block_size, SEEK_SET))
     245  		goto fail;
     246  	    }
     247  
     248  	  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
     249  	      sizeof (uint32_t))
     250  	    {
     251  	      bfd_set_error (bfd_error_malformed_archive);
     252  	      goto fail;
     253  	    }
     254  
     255  	  size = bfd_getl32 (int_buf);
     256  
     257  	  if (size == 0xffffffff)
     258  	    size = 0;
     259  
     260  	  num_blocks = (size + block_size - 1) / block_size;
     261  	  block_off += num_blocks;
     262  
     263  	  dir_offset += sizeof (uint32_t);
     264  	}
     265      }
     266  
     267    /* Read blocks, and write into new BFD.  */
     268  
     269    dir_offset = sizeof (uint32_t) * (num_files + block_off + 1);
     270  
     271    if (dir_offset >= block_size)
     272      {
     273        uint32_t block_map_addr_off;
     274  
     275        block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
     276  
     277        if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
     278  		    SEEK_SET))
     279  	goto fail;
     280  
     281        if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     282  	{
     283  	  bfd_set_error (bfd_error_malformed_archive);
     284  	  goto fail;
     285  	}
     286  
     287        block = bfd_getl32 (int_buf);
     288      }
     289    else
     290      {
     291        block = first_dir_block;
     292      }
     293  
     294    buf = bfd_malloc (block_size);
     295    if (!buf)
     296      goto fail;
     297  
     298    left = file_size;
     299    do
     300      {
     301        uint32_t file_block, to_read;
     302  
     303        if ((dir_offset % block_size) == 0 && left != file_size)
     304  	{
     305  	  uint32_t block_map_addr_off;
     306  
     307  	  block_map_addr_off =
     308  	    ((dir_offset / block_size) * sizeof (uint32_t));
     309  
     310  	  if (bfd_seek
     311  	      (abfd, (block_map_addr * block_size) + block_map_addr_off,
     312  	       SEEK_SET))
     313  	    goto fail2;
     314  
     315  	  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
     316  	      sizeof (uint32_t))
     317  	    {
     318  	      bfd_set_error (bfd_error_malformed_archive);
     319  	      goto fail2;
     320  	    }
     321  
     322  	  block = bfd_getl32 (int_buf);
     323  	}
     324  
     325        if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
     326  		    SEEK_SET))
     327  	goto fail2;
     328  
     329        if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     330  	{
     331  	  bfd_set_error (bfd_error_malformed_archive);
     332  	  goto fail2;
     333  	}
     334  
     335        file_block = bfd_getl32 (int_buf);
     336  
     337        if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
     338  	goto fail2;
     339  
     340        to_read = left > block_size ? block_size : left;
     341  
     342        if (bfd_bread (buf, to_read, abfd) != to_read)
     343  	{
     344  	  bfd_set_error (bfd_error_malformed_archive);
     345  	  goto fail2;
     346  	}
     347  
     348        if (bfd_bwrite (buf, to_read, file) != to_read)
     349  	goto fail2;
     350  
     351        if (left > block_size)
     352  	left -= block_size;
     353        else
     354  	break;
     355  
     356        dir_offset += sizeof (uint32_t);
     357      }
     358    while (left > 0);
     359  
     360    free (buf);
     361  
     362    return file;
     363  
     364  fail2:
     365    free (buf);
     366  
     367  fail:
     368    bfd_close (file);
     369    return NULL;
     370  }
     371  
     372  static bfd *
     373  pdb_openr_next_archived_file (bfd *archive, bfd *last_file)
     374  {
     375    if (!last_file)
     376      return pdb_get_elt_at_index (archive, 0);
     377    else
     378      return pdb_get_elt_at_index (archive, arch_eltdata (last_file)->key + 1);
     379  }
     380  
     381  static int
     382  pdb_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
     383  {
     384    buf->st_mtime = 0;
     385    buf->st_uid = 0;
     386    buf->st_gid = 0;
     387    buf->st_mode = 0644;
     388    buf->st_size = arch_eltdata (abfd)->parsed_size;
     389  
     390    return 0;
     391  }
     392  
     393  static uint32_t
     394  pdb_allocate_block (uint32_t *num_blocks, uint32_t block_size)
     395  {
     396    uint32_t block;
     397  
     398    block = *num_blocks;
     399  
     400    (*num_blocks)++;
     401  
     402    /* If new interval, skip two blocks for free space map.  */
     403  
     404    if ((block % block_size) == 1)
     405      {
     406        block += 2;
     407        (*num_blocks) += 2;
     408      }
     409  
     410    return block;
     411  }
     412  
     413  static bool
     414  pdb_write_directory (bfd *abfd, uint32_t block_size, uint32_t num_files,
     415  		     uint32_t block_map_addr, uint32_t * num_blocks)
     416  {
     417    char tmp[sizeof (uint32_t)];
     418    uint32_t block, left, block_map_off;
     419    bfd *arelt;
     420    char *buf;
     421  
     422    /* Allocate first block for directory.  */
     423  
     424    block = pdb_allocate_block (num_blocks, block_size);
     425    left = block_size;
     426  
     427    /* Write allocated block no. at beginning of block map.  */
     428  
     429    if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
     430      return false;
     431  
     432    bfd_putl32 (block, tmp);
     433  
     434    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     435      return false;
     436  
     437    block_map_off = sizeof (uint32_t);
     438  
     439    /* Write num_files at beginning of directory.  */
     440  
     441    if (bfd_seek (abfd, block * block_size, SEEK_SET))
     442      return false;
     443  
     444    bfd_putl32 (num_files, tmp);
     445  
     446    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     447      return false;
     448  
     449    left -= sizeof (uint32_t);
     450  
     451    /* Write file sizes.  */
     452  
     453    arelt = abfd->archive_head;
     454    while (arelt)
     455      {
     456        if (left == 0)
     457  	{
     458  	  if (block_map_off == block_size) /* Too many blocks.  */
     459  	    {
     460  	      bfd_set_error (bfd_error_invalid_operation);
     461  	      return false;
     462  	    }
     463  
     464  	  block = pdb_allocate_block (num_blocks, block_size);
     465  	  left = block_size;
     466  
     467  	  if (bfd_seek
     468  	      (abfd, (block_map_addr * block_size) + block_map_off, SEEK_SET))
     469  	    return false;
     470  
     471  	  bfd_putl32 (block, tmp);
     472  
     473  	  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     474  	    return false;
     475  
     476  	  block_map_off += sizeof (uint32_t);
     477  
     478  	  if (bfd_seek (abfd, block * block_size, SEEK_SET))
     479  	    return false;
     480  	}
     481  
     482        bfd_putl32 (bfd_get_size (arelt), tmp);
     483  
     484        if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     485  	return false;
     486  
     487        left -= sizeof (uint32_t);
     488  
     489        arelt = arelt->archive_next;
     490      }
     491  
     492    /* Write blocks.  */
     493  
     494    buf = bfd_malloc (block_size);
     495    if (!buf)
     496      return false;
     497  
     498    arelt = abfd->archive_head;
     499    while (arelt)
     500      {
     501        ufile_ptr size = bfd_get_size (arelt);
     502        uint32_t req_blocks = (size + block_size - 1) / block_size;
     503  
     504        if (bfd_seek (arelt, 0, SEEK_SET))
     505  	{
     506  	  free (buf);
     507  	  return false;
     508  	}
     509  
     510        for (uint32_t i = 0; i < req_blocks; i++)
     511  	{
     512  	  uint32_t file_block, to_read;
     513  
     514  	  if (left == 0)
     515  	    {
     516  	      if (block_map_off == block_size) /* Too many blocks.  */
     517  		{
     518  		  bfd_set_error (bfd_error_invalid_operation);
     519  		  free (buf);
     520  		  return false;
     521  		}
     522  
     523  	      block = pdb_allocate_block (num_blocks, block_size);
     524  	      left = block_size;
     525  
     526  	      if (bfd_seek
     527  		  (abfd, (block_map_addr * block_size) + block_map_off,
     528  		   SEEK_SET))
     529  		{
     530  		  free (buf);
     531  		  return false;
     532  		}
     533  
     534  	      bfd_putl32 (block, tmp);
     535  
     536  	      if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) !=
     537  		  sizeof (uint32_t))
     538  		{
     539  		  free (buf);
     540  		  return false;
     541  		}
     542  
     543  	      block_map_off += sizeof (uint32_t);
     544  
     545  	      if (bfd_seek (abfd, block * block_size, SEEK_SET))
     546  		{
     547  		  free (buf);
     548  		  return false;
     549  		}
     550  	    }
     551  
     552  	  /* Allocate block and write number into directory.  */
     553  
     554  	  file_block = pdb_allocate_block (num_blocks, block_size);
     555  
     556  	  bfd_putl32 (file_block, tmp);
     557  
     558  	  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     559  	    {
     560  	      free (buf);
     561  	      return false;
     562  	    }
     563  
     564  	  left -= sizeof (uint32_t);
     565  
     566  	  /* Read file contents into buffer.  */
     567  
     568  	  to_read = size > block_size ? block_size : size;
     569  
     570  	  if (bfd_bread (buf, to_read, arelt) != to_read)
     571  	    {
     572  	      free (buf);
     573  	      return false;
     574  	    }
     575  
     576  	  size -= to_read;
     577  
     578  	  if (to_read < block_size)
     579  	    memset (buf + to_read, 0, block_size - to_read);
     580  
     581  	  if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
     582  	    {
     583  	      free (buf);
     584  	      return false;
     585  	    }
     586  
     587  	  /* Write file contents into allocated block.  */
     588  
     589  	  if (bfd_bwrite (buf, block_size, abfd) != block_size)
     590  	    {
     591  	      free (buf);
     592  	      return false;
     593  	    }
     594  
     595  	  if (bfd_seek
     596  	      (abfd, (block * block_size) + block_size - left, SEEK_SET))
     597  	    {
     598  	      free (buf);
     599  	      return false;
     600  	    }
     601  	}
     602  
     603        arelt = arelt->archive_next;
     604      }
     605  
     606    memset (buf, 0, left);
     607  
     608    if (bfd_bwrite (buf, left, abfd) != left)
     609      {
     610        free (buf);
     611        return false;
     612      }
     613  
     614    free (buf);
     615  
     616    return true;
     617  }
     618  
     619  static bool
     620  pdb_write_bitmap (bfd *abfd, uint32_t block_size, uint32_t num_blocks)
     621  {
     622    char *buf;
     623    uint32_t num_intervals = (num_blocks + block_size - 1) / block_size;
     624  
     625    buf = bfd_malloc (block_size);
     626    if (!buf)
     627      return false;
     628  
     629    num_blocks--;			/* Superblock not included.  */
     630  
     631    for (uint32_t i = 0; i < num_intervals; i++)
     632      {
     633        if (bfd_seek (abfd, ((i * block_size) + 1) * block_size, SEEK_SET))
     634  	{
     635  	  free (buf);
     636  	  return false;
     637  	}
     638  
     639        /* All of our blocks are contiguous, making our free block map simple.
     640           0 = used, 1 = free.  */
     641  
     642        if (num_blocks >= 8)
     643  	memset (buf, 0,
     644  		(num_blocks / 8) >
     645  		block_size ? block_size : (num_blocks / 8));
     646  
     647        if (num_blocks < block_size * 8)
     648  	{
     649  	  unsigned int off = num_blocks / 8;
     650  
     651  	  if (num_blocks % 8)
     652  	    {
     653  	      buf[off] = (1 << (8 - (num_blocks % 8))) - 1;
     654  	      off++;
     655  	    }
     656  
     657  	  if (off < block_size)
     658  	    memset (buf + off, 0xff, block_size - off);
     659  	}
     660  
     661        if (num_blocks < block_size * 8)
     662  	num_blocks = 0;
     663        else
     664  	num_blocks -= block_size * 8;
     665  
     666        if (bfd_bwrite (buf, block_size, abfd) != block_size)
     667  	return false;
     668      }
     669  
     670    free (buf);
     671  
     672    return true;
     673  }
     674  
     675  static bool
     676  pdb_write_contents (bfd *abfd)
     677  {
     678    char tmp[sizeof (uint32_t)];
     679    const uint32_t block_size = 0x400;
     680    uint32_t block_map_addr;
     681    uint32_t num_blocks;
     682    uint32_t num_files = 0;
     683    uint32_t num_directory_bytes = sizeof (uint32_t);
     684    bfd *arelt;
     685  
     686    if (bfd_bwrite (pdb_magic, sizeof (pdb_magic), abfd) != sizeof (pdb_magic))
     687      return false;
     688  
     689    bfd_putl32 (block_size, tmp);
     690  
     691    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     692      return false;
     693  
     694    bfd_putl32 (1, tmp); /* Free block map block (always either 1 or 2).  */
     695  
     696    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     697      return false;
     698  
     699    arelt = abfd->archive_head;
     700  
     701    while (arelt)
     702      {
     703        uint32_t blocks_required =
     704  	(bfd_get_size (arelt) + block_size - 1) / block_size;
     705  
     706        num_directory_bytes += sizeof (uint32_t); /* Size.  */
     707        num_directory_bytes += blocks_required * sizeof (uint32_t); /* Blocks.  */
     708  
     709        num_files++;
     710  
     711        arelt = arelt->archive_next;
     712      }
     713  
     714    /* Superblock plus two bitmap blocks.  */
     715    num_blocks = 3;
     716  
     717    /* Skip num_blocks for now.  */
     718    if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
     719      return false;
     720  
     721    bfd_putl32 (num_directory_bytes, tmp);
     722  
     723    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     724      return false;
     725  
     726    /* Skip unknown uint32_t (always 0?).  */
     727    if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
     728      return false;
     729  
     730    block_map_addr = pdb_allocate_block (&num_blocks, block_size);
     731  
     732    bfd_putl32 (block_map_addr, tmp);
     733  
     734    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     735      return false;
     736  
     737    if (!pdb_write_directory
     738        (abfd, block_size, num_files, block_map_addr, &num_blocks))
     739      return false;
     740  
     741    if (!pdb_write_bitmap (abfd, block_size, num_blocks))
     742      return false;
     743  
     744    /* Write num_blocks now we know it.  */
     745  
     746    if (bfd_seek
     747        (abfd, sizeof (pdb_magic) + sizeof (uint32_t) + sizeof (uint32_t),
     748         SEEK_SET))
     749      return false;
     750  
     751    bfd_putl32 (num_blocks, tmp);
     752  
     753    if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
     754      return false;
     755  
     756    return true;
     757  }
     758  
     759  #define pdb_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
     760  #define pdb_new_section_hook _bfd_generic_new_section_hook
     761  #define pdb_get_section_contents _bfd_generic_get_section_contents
     762  #define pdb_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
     763  #define pdb_close_and_cleanup _bfd_generic_close_and_cleanup
     764  
     765  #define pdb_slurp_armap _bfd_noarchive_slurp_armap
     766  #define pdb_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
     767  #define pdb_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
     768  #define pdb_truncate_arname _bfd_noarchive_truncate_arname
     769  #define pdb_write_armap _bfd_noarchive_write_armap
     770  #define pdb_read_ar_hdr _bfd_noarchive_read_ar_hdr
     771  #define pdb_write_ar_hdr _bfd_noarchive_write_ar_hdr
     772  #define pdb_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
     773  
     774  const bfd_target pdb_vec =
     775  {
     776    "pdb",
     777    bfd_target_unknown_flavour,
     778    BFD_ENDIAN_LITTLE,		/* target byte order */
     779    BFD_ENDIAN_LITTLE,		/* target headers byte order */
     780    0,				/* object flags */
     781    0,				/* section flags */
     782    0,				/* leading underscore */
     783    ' ',				/* ar_pad_char */
     784    16,				/* ar_max_namelen */
     785    0,				/* match priority.  */
     786    TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     787    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     788    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     789    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
     790    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     791    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     792    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
     793  
     794    {				/* bfd_check_format */
     795      _bfd_dummy_target,
     796      _bfd_dummy_target,
     797      pdb_archive_p,
     798      _bfd_dummy_target
     799    },
     800    {				/* bfd_set_format */
     801      _bfd_bool_bfd_false_error,
     802      _bfd_bool_bfd_false_error,
     803      _bfd_bool_bfd_true,
     804      _bfd_bool_bfd_false_error
     805    },
     806    {				/* bfd_write_contents */
     807      _bfd_bool_bfd_true,
     808      _bfd_bool_bfd_false_error,
     809      pdb_write_contents,
     810      _bfd_bool_bfd_false_error
     811    },
     812  
     813    BFD_JUMP_TABLE_GENERIC (pdb),
     814    BFD_JUMP_TABLE_COPY (_bfd_generic),
     815    BFD_JUMP_TABLE_CORE (_bfd_nocore),
     816    BFD_JUMP_TABLE_ARCHIVE (pdb),
     817    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
     818    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
     819    BFD_JUMP_TABLE_WRITE (_bfd_generic),
     820    BFD_JUMP_TABLE_LINK (_bfd_nolink),
     821    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
     822  
     823    NULL,
     824  
     825    NULL
     826  };