Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/pdb.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD back-end for PDB Multi-Stream Format archives.
2
   Copyright (C) 2022-2025 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
5.63k
#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
37
38
static bfd_cleanup
39
pdb_archive_p (bfd *abfd)
40
157k
{
41
157k
  int ret;
42
157k
  char magic[sizeof (pdb_magic)];
43
44
157k
  ret = bfd_read (magic, sizeof (magic), abfd);
45
157k
  if (ret != sizeof (magic))
46
10.2k
    {
47
10.2k
      bfd_set_error (bfd_error_wrong_format);
48
10.2k
      return NULL;
49
10.2k
    }
50
51
146k
  if (memcmp (magic, pdb_magic, sizeof (magic)))
52
146k
    {
53
146k
      bfd_set_error (bfd_error_wrong_format);
54
146k
      return NULL;
55
146k
    }
56
57
131
  void *tdata = bfd_zalloc (abfd, sizeof (struct artdata));
58
131
  if (tdata == NULL)
59
0
    return NULL;
60
131
  bfd_ardata (abfd) = tdata;
61
62
131
  return _bfd_no_cleanup;
63
131
}
64
65
static bfd *
66
pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
67
1.76k
{
68
1.76k
  char int_buf[sizeof (uint32_t)];
69
1.76k
  uint32_t block_size, block_map_addr, block, num_files;
70
1.76k
  uint32_t first_dir_block, dir_offset, file_size, block_off, left;
71
1.76k
  char name[10];
72
1.76k
  bfd *file;
73
1.76k
  char *buf;
74
75
  /* Get block_size.  */
76
77
1.76k
  if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
78
0
    return NULL;
79
80
1.76k
  if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
81
2
    {
82
2
      bfd_set_error (bfd_error_malformed_archive);
83
2
      return NULL;
84
2
    }
85
86
1.76k
  block_size = bfd_getl32 (int_buf);
87
1.76k
  if ((block_size & -block_size) != block_size
88
1.76k
      || block_size < 512
89
1.76k
      || block_size > 4096)
90
7
    {
91
7
      bfd_set_error (bfd_error_malformed_archive);
92
7
      return NULL;
93
7
    }
94
95
  /* Get block_map_addr.  */
96
97
1.75k
  if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
98
0
    return NULL;
99
100
1.75k
  if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
101
3
    {
102
3
      bfd_set_error (bfd_error_malformed_archive);
103
3
      return NULL;
104
3
    }
105
106
1.75k
  block_map_addr = bfd_getl32 (int_buf);
107
108
  /* Get num_files.  */
109
110
1.75k
  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
111
0
    return NULL;
112
113
1.75k
  if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
114
2
    {
115
2
      bfd_set_error (bfd_error_malformed_archive);
116
2
      return NULL;
117
2
    }
118
119
1.74k
  first_dir_block = bfd_getl32 (int_buf);
120
121
1.74k
  if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
122
0
    return NULL;
123
124
1.74k
  if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
125
2
    {
126
2
      bfd_set_error (bfd_error_malformed_archive);
127
2
      return NULL;
128
2
    }
129
130
1.74k
  num_files = bfd_getl32 (int_buf);
131
132
1.74k
  if (sym_index >= num_files)
133
5
    {
134
5
      bfd_set_error (bfd_error_no_more_archived_files);
135
5
      return NULL;
136
5
    }
137
138
  /* Read file size.  */
139
140
1.74k
  dir_offset = sizeof (uint32_t) * (sym_index + 1);
141
142
1.74k
  if (dir_offset >= block_size)
143
47
    {
144
47
      uint32_t block_map_addr_off;
145
146
47
      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
147
148
47
      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
149
47
        SEEK_SET))
150
0
  return NULL;
151
152
47
      if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
153
0
  {
154
0
    bfd_set_error (bfd_error_malformed_archive);
155
0
    return NULL;
156
0
  }
157
158
47
      block = bfd_getl32 (int_buf);
