pdb.c revision 1.1.1.3 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
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 *
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 *
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 uint32_t *stream0_start)
417 {
418 char tmp[sizeof (uint32_t)];
419 uint32_t block, left, block_map_off;
420 bfd *arelt;
421 char *buf;
422
423 /* Allocate first block for directory. */
424
425 block = pdb_allocate_block (num_blocks, block_size);
426 left = block_size;
427
428 /* Write allocated block no. at beginning of block map. */
429
430 if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
431 return false;
432
433 bfd_putl32 (block, tmp);
434
435 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
436 return false;
437
438 block_map_off = sizeof (uint32_t);
439
440 /* Write num_files at beginning of directory. */
441
442 if (bfd_seek (abfd, block * block_size, SEEK_SET))
443 return false;
444
445 bfd_putl32 (num_files, tmp);
446
447 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
448 return false;
449
450 left -= sizeof (uint32_t);
451
452 /* Write file sizes. */
453
454 arelt = abfd->archive_head;
455 while (arelt)
456 {
457 if (left == 0)
458 {
459 if (block_map_off == block_size) /* Too many blocks. */
460 {
461 bfd_set_error (bfd_error_invalid_operation);
462 return false;
463 }
464
465 block = pdb_allocate_block (num_blocks, block_size);
466 left = block_size;
467
468 if (bfd_seek
469 (abfd, (block_map_addr * block_size) + block_map_off, SEEK_SET))
470 return false;
471
472 bfd_putl32 (block, tmp);
473
474 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
475 return false;
476
477 block_map_off += sizeof (uint32_t);
478
479 if (bfd_seek (abfd, block * block_size, SEEK_SET))
480 return false;
481 }
482
483 bfd_putl32 (bfd_get_size (arelt), tmp);
484
485 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
486 return false;
487
488 left -= sizeof (uint32_t);
489
490 arelt = arelt->archive_next;
491 }
492
493 /* Write blocks. */
494
495 buf = bfd_malloc (block_size);
496 if (!buf)
497 return false;
498
499 arelt = abfd->archive_head;
500 while (arelt)
501 {
502 ufile_ptr size = bfd_get_size (arelt);
503 uint32_t req_blocks = (size + block_size - 1) / block_size;
504
505 if (bfd_seek (arelt, 0, SEEK_SET))
506 {
507 free (buf);
508 return false;
509 }
510
511 for (uint32_t i = 0; i < req_blocks; i++)
512 {
513 uint32_t file_block, to_read;
514
515 if (left == 0)
516 {
517 if (block_map_off == block_size) /* Too many blocks. */
518 {
519 bfd_set_error (bfd_error_invalid_operation);
520 free (buf);
521 return false;
522 }
523
524 block = pdb_allocate_block (num_blocks, block_size);
525 left = block_size;
526
527 if (bfd_seek
528 (abfd, (block_map_addr * block_size) + block_map_off,
529 SEEK_SET))
530 {
531 free (buf);
532 return false;
533 }
534
535 bfd_putl32 (block, tmp);
536
537 if (bfd_write (tmp, sizeof (uint32_t), abfd) !=
538 sizeof (uint32_t))
539 {
540 free (buf);
541 return false;
542 }
543
544 block_map_off += sizeof (uint32_t);
545
546 if (bfd_seek (abfd, block * block_size, SEEK_SET))
547 {
548 free (buf);
549 return false;
550 }
551 }
552
553 /* Allocate block and write number into directory. */
554
555 file_block = pdb_allocate_block (num_blocks, block_size);
556
557 bfd_putl32 (file_block, tmp);
558
559 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
560 {
561 free (buf);
562 return false;
563 }
564
565 if (arelt == abfd->archive_head && i == 0)
566 *stream0_start = file_block;
567
568 left -= sizeof (uint32_t);
569
570 /* Read file contents into buffer. */
571
572 to_read = size > block_size ? block_size : size;
573
574 if (bfd_read (buf, to_read, arelt) != to_read)
575 {
576 free (buf);
577 return false;
578 }
579
580 size -= to_read;
581
582 if (to_read < block_size)
583 memset (buf + to_read, 0, block_size - to_read);
584
585 if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
586 {
587 free (buf);
588 return false;
589 }
590
591 /* Write file contents into allocated block. */
592
593 if (bfd_write (buf, block_size, abfd) != block_size)
594 {
595 free (buf);
596 return false;
597 }
598
599 if (bfd_seek
600 (abfd, (block * block_size) + block_size - left, SEEK_SET))
601 {
602 free (buf);
603 return false;
604 }
605 }
606
607 arelt = arelt->archive_next;
608 }
609
610 memset (buf, 0, left);
611
612 if (bfd_write (buf, left, abfd) != left)
613 {
614 free (buf);
615 return false;
616 }
617
618 free (buf);
619
620 return true;
621 }
622
623 static bool
624 pdb_write_bitmap (bfd *abfd, uint32_t block_size, uint32_t num_blocks,
625 uint32_t stream0_start)
626 {
627 char *buf;
628 uint32_t num_intervals = (num_blocks + block_size - 1) / block_size;
629
630 buf = bfd_malloc (block_size);
631 if (!buf)
632 return false;
633
634 for (uint32_t i = 0; i < num_intervals; i++)
635 {
636 if (bfd_seek (abfd, ((i * block_size) + 1) * block_size, SEEK_SET))
637 {
638 free (buf);
639 return false;
640 }
641
642 /* All of our blocks are contiguous, making our free block map
643 relatively simple. 0 = used, 1 = free. */
644
645 if (num_blocks >= 8)
646 memset (buf, 0,
647 (num_blocks / 8) >
648 block_size ? block_size : (num_blocks / 8));
649
650 if (num_blocks < block_size * 8)
651 {
652 unsigned int off = num_blocks / 8;
653
654 if (num_blocks % 8)
655 {
656 buf[off] = 256 - (1 << (num_blocks % 8));
657 off++;
658 }
659
660 if (off < block_size)
661 memset (buf + off, 0xff, block_size - off);
662 }
663
664 /* Mark the blocks allocated to stream 0 as free. This is because stream
665 0 is intended to be used for the previous MSF directory, to allow
666 atomic updates. This doesn't apply to us, as we rewrite the whole
667 file whenever any change is made. */
668
669 if (i == 0 && abfd->archive_head)
670 {
671 bfd *arelt = abfd->archive_head;
672 uint32_t stream0_blocks =
673 (bfd_get_size (arelt) + block_size - 1) / block_size;
674
675 if (stream0_start % 8)
676 {
677 unsigned int high_bit;
678
679 high_bit = (stream0_start % 8) + stream0_blocks;
680 if (high_bit > 8)
681 high_bit = 8;
682
683 buf[stream0_start / 8] |=
684 (1 << high_bit) - (1 << (stream0_start % 8));
685
686 stream0_blocks -= high_bit - (stream0_start % 8);
687 stream0_start += high_bit - (stream0_start % 8);
688 }
689
690 memset (buf + (stream0_start / 8), 0xff, stream0_blocks / 8);
691 stream0_start += stream0_blocks / 8;
692 stream0_blocks %= 8;
693
694 if (stream0_blocks > 0)
695 buf[stream0_start / 8] |= (1 << stream0_blocks) - 1;
696 }
697
698 if (num_blocks < block_size * 8)
699 num_blocks = 0;
700 else
701 num_blocks -= block_size * 8;
702
703 if (bfd_write (buf, block_size, abfd) != block_size)
704 return false;
705 }
706
707 free (buf);
708
709 return true;
710 }
711
712 static bool
713 pdb_write_contents (bfd *abfd)
714 {
715 char tmp[sizeof (uint32_t)];
716 const uint32_t block_size = 0x400;
717 uint32_t block_map_addr;
718 uint32_t num_blocks;
719 uint32_t num_files = 0;
720 uint32_t num_directory_bytes = sizeof (uint32_t);
721 uint32_t stream0_start = 0;
722 bfd *arelt;
723
724 if (bfd_write (pdb_magic, sizeof (pdb_magic), abfd) != sizeof (pdb_magic))
725 return false;
726
727 bfd_putl32 (block_size, tmp);
728
729 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
730 return false;
731
732 bfd_putl32 (1, tmp); /* Free block map block (always either 1 or 2). */
733
734 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
735 return false;
736
737 arelt = abfd->archive_head;
738
739 while (arelt)
740 {
741 uint32_t blocks_required =
742 (bfd_get_size (arelt) + block_size - 1) / block_size;
743
744 num_directory_bytes += sizeof (uint32_t); /* Size. */
745 num_directory_bytes += blocks_required * sizeof (uint32_t); /* Blocks. */
746
747 num_files++;
748
749 arelt = arelt->archive_next;
750 }
751
752 /* Superblock plus two bitmap blocks. */
753 num_blocks = 3;
754
755 /* Skip num_blocks for now. */
756 if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
757 return false;
758
759 bfd_putl32 (num_directory_bytes, tmp);
760
761 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
762 return false;
763
764 /* Skip unknown uint32_t (always 0?). */
765 if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
766 return false;
767
768 block_map_addr = pdb_allocate_block (&num_blocks, block_size);
769
770 bfd_putl32 (block_map_addr, tmp);
771
772 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
773 return false;
774
775 if (!pdb_write_directory
776 (abfd, block_size, num_files, block_map_addr, &num_blocks,
777 &stream0_start))
778 return false;
779
780 if (!pdb_write_bitmap (abfd, block_size, num_blocks, stream0_start))
781 return false;
782
783 /* Write num_blocks now we know it. */
784
785 if (bfd_seek
786 (abfd, sizeof (pdb_magic) + sizeof (uint32_t) + sizeof (uint32_t),
787 SEEK_SET))
788 return false;
789
790 bfd_putl32 (num_blocks, tmp);
791
792 if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
793 return false;
794
795 return true;
796 }
797
798 #define pdb_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
799 #define pdb_new_section_hook _bfd_generic_new_section_hook
800 #define pdb_get_section_contents _bfd_generic_get_section_contents
801 #define pdb_close_and_cleanup _bfd_generic_close_and_cleanup
802
803 #define pdb_slurp_armap _bfd_noarchive_slurp_armap
804 #define pdb_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
805 #define pdb_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
806 #define pdb_truncate_arname _bfd_noarchive_truncate_arname
807 #define pdb_write_armap _bfd_noarchive_write_armap
808 #define pdb_read_ar_hdr _bfd_noarchive_read_ar_hdr
809 #define pdb_write_ar_hdr _bfd_noarchive_write_ar_hdr
810 #define pdb_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
811
812 const bfd_target pdb_vec =
813 {
814 "pdb",
815 bfd_target_unknown_flavour,
816 BFD_ENDIAN_LITTLE, /* target byte order */
817 BFD_ENDIAN_LITTLE, /* target headers byte order */
818 0, /* object flags */
819 0, /* section flags */
820 0, /* leading underscore */
821 ' ', /* ar_pad_char */
822 16, /* ar_max_namelen */
823 0, /* match priority. */
824 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
825 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
826 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
827 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
828 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
829 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
830 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
831
832 { /* bfd_check_format */
833 _bfd_dummy_target,
834 _bfd_dummy_target,
835 pdb_archive_p,
836 _bfd_dummy_target
837 },
838 { /* bfd_set_format */
839 _bfd_bool_bfd_false_error,
840 _bfd_bool_bfd_false_error,
841 _bfd_bool_bfd_true,
842 _bfd_bool_bfd_false_error
843 },
844 { /* bfd_write_contents */
845 _bfd_bool_bfd_true,
846 _bfd_bool_bfd_false_error,
847 pdb_write_contents,
848 _bfd_bool_bfd_false_error
849 },
850
851 BFD_JUMP_TABLE_GENERIC (pdb),
852 BFD_JUMP_TABLE_COPY (_bfd_generic),
853 BFD_JUMP_TABLE_CORE (_bfd_nocore),
854 BFD_JUMP_TABLE_ARCHIVE (pdb),
855 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
856 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
857 BFD_JUMP_TABLE_WRITE (_bfd_generic),
858 BFD_JUMP_TABLE_LINK (_bfd_nolink),
859 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
860
861 NULL,
862
863 NULL
864 };
865