1 /* Support for generating PDB CodeView debugging files.
2 Copyright (C) 2022 Free Software Foundation, Inc.
4 This file is part of the GNU Binutils.
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.
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.
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. */
26 #include "libiberty.h"
27 #include "coff/i386.h"
28 #include "coff/external.h"
29 #include "coff/internal.h"
44 /* Add a new stream to the PDB archive, and return its BFD. */
46 add_stream (bfd
*pdb
, const char *name
, uint16_t *stream_num
)
51 stream
= bfd_create (name
? name
: "", pdb
);
55 if (!bfd_make_writable (stream
))
61 if (!pdb
->archive_head
)
63 bfd_set_archive_head (pdb
, stream
);
68 bfd
*b
= pdb
->archive_head
;
72 while (b
->archive_next
)
78 b
->archive_next
= stream
;
87 /* Stream 0 ought to be a copy of the MSF directory from the last
88 time the PDB file was written. Because we don't do incremental
89 writes this isn't applicable to us, but we fill it with a dummy
90 value so as not to confuse radare. */
92 create_old_directory_stream (bfd
*pdb
)
95 char buf
[sizeof (uint32_t)];
97 stream
= add_stream (pdb
, NULL
, NULL
);
103 return bfd_bwrite (buf
, sizeof (uint32_t), stream
) == sizeof (uint32_t);
106 /* Calculate the hash of a given string. */
108 calc_hash (const char *data
, size_t len
)
115 hash
^= data
[1] << 8;
116 hash
^= data
[2] << 16;
117 hash
^= data
[3] << 24;
126 hash
^= data
[1] << 8;
136 hash
^= (hash
>> 11);
138 return hash
^ (hash
>> 16);
141 /* Stream 1 is the PDB info stream - see
142 https://llvm.org/docs/PDB/PdbStream.html. */
144 populate_info_stream (bfd
*pdb
, bfd
*info_stream
, const unsigned char *guid
)
147 struct pdb_stream_70 h
;
148 uint32_t num_entries
, num_buckets
;
149 uint32_t names_length
, stream_num
;
150 char int_buf
[sizeof (uint32_t)];
158 struct hash_entry
**buckets
= NULL
;
162 bfd_putl32 (PDB_STREAM_VERSION_VC70
, &h
.version
);
163 bfd_putl32 (time (NULL
), &h
.signature
);
164 bfd_putl32 (1, &h
.age
);
166 bfd_putl32 (bfd_getb32 (guid
), h
.guid
);
167 bfd_putl16 (bfd_getb16 (&guid
[4]), &h
.guid
[4]);
168 bfd_putl16 (bfd_getb16 (&guid
[6]), &h
.guid
[6]);
169 memcpy (&h
.guid
[8], &guid
[8], 8);
171 if (bfd_bwrite (&h
, sizeof (h
), info_stream
) != sizeof (h
))
174 /* Write hash list of named streams. This is a "rollover" hash, i.e.
175 if a bucket is filled an entry gets placed in the next free
179 for (bfd
*b
= pdb
->archive_head
; b
; b
= b
->archive_next
)
181 if (strcmp (b
->filename
, ""))
185 num_buckets
= num_entries
* 2;
192 buckets
= xmalloc (sizeof (struct hash_entry
*) * num_buckets
);
193 memset (buckets
, 0, sizeof (struct hash_entry
*) * num_buckets
);
195 for (bfd
*b
= pdb
->archive_head
; b
; b
= b
->archive_next
)
197 if (strcmp (b
->filename
, ""))
199 size_t len
= strlen (b
->filename
);
200 uint32_t hash
= (uint16_t) calc_hash (b
->filename
, len
);
201 uint32_t bucket_num
= hash
% num_buckets
;
203 while (buckets
[bucket_num
])
207 if (bucket_num
== num_buckets
)
211 buckets
[bucket_num
] = xmalloc (sizeof (struct hash_entry
));
213 buckets
[bucket_num
]->offset
= names_length
;
214 buckets
[bucket_num
]->value
= stream_num
;
216 names_length
+= len
+ 1;
223 /* Write the strings list - the hash keys are indexes into this. */
225 bfd_putl32 (names_length
, int_buf
);
227 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
231 for (bfd
*b
= pdb
->archive_head
; b
; b
= b
->archive_next
)
233 if (!strcmp (b
->filename
, ""))
236 size_t len
= strlen (b
->filename
) + 1;
238 if (bfd_bwrite (b
->filename
, len
, info_stream
) != len
)
242 /* Write the number of entries and buckets. */
244 bfd_putl32 (num_entries
, int_buf
);
246 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
250 bfd_putl32 (num_buckets
, int_buf
);
252 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
256 /* Write the present bitmap. */
258 bfd_putl32 ((num_buckets
+ 31) / 32, int_buf
);
260 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
264 for (unsigned int i
= 0; i
< num_buckets
; i
+= 32)
268 for (unsigned int j
= 0; j
< 32; j
++)
270 if (i
+ j
>= num_buckets
)
277 bfd_putl32 (v
, int_buf
);
279 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
284 /* Write the (empty) deleted bitmap. */
286 bfd_putl32 (0, int_buf
);
288 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
292 /* Write the buckets. */
294 for (unsigned int i
= 0; i
< num_buckets
; i
++)
298 bfd_putl32 (buckets
[i
]->offset
, int_buf
);
300 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
304 bfd_putl32 (buckets
[i
]->value
, int_buf
);
306 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
312 bfd_putl32 (0, int_buf
);
314 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
318 bfd_putl32 (PDB_STREAM_VERSION_VC140
, int_buf
);
320 if (bfd_bwrite (int_buf
, sizeof (uint32_t), info_stream
) !=
327 for (unsigned int i
= 0; i
< num_buckets
; i
++)
338 /* Stream 2 is the type information (TPI) stream, and stream 4 is
339 the ID information (IPI) stream. They differ only in which records
340 go in which stream. */
342 create_type_stream (bfd
*pdb
)
345 struct pdb_tpi_stream_header h
;
347 stream
= add_stream (pdb
, NULL
, NULL
);
351 bfd_putl32 (TPI_STREAM_VERSION_80
, &h
.version
);
352 bfd_putl32 (sizeof (h
), &h
.header_size
);
353 bfd_putl32 (TPI_FIRST_INDEX
, &h
.type_index_begin
);
354 bfd_putl32 (TPI_FIRST_INDEX
, &h
.type_index_end
);
355 bfd_putl32 (0, &h
.type_record_bytes
);
356 bfd_putl16 (0xffff, &h
.hash_stream_index
);
357 bfd_putl16 (0xffff, &h
.hash_aux_stream_index
);
358 bfd_putl32 (4, &h
.hash_key_size
);
359 bfd_putl32 (0x3ffff, &h
.num_hash_buckets
);
360 bfd_putl32 (0, &h
.hash_value_buffer_offset
);
361 bfd_putl32 (0, &h
.hash_value_buffer_length
);
362 bfd_putl32 (0, &h
.index_offset_buffer_offset
);
363 bfd_putl32 (0, &h
.index_offset_buffer_length
);
364 bfd_putl32 (0, &h
.hash_adj_buffer_offset
);
365 bfd_putl32 (0, &h
.hash_adj_buffer_length
);
367 if (bfd_bwrite (&h
, sizeof (h
), stream
) != sizeof (h
))
373 /* Return the PE architecture number for the image. */
375 get_arch_number (bfd
*abfd
)
377 if (abfd
->arch_info
->arch
!= bfd_arch_i386
)
380 if (abfd
->arch_info
->mach
& bfd_mach_x86_64
)
381 return IMAGE_FILE_MACHINE_AMD64
;
383 return IMAGE_FILE_MACHINE_I386
;
386 /* Stream 4 is the debug information (DBI) stream. */
388 populate_dbi_stream (bfd
*stream
, bfd
*abfd
)
390 struct pdb_dbi_stream_header h
;
391 struct optional_dbg_header opt
;
393 bfd_putl32 (0xffffffff, &h
.version_signature
);
394 bfd_putl32 (DBI_STREAM_VERSION_70
, &h
.version_header
);
395 bfd_putl32 (1, &h
.age
);
396 bfd_putl16 (0xffff, &h
.global_stream_index
);
397 bfd_putl16 (0x8e1d, &h
.build_number
); // MSVC 14.29
398 bfd_putl16 (0xffff, &h
.public_stream_index
);
399 bfd_putl16 (0, &h
.pdb_dll_version
);
400 bfd_putl16 (0xffff, &h
.sym_record_stream
);
401 bfd_putl16 (0, &h
.pdb_dll_rbld
);
402 bfd_putl32 (0, &h
.mod_info_size
);
403 bfd_putl32 (0, &h
.section_contribution_size
);
404 bfd_putl32 (0, &h
.section_map_size
);
405 bfd_putl32 (0, &h
.source_info_size
);
406 bfd_putl32 (0, &h
.type_server_map_size
);
407 bfd_putl32 (0, &h
.mfc_type_server_index
);
408 bfd_putl32 (sizeof (opt
), &h
.optional_dbg_header_size
);
409 bfd_putl32 (0, &h
.ec_substream_size
);
410 bfd_putl16 (0, &h
.flags
);
411 bfd_putl16 (get_arch_number (abfd
), &h
.machine
);
412 bfd_putl32 (0, &h
.padding
);
414 if (bfd_bwrite (&h
, sizeof (h
), stream
) != sizeof (h
))
417 bfd_putl16 (0xffff, &opt
.fpo_stream
);
418 bfd_putl16 (0xffff, &opt
.exception_stream
);
419 bfd_putl16 (0xffff, &opt
.fixup_stream
);
420 bfd_putl16 (0xffff, &opt
.omap_to_src_stream
);
421 bfd_putl16 (0xffff, &opt
.omap_from_src_stream
);
422 bfd_putl16 (0xffff, &opt
.section_header_stream
);
423 bfd_putl16 (0xffff, &opt
.token_map_stream
);
424 bfd_putl16 (0xffff, &opt
.xdata_stream
);
425 bfd_putl16 (0xffff, &opt
.pdata_stream
);
426 bfd_putl16 (0xffff, &opt
.new_fpo_stream
);
427 bfd_putl16 (0xffff, &opt
.orig_section_header_stream
);
429 if (bfd_bwrite (&opt
, sizeof (opt
), stream
) != sizeof (opt
))
435 /* Create a PDB debugging file for the PE image file abfd with the build ID
436 guid, stored at pdb_name. */
438 create_pdb_file (bfd
*abfd
, const char *pdb_name
, const unsigned char *guid
)
442 bfd
*info_stream
, *dbi_stream
, *names_stream
;
444 pdb
= bfd_openw (pdb_name
, "pdb");
447 einfo (_("%P: warning: cannot create PDB file: %s\n"),
448 bfd_errmsg (bfd_get_error ()));
452 bfd_set_format (pdb
, bfd_archive
);
454 if (!create_old_directory_stream (pdb
))
456 einfo (_("%P: warning: cannot create old directory stream "
457 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
461 info_stream
= add_stream (pdb
, NULL
, NULL
);
465 einfo (_("%P: warning: cannot create info stream "
466 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
470 if (!create_type_stream (pdb
))
472 einfo (_("%P: warning: cannot create TPI stream "
473 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
477 dbi_stream
= add_stream (pdb
, NULL
, NULL
);
481 einfo (_("%P: warning: cannot create DBI stream "
482 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
486 if (!create_type_stream (pdb
))
488 einfo (_("%P: warning: cannot create IPI stream "
489 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
493 names_stream
= add_stream (pdb
, "/names", NULL
);
497 einfo (_("%P: warning: cannot create /names stream "
498 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
502 if (!populate_dbi_stream (dbi_stream
, abfd
))
504 einfo (_("%P: warning: cannot populate DBI stream "
505 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));
509 if (!populate_info_stream (pdb
, info_stream
, guid
))
511 einfo (_("%P: warning: cannot populate info stream "
512 "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ()));