159
47
    }
160
1.69k
  else
161
1.69k
    {
162
1.69k
      block = first_dir_block;
163
1.69k
    }
164
165
1.74k
  if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
166
1.74k
    SEEK_SET))
167
0
    return NULL;
168
169
1.74k
  if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
170
4
    {
171
4
      bfd_set_error (bfd_error_malformed_archive);
172
4
      return NULL;
173
4
    }
174
175
1.73k
  file_size = bfd_getl32 (int_buf);
176
177
  /* Undocumented? Seen on PDBs created by MSVC 2022.  */
178
1.73k
  if (file_size == 0xffffffff)
179
975
    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
1.73k
  sprintf (name, "%04lx", sym_index);
186
187
1.73k
  file = bfd_create (name, abfd);
188
189
1.73k
  if (!file)
190
0
    return NULL;
191
192
1.73k
  if (!bfd_make_writable (file))
193
0
    goto fail;
194
195
1.73k
  file->arelt_data =
196
1.73k
    (struct areltdata *) bfd_zmalloc (sizeof (struct areltdata));
197
198
1.73k
  if (!file->arelt_data)
199
0
    goto fail;
200
201
1.73k
  arch_eltdata (file)->parsed_size = file_size;
202
1.73k
  arch_eltdata (file)->key = sym_index;
203
204
1.73k
  if (file_size == 0)
205
1.23k
    return file;
206
207
499
  block_off = 0;
208
209
  /* Sum number of blocks in previous files.  */
210
211
499
  if (sym_index != 0)
212
448
    {
213
448
      dir_offset = sizeof (uint32_t);
214
215
448
      if (bfd_seek (abfd, (first_dir_block * block_size) + sizeof (uint32_t),
216
448
        SEEK_SET))
217
0
  goto fail;
218
219
11.5k
      for (symindex i = 0; i < sym_index; i++)
220
11.1k
  {
221
11.1k
    uint32_t size, num_blocks;
222
223
11.1k
    if ((dir_offset % block_size) == 0)
224
4
      {
225
4
        uint32_t block_map_addr_off;
226
227
4
        block_map_addr_off =
228
4
    ((dir_offset / block_size) * sizeof (uint32_t));
229
230
4
        if (bfd_seek
231
4
      (abfd, (block_map_addr * block_size) + block_map_addr_off,
232
4
       SEEK_SET))
233
0
    goto fail;
234
235
4
        if (bfd_read (int_buf, sizeof (uint32_t), abfd) !=
236
4
      sizeof (uint32_t))
237
0
    {
238
0
      bfd_set_error (bfd_error_malformed_archive);
239
0
      goto fail;
240
0
    }
241
242
4
        block = bfd_getl32 (int_buf);
243
244
4
        if (bfd_seek (abfd, block * block_size, SEEK_SET))
245
0
    goto fail;
246
4
      }
247
248
11.1k
    if (bfd_read (int_buf, sizeof (uint32_t), abfd) !=
249
11.1k
        sizeof (uint32_t))
250
0
      {
251
0
        bfd_set_error (bfd_error_malformed_archive);
252
0
        goto fail;
253
0
      }
254
255
11.1k
    size = bfd_getl32 (int_buf);
256
257
11.1k
    if (size == 0xffffffff)
258
824
      size = 0;
259
260
11.1k
    num_blocks = (size + block_size - 1) / block_size;
261
11.1k
    block_off += num_blocks;
262
263
11.1k
    dir_offset += sizeof (uint32_t);
264
11.1k
  }
265
448
    }
266
267
  /* Read blocks, and write into new BFD.  */
268
269
499
  dir_offset = sizeof (uint32_t) * (num_files + block_off + 1);
270
271
499
  if (dir_offset >= block_size)
272
217
    {
273
217
      uint32_t block_map_addr_off;
274
275
217
      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
276
277
217
      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
278
217
        SEEK_SET))
