xref: /netbsd-src/external/gpl3/binutils/dist/bfd/pdb.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* BFD back-end for PDB Multi-Stream Format archives.
2    Copyright (C) 2022-2024 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
pdb_archive_p(bfd * abfd)39 pdb_archive_p (bfd *abfd)
40 {
41   int ret;
42   char magic[sizeof (pdb_magic)];
43 
44   ret = bfd_read (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 *
pdb_get_elt_at_index(bfd * abfd,symindex sym_index)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_read (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_read (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_read (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_read (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_read (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_read (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_read (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_read (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_read (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_read (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_read (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_read (buf, to_read, abfd) != to_read)
343 	{
344 	  bfd_set_error (bfd_error_malformed_archive);
345 	  goto fail2;
346 	}
347 
348       if (bfd_write (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 *
pdb_openr_next_archived_file(bfd * archive,bfd * last_file)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
pdb_generic_stat_arch_elt(bfd * abfd,struct stat * buf)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
pdb_allocate_block(uint32_t * num_blocks,uint32_t block_size)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
pdb_write_directory(bfd * abfd,uint32_t block_size,uint32_t num_files,uint32_t block_map_addr,uint32_t * num_blocks)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_write (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_write (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_write (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_write (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_write (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_write (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_read (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_write (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_write (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
pdb_write_bitmap(bfd * abfd,uint32_t block_size,uint32_t num_blocks)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_write (buf, block_size, abfd) != block_size)
667 	return false;
668     }
669 
670   free (buf);
671 
672   return true;
673 }
674 
675 static bool
pdb_write_contents(bfd * abfd)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_write (pdb_magic, sizeof (pdb_magic), abfd) != sizeof (pdb_magic))
687     return false;
688 
689   bfd_putl32 (block_size, tmp);
690 
691   if (bfd_write (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_write (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_write (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_write (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_write (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 };
827