Coverage Report

Created: 2026-09-14 08:07

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