279
0
  goto fail;
280
281
217
      if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
282
14
  {
283
14
    bfd_set_error (bfd_error_malformed_archive);
284
14
    goto fail;
285
14
  }
286
287
203
      block = bfd_getl32 (int_buf);
288
203
    }
289
282
  else
290
282
    {
291
282
      block = first_dir_block;
292
282
    }
293
294
485
  buf = bfd_malloc (block_size);
295
485
  if (!buf)
296
0
    goto fail;
297
298
485
  left = file_size;
299
485
  do
300
2.29k
    {
301
2.29k
      uint32_t file_block, to_read;
302
303
2.29k
      if ((dir_offset % block_size) == 0 && left != file_size)
304
10
  {
305
10
    uint32_t block_map_addr_off;
306
307
10
    block_map_addr_off =
308
10
      ((dir_offset / block_size) * sizeof (uint32_t));
309
310
10
    if (bfd_seek
311
10
        (abfd, (block_map_addr * block_size) + block_map_addr_off,
312
10
         SEEK_SET))
313
0
      goto fail2;
314
315
10
    if (bfd_read (int_buf, sizeof (uint32_t), abfd) !=
316
10
        sizeof (uint32_t))
317
0
      {
318
0
        bfd_set_error (bfd_error_malformed_archive);
319
0
        goto fail2;
320
0
      }
321
322
10
    block = bfd_getl32 (int_buf);
323
10
  }
324
325
2.29k
      if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
326
2.29k
        SEEK_SET))
327
0
  goto fail2;
328
329
2.29k
      if (bfd_read (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
330
9
  {
331
9
    bfd_set_error (bfd_error_malformed_archive);
332
9
    goto fail2;
333
9
  }
334
335
2.28k
      file_block = bfd_getl32 (int_buf);
336
337
2.28k
      if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
338
0
  goto fail2;
339
340
2.28k
      to_read = left > block_size ? block_size : left;
341
342
2.28k
      if (bfd_read (buf, to_read, abfd) != to_read)
343
80
  {
344
80
    bfd_set_error (bfd_error_malformed_archive);
345
80
    goto fail2;
346
80
  }
347
348
2.20k
      if (bfd_write (buf, to_read, file) != to_read)
349
0
  goto fail2;
350
351
2.20k
      if (left > block_size)
352
1.80k
  left -= block_size;
353
396
      else
354
396
  break;
355
356
1.80k
      dir_offset += sizeof (uint32_t);
357
1.80k
    }
358
1.80k
  while (left > 0);
359
360
396
  free (buf);
361
362
396
  return file;
363
364
89
fail2:
365
89
  free (buf);
366
367
103
fail:
368
103
  bfd_close (file);
369
103
  return NULL;
370
89
}
371
372
static bfd *
373
pdb_openr_next_archived_file (bfd *archive, bfd *last_file)
374
1.76k
{
375
1.76k
  if (!last_file)
376
128
    return pdb_get_elt_at_index (archive, 0);
377
1.63k
  else
378
1.63k
    return pdb_get_elt_at_index (archive, arch_eltdata (last_file)->key + 1);
379
1.76k
}
380
381
static int
382
pdb_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
383
522
{
384
522
  buf->st_mtime = 0;
385
522
  buf->st_uid = 0;
386
522
  buf->st_gid = 0;
387
522
  buf->st_mode = 0644;
388
522
  buf->st_size = arch_eltdata (abfd)->parsed_size;
389
390
522
  return 0;
391
522
}
392
393
static uint32_t
394
pdb_allocate_block (uint32_t *num_blocks, uint32_t block_size)
395
783
{
396
783
  uint32_t block;
397
398
783
  block = *num_blocks;
399
400
783
  (*num_blocks)++;
401
402
  /* If new interval, skip two blocks for free space map.  */
403
404
783
  if ((block % block_size) == 1)
405
0
    {
406
0
      block += 2;
407
0
      (*num_blocks) += 2;
408
0
    }
409
410
783
  return block;
411
783
}
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
37
{
418
37
  char tmp[sizeof (uint32_t)];
419
37
  uint32_t block, left, block_map_off;
420
37
  bfd *arelt;
421
37
  char *buf;
422
423
  /* Allocate first block for directory.  */
424
425
37
  block = pdb_allocate_block (num_blocks, block_size);
426
37
  left = block_size;
427
428
  /* Write allocated block no. at beginning of block map.  */
429
430
37
  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
431
0
    return false;
432
433
37
  bfd_putl32 (block, tmp);
434
435
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
436
0
    return false;
437
438
37
  block_map_off = sizeof (uint32_t);
439
440
  /* Write num_files at beginning of directory.  */
441
442
37
  if (bfd_seek (abfd, block * block_size, SEEK_SET))
443
0
    return false;
444
445
37
  bfd_putl32 (num_files, tmp);
446
447
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
448
0
    return false;
449
450
37
  left -= sizeof (uint32_t);
451
452
  /* Write file sizes.  */
453
454
37
  arelt = abfd->archive_head;
455
559
  while (arelt)
456
522
    {
457
522
      if (left == 0)
458
0
  {
459
0
    if (block_map_off == block_size) /* Too many blocks.  */
460
0
      {
461
0
        bfd_set_error (bfd_error_invalid_operation);
462
0
        return false;
463
0
      }
464
465
0
    block = pdb_allocate_block (num_blocks, block_size);
466
0
    left = block_size;
467
468
0
    if (bfd_seek
469
0
        (abfd, (block_map_addr * block_size) + block_map_off, SEEK_SET))
470
0
      return false;
471
472
0
    bfd_putl32 (block, tmp);
473
474
0
    if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
475
0
      return false;
476
477
0
    block_map_off += sizeof (uint32_t);
478
479
0
    if (bfd_seek (abfd, block * block_size, SEEK_SET))
480
0
      return false;
481
0
  }
482
483
522
      bfd_putl32 (bfd_get_size (arelt), tmp);
484
485
522
      if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
486
0
  return false;
487
488
522
      left -= sizeof (uint32_t);
489
490
522
      arelt = arelt->archive_next;
491
522
    }
492
493
  /* Write blocks.  */
494
495
37
  buf = bfd_malloc (block_size);
496
37
  if (!buf)
497
0
    return false;
498
499
37
  arelt = abfd->archive_head;
500
559
  while (arelt)
501
522
    {
502
522
      ufile_ptr size = bfd_get_size (arelt);
503
522
      uint32_t req_blocks = (size + block_size - 1) / block_size;
504
505
522
      if (bfd_seek (arelt, 0, SEEK_SET))
506
0
  {
507
0
    free (buf);
508
0
    return false;
509
0
  }
510
511
1.23k
      for (uint32_t i = 0; i < req_blocks; i++)
512
708
  {
513
708
    uint32_t file_block, to_read;
514
515
708
    if (left == 0)
516
1
      {
517
1
        if (block_map_off == block_size) /* Too many blocks.  */
518
0
    {
519
0
      bfd_set_error (bfd_error_invalid_operation);
520
0
      free (buf);
521
0
      return false;
522
0
    }
523
524
1
        block = pdb_allocate_block (num_blocks, block_size);
525
1
        left = block_size;
526
527
1
        if (bfd_seek
528
1
      (abfd, (block_map_addr * block_size) + block_map_off,
529
1
       SEEK_SET))
530
0
    {
531
0
      free (buf);
532
0
      return false;
533
0
    }
534
535
1
        bfd_putl32 (block, tmp);
536
537
1
        if (bfd_write (tmp, sizeof (uint32_t), abfd) !=
538
1
      sizeof (uint32_t))
539
0
    {
540
0
      free (buf);
541
0
      return false;
542
0
    }
543
544
1
        block_map_off += sizeof (uint32_t);
545
546
1
        if (bfd_seek (abfd, block * block_size, SEEK_SET))
547
0
    {
548
0
      free (buf);
549
0
      return false;
550
0
    }
551
1
      }
552
553
    /* Allocate block and write number into directory.  */
554
555
708
    file_block = pdb_allocate_block (num_blocks, block_size);
556
557
708
    bfd_putl32 (file_block, tmp);
558
559
708
    if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
560
0
      {
561
0
        free (buf);
562
0
        return false;
563
0
      }
564
565
708
    if (arelt == abfd->archive_head && i == 0)
566
17
      *stream0_start = file_block;
567
568
708
    left -= sizeof (uint32_t);
569
570
    /* Read file contents into buffer.  */
571
572
708
    to_read = size > block_size ? block_size : size;
573
574
708
    if (bfd_read (buf, to_read, arelt) != to_read)
575
0
      {
576
0
        free (buf);
577
0
        return false;
578
0
      }
579
580
708
    size -= to_read;
581
582
708
    if (to_read < block_size)
583
287
      memset (buf + to_read, 0, block_size - to_read);
584
585
708
    if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
586
0
      {
587
0
        free (buf);
588
0
        return false;
589
0
      }
590
591
    /* Write file contents into allocated block.  */
592
593
708
    if (bfd_write (buf, block_size, abfd) != block_size)
594
0
      {
595
0
        free (buf);
596
0
        return false;
597
0
      }
598
599
708
    if (bfd_seek
600
708
        (abfd, (block * block_size) + block_size - left, SEEK_SET))
601
0
      {
602
0
        free (buf);
603
0
        return false;
604
0
      }
605
708
  }
606
607
522
      arelt = arelt->archive_next;
608
522
    }
609
610
37
  memset (buf, 0, left);
611
612
37
  if (bfd_write (buf, left, abfd) != left)
613
0
    {
614
0
      free (buf);
615
0
      return false;
616
0
    }
617
618
37
  free (buf);
619
620
37
  return true;
621
37
}
622
623
static bool
624
pdb_write_bitmap (bfd *abfd, uint32_t block_size, uint32_t num_blocks,
625
      uint32_t stream0_start)
626
37
{
627
37
  char *buf;
628
37
  uint32_t num_intervals = (num_blocks + block_size - 1) / block_size;
629
630
37
  buf = bfd_malloc (block_size);
631
37
  if (!buf)
632
0
    return false;
633
634
74
  for (uint32_t i = 0; i < num_intervals; i++)
635
37
    {
636
37
      if (bfd_seek (abfd, ((i * block_size) + 1) * block_size, SEEK_SET))
637
0
  {
638
0
    free (buf);
639
0
    return false;
640
0
  }
641
642
      /* All of our blocks are contiguous, making our free block map
643
   relatively simple.  0 = used, 1 = free.  */
644
645
37
      if (num_blocks >= 8)
646
20
  memset (buf, 0,
647
20
    (num_blocks / 8) >
648
20
    block_size ? block_size : (num_blocks / 8));
649
650
37
      if (num_blocks < block_size * 8)
651
37
  {
652
37
    unsigned int off = num_blocks / 8;
653
654
37
    if (num_blocks % 8)
655
33
      {
656
33
        buf[off] = 256 - (1 << (num_blocks % 8));
657
33
        off++;
658
33
      }
659
660
37
    if (off < block_size)
661
37
      memset (buf + off, 0xff, block_size - off);
662
37
  }
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
37
      if (i == 0 && abfd->archive_head)
670
32
  {
671
32
    bfd *arelt = abfd->archive_head;
672
32
    uint32_t stream0_blocks =
673
32
      (bfd_get_size (arelt) + block_size - 1) / block_size;
674
675
32
    if (stream0_start % 8)
676
17
      {
677
17
        unsigned int high_bit;
678
679
17
        high_bit = (stream0_start % 8) + stream0_blocks;
680
17
        if (high_bit > 8)
681
5
    high_bit = 8;
682
683
17
        buf[stream0_start / 8] |=
684
17
    (1 << high_bit) - (1 << (stream0_start % 8));
685
686
17
        stream0_blocks -= high_bit - (stream0_start % 8);
687
17
        stream0_start += high_bit - (stream0_start % 8);
688
17
      }
689
690
32
    memset (buf + (stream0_start / 8), 0xff, stream0_blocks / 8);
691
32
    stream0_start += stream0_blocks / 8;
692
32
    stream0_blocks %= 8;
693
694
32
    if (stream0_blocks > 0)
695
4
      buf[stream0_start / 8] |= (1 << stream0_blocks) - 1;
696
32
  }
697
698
37
      if (num_blocks < block_size * 8)
699
37
  num_blocks = 0;
700
0
      else
701
0
  num_blocks -= block_size * 8;
702
703
37
      if (bfd_write (buf, block_size, abfd) != block_size)
704
0
  return false;
705
37
    }
706
707
37
  free (buf);
708
709
37
  return true;
710
37
}
711
712
static bool
713
pdb_write_contents (bfd *abfd)
714
37
{
715
37
  char tmp[sizeof (uint32_t)];
716
37
  const uint32_t block_size = 0x400;
717
37
  uint32_t block_map_addr;
718
37
  uint32_t num_blocks;
719
37
  uint32_t num_files = 0;
720
37
  uint32_t num_directory_bytes = sizeof (uint32_t);
721
37
  uint32_t stream0_start = 0;
722
37
  bfd *arelt;
723
724
37
  if (bfd_write (pdb_magic, sizeof (pdb_magic), abfd) != sizeof (pdb_magic))
725
0
    return false;
726
727
37
  bfd_putl32 (block_size, tmp);
728
729
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
730
0
    return false;
731
732
37
  bfd_putl32 (1, tmp); /* Free block map block (always either 1 or 2).  */
733
734
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
735
0
    return false;
736
737
37
  arelt = abfd->archive_head;
738
739
559
  while (arelt)
740
522
    {
741
522
      uint32_t blocks_required =
742
522
  (bfd_get_size (arelt) + block_size - 1) / block_size;
743
744
522
      num_directory_bytes += sizeof (uint32_t); /* Size.  */
745
522
      num_directory_bytes += blocks_required * sizeof (uint32_t); /* Blocks.  */
746
747
522
      num_files++;
748
749
522
      arelt = arelt->archive_next;
750
522
    }
751
752
  /* Superblock plus two bitmap blocks.  */
753
37
  num_blocks = 3;
754
755
  /* Skip num_blocks for now.  */
756
37
  if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
757
0
    return false;
758
759
37
  bfd_putl32 (num_directory_bytes, tmp);
760
761
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
762
0
    return false;
763
764
  /* Skip unknown uint32_t (always 0?).  */
765
37
  if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
766
0
    return false;
767
768
37
  block_map_addr = pdb_allocate_block (&num_blocks, block_size);
769
770
37
  bfd_putl32 (block_map_addr, tmp);
771
772
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
773
0
    return false;
774
775
37
  if (!pdb_write_directory
776
37
      (abfd, block_size, num_files, block_map_addr, &num_blocks,
777
37
       &stream0_start))
778
0
    return false;
779
780
37
  if (!pdb_write_bitmap (abfd, block_size, num_blocks, stream0_start))
781
0
    return false;
782
783
  /* Write num_blocks now we know it.  */
784
785
37
  if (bfd_seek
786
37
      (abfd, sizeof (pdb_magic) + sizeof (uint32_t) + sizeof (uint32_t),
787
37
       SEEK_SET))
788
0
    return false;
789
790
37
  bfd_putl32 (num_blocks, tmp);
791
792
37
  if (bfd_write (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
793
0
    return false;
794
795
37
  return true;
796
37
}
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
};