public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add pdb archive target
@ 2022-07-25 23:44 Mark Harmstone
  2022-08-11 13:02 ` Jan Beulich
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Harmstone @ 2022-07-25 23:44 UTC (permalink / raw)
  To: binutils; +Cc: Mark Harmstone

This adds support for the "Multi-Stream Format" container format that
MSVC uses for its PDB debugging files, as documented at
https://llvm.org/docs/PDB/MsfFile.html.

This is a prerequisite for gdb to be able to read Microsoft's debug
files, and for gcc and ld to generate debugging info that can be read by
Microsoft's tools.

---
 bfd/Makefile.am                          |   2 +
 bfd/Makefile.in                          |   3 +
 bfd/config.bfd                           |   6 +-
 bfd/configure                            |   3 +-
 bfd/configure.ac                         |   3 +-
 bfd/pdb.c                                | 804 +++++++++++++++++++++++
 bfd/targets.c                            |   3 +
 binutils/testsuite/binutils-all/pdb.exp  | 157 +++++
 binutils/testsuite/binutils-all/pdb1.d   | 388 +++++++++++
 binutils/testsuite/binutils-all/pdb2.d   | 388 +++++++++++
 binutils/testsuite/binutils-all/pdb3.d   | 516 +++++++++++++++
 binutils/testsuite/binutils-all/pdbfile1 |   1 +
 binutils/testsuite/binutils-all/pdbfile2 |   1 +
 13 files changed, 2270 insertions(+), 5 deletions(-)
 create mode 100644 bfd/pdb.c
 create mode 100644 binutils/testsuite/binutils-all/pdb.exp
 create mode 100644 binutils/testsuite/binutils-all/pdb1.d
 create mode 100644 binutils/testsuite/binutils-all/pdb2.d
 create mode 100644 binutils/testsuite/binutils-all/pdb3.d
 create mode 100644 binutils/testsuite/binutils-all/pdbfile1
 create mode 100644 binutils/testsuite/binutils-all/pdbfile2

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 10dd765bec8..d59efcdcea8 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -367,6 +367,7 @@ BFD32_BACKENDS = \
 	mach-o-arm.lo \
 	ns32knetbsd.lo \
 	pc532-mach.lo \
+	pdb.lo \
 	pdp11.lo \
 	pe-arm-wince.lo \
 	pe-arm.lo \
@@ -500,6 +501,7 @@ BFD32_BACKENDS_CFILES = \
 	mach-o-arm.c \
 	ns32knetbsd.c \
 	pc532-mach.c \
+	pdb.c \
 	pdp11.c \
 	pe-arm-wince.c \
 	pe-arm.c \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index f5313a2ad6f..aaa93b5589f 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -794,6 +794,7 @@ BFD32_BACKENDS = \
 	mach-o-arm.lo \
 	ns32knetbsd.lo \
 	pc532-mach.lo \
+	pdb.lo \
 	pdp11.lo \
 	pe-arm-wince.lo \
 	pe-arm.lo \
@@ -927,6 +928,7 @@ BFD32_BACKENDS_CFILES = \
 	mach-o-arm.c \
 	ns32knetbsd.c \
 	pc532-mach.c \
+	pdb.c \
 	pdp11.c \
 	pe-arm-wince.c \
 	pe-arm.c \
@@ -1574,6 +1576,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opncls.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osf-core.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pc532-mach.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-aarch64igen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@
diff --git a/bfd/config.bfd b/bfd/config.bfd
index cfe58247882..806b92dd176 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -388,7 +388,7 @@ case "${targ}" in
     ;;
   arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*)
     targ_defvec=arm_pe_wince_le_vec
-    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec"
+    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec pdb_vec"
     targ_underscore=no
     targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX"
     ;;
@@ -708,7 +708,7 @@ case "${targ}" in
     ;;
   x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin)
     targ_defvec=x86_64_pe_vec
-    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
+    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec pdb_vec"
     want64=true
     targ_underscore=no
     ;;
@@ -761,7 +761,7 @@ case "${targ}" in
     ;;
   i[3-7]86-*-mingw32* | i[3-7]86-*-cygwin* | i[3-7]86-*-winnt | i[3-7]86-*-pe)
     targ_defvec=i386_pe_vec
-    targ_selvecs="i386_pe_vec i386_pe_big_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
+    targ_selvecs="i386_pe_vec i386_pe_big_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec pdb_vec"
     targ_underscore=yes
     ;;
   i[3-7]86-*-vxworks*)
diff --git a/bfd/configure b/bfd/configure
index b23c9eebfd7..13e3779dec7 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13337,7 +13337,7 @@ tb=
 
 elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo
      dwarf1.lo dwarf2.lo"
-coffgen="coffgen.lo dwarf2.lo"
+coffgen="coffgen.lo dwarf2.lo pdb.lo"
 coff="cofflink.lo $coffgen"
 ecoff="ecofflink.lo $coffgen"
 xcoff="xcofflink.lo $coffgen"
@@ -13516,6 +13516,7 @@ do
     ns32k_aout_pc532mach_vec)	 tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
     ns32k_aout_pc532nbsd_vec)	 tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
     or1k_elf32_vec)		 tb="$tb elf32-or1k.lo elf32.lo $elf" ;;
+    pdb_vec)			 tb="$tb pdb.lo" ;;
     pdp11_aout_vec)		 tb="$tb pdp11.lo" ;;
     pef_vec)			 tb="$tb pef.lo" ;;
     pef_xlib_vec)		 tb="$tb pef.lo" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index a9078965c40..19d6ce154a2 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -416,7 +416,7 @@ tb=
 
 elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo
      dwarf1.lo dwarf2.lo"
-coffgen="coffgen.lo dwarf2.lo"
+coffgen="coffgen.lo dwarf2.lo pdb.lo"
 coff="cofflink.lo $coffgen"
 ecoff="ecofflink.lo $coffgen"
 xcoff="xcofflink.lo $coffgen"
@@ -595,6 +595,7 @@ do
     ns32k_aout_pc532mach_vec)	 tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
     ns32k_aout_pc532nbsd_vec)	 tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
     or1k_elf32_vec)		 tb="$tb elf32-or1k.lo elf32.lo $elf" ;;
+    pdb_vec)			 tb="$tb pdb.lo" ;;
     pdp11_aout_vec)		 tb="$tb pdp11.lo" ;;
     pef_vec)			 tb="$tb pef.lo" ;;
     pef_xlib_vec)		 tb="$tb pef.lo" ;;
diff --git a/bfd/pdb.c b/bfd/pdb.c
new file mode 100644
index 00000000000..4cc79e707f1
--- /dev/null
+++ b/bfd/pdb.c
@@ -0,0 +1,804 @@
+/* BFD back-end for PDB Multi-Stream Format archives.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA. */
+
+/* This describes the MSF file archive format, which is used for the
+   PDB debug info generated by MSVC. See https://llvm.org/docs/PDB/MsfFile.html
+   for a full description of the format. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0\0" */
+static const uint8_t pdb_magic[] =
+{ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
+  0x74, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, 0x20,
+  0x4d, 0x53, 0x46, 0x20, 0x37, 0x2e, 0x30, 0x30,
+  0x0d, 0x0a, 0x1a, 0x44, 0x53, 0x00, 0x00, 0x00 };
+
+#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
+
+static bfd_cleanup
+pdb_archive_p (bfd *abfd)
+{
+  int ret;
+  char magic[sizeof (pdb_magic)];
+
+  ret = bfd_bread (magic, sizeof (magic), abfd);
+  if (ret != sizeof (magic))
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  if (memcmp (magic, pdb_magic, sizeof (magic)))
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  return _bfd_no_cleanup;
+}
+
+static bfd *
+pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
+{
+  char int_buf[sizeof (uint32_t)];
+  uint32_t block_size, block_map_addr, block, num_files;
+  uint32_t first_dir_block, dir_offset, file_size, block_off, left;
+  char name[10];
+  bfd *file;
+  char *buf;
+
+  /* get block_size */
+
+  if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
+    return NULL;
+
+  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
+  block_size = bfd_getl32 (int_buf);
+
+  /* get block_map_addr */
+
+  if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
+    return NULL;
+
+  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
+  block_map_addr = bfd_getl32 (int_buf);
+
+  /* get num_files */
+
+  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
+    return NULL;
+
+  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
+  first_dir_block = bfd_getl32 (int_buf);
+
+  if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
+    return NULL;
+
+  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
+  num_files = bfd_getl32 (int_buf);
+
+  if (sym_index >= num_files)
+    {
+      bfd_set_error (bfd_error_no_more_archived_files);
+      return NULL;
+    }
+
+  /* read file size */
+
+  dir_offset = sizeof (uint32_t) * (sym_index + 1);
+
+  if (dir_offset >= block_size)
+    {
+      uint32_t block_map_addr_off;
+
+      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
+
+      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
+		    SEEK_SET))
+	return NULL;
+
+      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	{
+	  bfd_set_error (bfd_error_malformed_archive);
+	  return NULL;
+	}
+
+      block = bfd_getl32 (int_buf);
+    }
+  else
+    {
+      block = first_dir_block;
+    }
+
+  if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
+		SEEK_SET))
+    return NULL;
+
+  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    {
+      bfd_set_error (bfd_error_malformed_archive);
+      return NULL;
+    }
+
+  file_size = bfd_getl32 (int_buf);
+
+  /* create BFD */
+
+  sprintf (name, "%04lx", sym_index);
+
+  file = bfd_create (name, abfd);
+
+  if (!file)
+    return NULL;
+
+  if (!bfd_make_writable (file))
+    goto fail;
+
+  file->arelt_data =
+    (struct areltdata *) bfd_malloc (sizeof (struct areltdata));
+
+  if (!file->arelt_data)
+    goto fail;
+
+  arch_eltdata (file)->parsed_size = file_size;
+  arch_eltdata (file)->key = sym_index;
+
+  if (file_size == 0)
+    return file;
+
+  block_off = 0;
+
+  /* sum number of blocks in previous files */
+
+  if (sym_index != 0)
+    {
+      dir_offset = sizeof (uint32_t);
+
+      if (bfd_seek (abfd, (first_dir_block * block_size) + sizeof (uint32_t),
+		    SEEK_SET))
+	goto fail;
+
+      for (symindex i = 0; i < sym_index; i++)
+	{
+	  uint32_t size, num_blocks;
+
+	  if ((dir_offset % block_size) == 0)
+	    {
+	      uint32_t block_map_addr_off;
+
+	      block_map_addr_off =
+		((dir_offset / block_size) * sizeof (uint32_t));
+
+	      if (bfd_seek
+		  (abfd, (block_map_addr * block_size) + block_map_addr_off,
+		   SEEK_SET))
+		goto fail;
+
+	      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
+		  sizeof (uint32_t))
+		{
+		  bfd_set_error (bfd_error_malformed_archive);
+		  goto fail;
+		}
+
+	      block = bfd_getl32 (int_buf);
+
+	      if (bfd_seek (abfd, block * block_size, SEEK_SET))
+		goto fail;
+	    }
+
+	  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
+	      sizeof (uint32_t))
+	    {
+	      bfd_set_error (bfd_error_malformed_archive);
+	      goto fail;
+	    }
+
+	  size = bfd_getl32 (int_buf);
+	  num_blocks = (size + block_size - 1) / block_size;
+	  block_off += num_blocks;
+
+	  dir_offset += sizeof (uint32_t);
+	}
+    }
+
+  /* read blocks, and write into new BFD */
+
+  dir_offset = sizeof (uint32_t) * (num_files + block_off + 1);
+
+  if (dir_offset >= block_size)
+    {
+      uint32_t block_map_addr_off;
+
+      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
+
+      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
+		    SEEK_SET))
+	goto fail;
+
+      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	{
+	  bfd_set_error (bfd_error_malformed_archive);
+	  goto fail;
+	}
+
+      block = bfd_getl32 (int_buf);
+    }
+  else
+    {
+      block = first_dir_block;
+    }
+
+  buf = bfd_malloc (block_size);
+  if (!buf)
+    goto fail;
+
+  left = file_size;
+  do
+    {
+      uint32_t file_block, to_read;
+
+      if ((dir_offset % block_size) == 0 && left != file_size)
+	{
+	  uint32_t block_map_addr_off;
+
+	  block_map_addr_off =
+	    ((dir_offset / block_size) * sizeof (uint32_t));
+
+	  if (bfd_seek
+	      (abfd, (block_map_addr * block_size) + block_map_addr_off,
+	       SEEK_SET))
+	    goto fail2;
+
+	  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) !=
+	      sizeof (uint32_t))
+	    {
+	      bfd_set_error (bfd_error_malformed_archive);
+	      goto fail2;
+	    }
+
+	  block = bfd_getl32 (int_buf);
+	}
+
+      if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
+		    SEEK_SET))
+	goto fail2;
+
+      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	{
+	  bfd_set_error (bfd_error_malformed_archive);
+	  goto fail2;
+	}
+
+      file_block = bfd_getl32 (int_buf);
+
+      if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
+	goto fail2;
+
+      to_read = left > block_size ? block_size : left;
+
+      if (bfd_bread (buf, to_read, abfd) != to_read)
+	{
+	  bfd_set_error (bfd_error_malformed_archive);
+	  goto fail2;
+	}
+
+      if (bfd_bwrite (buf, to_read, file) != to_read)
+	goto fail2;
+
+      if (left > block_size)
+	left -= block_size;
+      else
+	break;
+
+      dir_offset += sizeof (uint32_t);
+    }
+  while (left > 0);
+
+  free (buf);
+
+  return file;
+
+fail2:
+  free (buf);
+
+fail:
+  bfd_close (file);
+  return NULL;
+}
+
+static bfd *
+pdb_openr_next_archived_file (bfd *archive, bfd *last_file)
+{
+  if (!last_file)
+    return pdb_get_elt_at_index (archive, 0);
+  else
+    return pdb_get_elt_at_index (archive, arch_eltdata (last_file)->key + 1);
+}
+
+static int
+pdb_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
+{
+  buf->st_mtime = 0;
+  buf->st_uid = 0;
+  buf->st_gid = 0;
+  buf->st_mode = 0644;
+  buf->st_size = arch_eltdata (abfd)->parsed_size;
+
+  return 0;
+}
+
+static uint32_t
+pdb_allocate_block (uint32_t *num_blocks, uint32_t block_size)
+{
+  uint32_t block;
+
+  block = *num_blocks;
+
+  (*num_blocks)++;
+
+  /* if new interval, skip two blocks for free space map */
+
+  if ((block % block_size) == 1)
+    {
+      block += 2;
+      (*num_blocks) += 2;
+    }
+
+  return block;
+}
+
+static bool
+pdb_write_directory (bfd *abfd, uint32_t block_size, uint32_t num_files,
+		     uint32_t block_map_addr, uint32_t * num_blocks)
+{
+  char tmp[sizeof (uint32_t)];
+  uint32_t block, left, block_map_off;
+  bfd *arelt;
+  char *buf;
+
+  /* allocate first block for directory */
+
+  block = pdb_allocate_block (num_blocks, block_size);
+  left = block_size;
+
+  /* write allocated block no. at beginning of block map */
+
+  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
+    return false;
+
+  bfd_putl32 (block, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  block_map_off = sizeof (uint32_t);
+
+  /* write num_files at beginning of directory */
+
+  if (bfd_seek (abfd, block * block_size, SEEK_SET))
+    return false;
+
+  bfd_putl32 (num_files, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  left -= sizeof (uint32_t);
+
+  /* write file sizes */
+
+  arelt = abfd->archive_head;
+  while (arelt)
+    {
+      if (left == 0)
+	{
+	  if (block_map_off == block_size) /* too many blocks */
+	    {
+	      bfd_set_error (bfd_error_invalid_operation);
+	      return false;
+	    }
+
+	  block = pdb_allocate_block (num_blocks, block_size);
+	  left = block_size;
+
+	  if (bfd_seek
+	      (abfd, (block_map_addr * block_size) + block_map_off, SEEK_SET))
+	    return false;
+
+	  bfd_putl32 (block, tmp);
+
+	  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	    return false;
+
+	  block_map_off += sizeof (uint32_t);
+
+	  if (bfd_seek (abfd, block * block_size, SEEK_SET))
+	    return false;
+	}
+
+      bfd_putl32 (bfd_get_size (arelt), tmp);
+
+      if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	return false;
+
+      left -= sizeof (uint32_t);
+
+      arelt = arelt->archive_next;
+    }
+
+  /* write blocks */
+
+  buf = bfd_malloc (block_size);
+  if (!buf)
+    return false;
+
+  arelt = abfd->archive_head;
+  while (arelt)
+    {
+      ufile_ptr size = bfd_get_size (arelt);
+      uint32_t req_blocks = (size + block_size - 1) / block_size;
+
+      if (bfd_seek (arelt, 0, SEEK_SET))
+	{
+	  free (buf);
+	  return false;
+	}
+
+      for (uint32_t i = 0; i < req_blocks; i++)
+	{
+	  uint32_t file_block, to_read;
+
+	  if (left == 0)
+	    {
+	      if (block_map_off == block_size) /* too many blocks */
+		{
+		  bfd_set_error (bfd_error_invalid_operation);
+		  free (buf);
+		  return false;
+		}
+
+	      block = pdb_allocate_block (num_blocks, block_size);
+	      left = block_size;
+
+	      if (bfd_seek
+		  (abfd, (block_map_addr * block_size) + block_map_off,
+		   SEEK_SET))
+		{
+		  free (buf);
+		  return false;
+		}
+
+	      bfd_putl32 (block, tmp);
+
+	      if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) !=
+		  sizeof (uint32_t))
+		{
+		  free (buf);
+		  return false;
+		}
+
+	      block_map_off += sizeof (uint32_t);
+
+	      if (bfd_seek (abfd, block * block_size, SEEK_SET))
+		{
+		  free (buf);
+		  return false;
+		}
+	    }
+
+	  /* allocate block and write number into directory */
+
+	  file_block = pdb_allocate_block (num_blocks, block_size);
+
+	  bfd_putl32 (file_block, tmp);
+
+	  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+	    {
+	      free (buf);
+	      return false;
+	    }
+
+	  left -= sizeof (uint32_t);
+
+	  /* read file contents into buffer */
+
+	  to_read = size > block_size ? block_size : size;
+
+	  if (bfd_bread (buf, to_read, arelt) != to_read)
+	    {
+	      free (buf);
+	      return false;
+	    }
+
+	  size -= to_read;
+
+	  if (to_read < block_size)
+	    memset (buf + to_read, 0, block_size - to_read);
+
+	  if (bfd_seek (abfd, file_block * block_size, SEEK_SET))
+	    {
+	      free (buf);
+	      return false;
+	    }
+
+	  /* write file contents into allocated block */
+
+	  if (bfd_bwrite (buf, block_size, abfd) != block_size)
+	    {
+	      free (buf);
+	      return false;
+	    }
+
+	  if (bfd_seek
+	      (abfd, (block * block_size) + block_size - left, SEEK_SET))
+	    {
+	      free (buf);
+	      return false;
+	    }
+	}
+
+      arelt = arelt->archive_next;
+    }
+
+  memset (buf, 0, left);
+
+  if (bfd_bwrite (buf, left, abfd) != left)
+    {
+      free (buf);
+      return false;
+    }
+
+  free (buf);
+
+  return true;
+}
+
+static bool
+pdb_write_bitmap (bfd *abfd, uint32_t block_size, uint32_t num_blocks)
+{
+  char *buf;
+  uint32_t num_intervals = (num_blocks + block_size - 1) / block_size;
+
+  buf = bfd_malloc (block_size);
+  if (!buf)
+    return false;
+
+  num_blocks--;			/* superblock not included */
+
+  for (uint32_t i = 0; i < num_intervals; i++)
+    {
+      if (bfd_seek (abfd, ((i * block_size) + 1) * block_size, SEEK_SET))
+	{
+	  free (buf);
+	  return false;
+	}
+
+      /* All of our blocks are contiguous, making our free block map simple
+       * 0 = used, 1 = free */
+
+      if (num_blocks >= 8)
+	memset (buf, 0,
+		(num_blocks / 8) >
+		block_size ? block_size : (num_blocks / 8));
+
+      if (num_blocks < block_size * 8)
+	{
+	  unsigned int off = num_blocks / 8;
+
+	  if (num_blocks % 8)
+	    {
+	      buf[off] = (1 << (8 - (num_blocks % 8))) - 1;
+	      off++;
+	    }
+
+	  if (off < block_size)
+	    memset (buf + off, 0xff, block_size - off);
+	}
+
+      if (num_blocks < block_size * 8)
+	num_blocks = 0;
+      else
+	num_blocks -= block_size * 8;
+
+      if (bfd_bwrite (buf, block_size, abfd) != block_size)
+	return false;
+    }
+
+  free (buf);
+
+  return true;
+}
+
+static bool
+pdb_write_contents (bfd *abfd)
+{
+  char tmp[sizeof (uint32_t)];
+  const uint32_t block_size = 0x400;
+  uint32_t block_map_addr;
+  uint32_t num_blocks;
+  uint32_t num_files = 0;
+  uint32_t num_directory_bytes = sizeof (uint32_t);
+  bfd *arelt;
+
+  if (bfd_bwrite (pdb_magic, sizeof (pdb_magic), abfd) != sizeof (pdb_magic))
+    return false;
+
+  bfd_putl32 (block_size, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  bfd_putl32 (1, tmp); /* free block map block (always either 1 or 2) */
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  arelt = abfd->archive_head;
+
+  while (arelt)
+    {
+      uint32_t blocks_required =
+	(bfd_get_size (arelt) + block_size - 1) / block_size;
+
+      num_directory_bytes += sizeof (uint32_t); /* size */
+      num_directory_bytes += blocks_required * sizeof (uint32_t); /* blocks */
+
+      num_files++;
+
+      arelt = arelt->archive_next;
+    }
+
+  /* superblock plus two bitmap blocks */
+  num_blocks = 3;
+
+  /* skip num_blocks for now */
+  if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
+    return false;
+
+  bfd_putl32 (num_directory_bytes, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  /* skip unknown uint32_t (always 0?) */
+  if (bfd_seek (abfd, sizeof (uint32_t), SEEK_CUR))
+    return false;
+
+  block_map_addr = pdb_allocate_block (&num_blocks, block_size);
+
+  bfd_putl32 (block_map_addr, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  if (!pdb_write_directory
+      (abfd, block_size, num_files, block_map_addr, &num_blocks))
+    return false;
+
+  if (!pdb_write_bitmap (abfd, block_size, num_blocks))
+    return false;
+
+  /* write num_blocks now we know it */
+
+  if (bfd_seek
+      (abfd, sizeof (pdb_magic) + sizeof (uint32_t) + sizeof (uint32_t),
+       SEEK_SET))
+    return false;
+
+  bfd_putl32 (num_blocks, tmp);
+
+  if (bfd_bwrite (tmp, sizeof (uint32_t), abfd) != sizeof (uint32_t))
+    return false;
+
+  return true;
+}
+
+#define pdb_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define pdb_new_section_hook _bfd_generic_new_section_hook
+#define pdb_get_section_contents _bfd_generic_get_section_contents
+#define pdb_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define pdb_close_and_cleanup _bfd_bool_bfd_true
+
+#define pdb_slurp_armap _bfd_noarchive_slurp_armap
+#define pdb_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
+#define pdb_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
+#define pdb_truncate_arname _bfd_noarchive_truncate_arname
+#define pdb_write_armap _bfd_noarchive_write_armap
+#define pdb_read_ar_hdr _bfd_noarchive_read_ar_hdr
+#define pdb_write_ar_hdr _bfd_noarchive_write_ar_hdr
+#define pdb_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
+
+const bfd_target pdb_vec =
+{
+  "pdb",
+  bfd_target_unknown_flavour,
+  BFD_ENDIAN_LITTLE,		/* target byte order */
+  BFD_ENDIAN_LITTLE,		/* target headers byte order */
+  0,				/* object flags */
+  0,				/* section flags */
+  0,				/* leading underscore */
+  ' ',				/* ar_pad_char */
+  16,				/* ar_max_namelen */
+  0,				/* match priority.  */
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
+
+  {				/* bfd_check_format */
+    _bfd_dummy_target,
+    _bfd_dummy_target,
+    pdb_archive_p,
+    _bfd_dummy_target
+  },
+  {				/* bfd_set_format */
+    _bfd_bool_bfd_false_error,
+    _bfd_bool_bfd_false_error,
+    _bfd_bool_bfd_true,
+    _bfd_bool_bfd_false_error
+  },
+  {				/* bfd_write_contents */
+    _bfd_bool_bfd_true,
+    _bfd_bool_bfd_false_error,
+    pdb_write_contents,
+    _bfd_bool_bfd_false_error
+  },
+
+  BFD_JUMP_TABLE_GENERIC (pdb),
+  BFD_JUMP_TABLE_COPY (_bfd_generic),
+  BFD_JUMP_TABLE_CORE (_bfd_nocore),
+  BFD_JUMP_TABLE_ARCHIVE (pdb),
+  BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+  BFD_JUMP_TABLE_WRITE (_bfd_generic),
+  BFD_JUMP_TABLE_LINK (_bfd_nolink),
+  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  NULL,
+
+  NULL
+};
diff --git a/bfd/targets.c b/bfd/targets.c
index 18fec45f02a..a50e7bc6e4c 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -836,6 +836,7 @@ extern const bfd_target nios2_elf32_le_vec;
 extern const bfd_target ns32k_aout_pc532mach_vec;
 extern const bfd_target ns32k_aout_pc532nbsd_vec;
 extern const bfd_target or1k_elf32_vec;
+extern const bfd_target pdb_vec;
 extern const bfd_target pdp11_aout_vec;
 extern const bfd_target pef_vec;
 extern const bfd_target pef_xlib_vec;
@@ -1221,6 +1222,8 @@ static const bfd_target * const _bfd_target_vector[] =
 
 	&or1k_elf32_vec,
 
+	&pdb_vec,
+
 	&pdp11_aout_vec,
 
 	&pef_vec,
diff --git a/binutils/testsuite/binutils-all/pdb.exp b/binutils/testsuite/binutils-all/pdb.exp
new file mode 100644
index 00000000000..f4880ab05d2
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdb.exp
@@ -0,0 +1,157 @@
+#   Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+proc pdb_archive_1 { } {
+    global AR
+    global OBJDUMP
+    global srcdir
+    global subdir
+
+    set testname "pdb archive 1"
+
+    file delete tmpdir/test.pdb
+
+    # add short file (less than block size)
+
+    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile1"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "tv tmpdir/test.pdb"]
+    if ![string match "rw-r--r-- 0/0      3 *0000*" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
+    set exp [file_contents "$srcdir/$subdir/pdb1.d"]
+    if ![string equal $got $exp] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "x tmpdir/test.pdb 0000 --output=tmpdir"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [file_contents tmpdir/0000]
+    set exp [file_contents "$srcdir/$subdir/pdbfile1"]
+    if ![string equal $got $exp] {
+	fail $testname
+	return
+    }
+
+    pass $testname
+}
+
+proc pdb_archive_2 { } {
+    global AR
+    global OBJDUMP
+    global srcdir
+    global subdir
+
+    set testname "pdb archive 2"
+
+    # add empty file
+
+    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb /dev/null"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "tv tmpdir/test.pdb"]
+    if ![string match "*\nrw-r--r-- 0/0      0 *0001*" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
+    set exp [file_contents "$srcdir/$subdir/pdb2.d"]
+    if ![string equal $got $exp] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "x tmpdir/test.pdb 0001 --output=tmpdir"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [file_contents tmpdir/0001]
+    if ![string equal $got ""] {
+	fail $testname
+	return
+    }
+
+    pass $testname
+}
+
+proc pdb_archive_3 { } {
+    global AR
+    global OBJDUMP
+    global srcdir
+    global subdir
+
+    set testname "pdb archive 3"
+
+    # add long file (greater than block size)
+
+    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile2"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "tv tmpdir/test.pdb"]
+    if ![string match "*\nrw-r--r-- 0/0   1032 *0002*" $got] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
+    set exp [file_contents "$srcdir/$subdir/pdb3.d"]
+    if ![string equal $got $exp] {
+	fail $testname
+	return
+    }
+
+    set got [binutils_run $AR "x tmpdir/test.pdb 0002 --output=tmpdir"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    set got [file_contents tmpdir/0002]
+    set exp [file_contents "$srcdir/$subdir/pdbfile2"]
+    if ![string equal $got $exp] {
+	fail $testname
+	return
+    }
+
+    pass $testname
+}
+
+pdb_archive_1
+pdb_archive_2
+pdb_archive_3
diff --git a/binutils/testsuite/binutils-all/pdb1.d b/binutils/testsuite/binutils-all/pdb1.d
new file mode 100644
index 00000000000..8d3411e5c77
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdb1.d
@@ -0,0 +1,388 @@
+
+tmpdir/test.pdb:     file format binary
+
+Contents of section .data:
+ 0000 4d696372 6f736f66 7420432f 432b2b20  Microsoft C/C++ 
+ 0010 4d534620 372e3030 0d0a1a44 53000000  MSF 7.00...DS...
+ 0020 00040000 01000000 06000000 0c000000  ................
+ 0030 00000000 03000000 00000000 00000000  ................
+ 0040 00000000 00000000 00000000 00000000  ................
+ 0050 00000000 00000000 00000000 00000000  ................
+ 0060 00000000 00000000 00000000 00000000  ................
+ 0070 00000000 00000000 00000000 00000000  ................
+ 0080 00000000 00000000 00000000 00000000  ................
+ 0090 00000000 00000000 00000000 00000000  ................
+ 00a0 00000000 00000000 00000000 00000000  ................
+ 00b0 00000000 00000000 00000000 00000000  ................
+ 00c0 00000000 00000000 00000000 00000000  ................
+ 00d0 00000000 00000000 00000000 00000000  ................
+ 00e0 00000000 00000000 00000000 00000000  ................
+ 00f0 00000000 00000000 00000000 00000000  ................
+ 0100 00000000 00000000 00000000 00000000  ................
+ 0110 00000000 00000000 00000000 00000000  ................
+ 0120 00000000 00000000 00000000 00000000  ................
+ 0130 00000000 00000000 00000000 00000000  ................
+ 0140 00000000 00000000 00000000 00000000  ................
+ 0150 00000000 00000000 00000000 00000000  ................
+ 0160 00000000 00000000 00000000 00000000  ................
+ 0170 00000000 00000000 00000000 00000000  ................
+ 0180 00000000 00000000 00000000 00000000  ................
+ 0190 00000000 00000000 00000000 00000000  ................
+ 01a0 00000000 00000000 00000000 00000000  ................
+ 01b0 00000000 00000000 00000000 00000000  ................
+ 01c0 00000000 00000000 00000000 00000000  ................
+ 01d0 00000000 00000000 00000000 00000000  ................
+ 01e0 00000000 00000000 00000000 00000000  ................
+ 01f0 00000000 00000000 00000000 00000000  ................
+ 0200 00000000 00000000 00000000 00000000  ................
+ 0210 00000000 00000000 00000000 00000000  ................
+ 0220 00000000 00000000 00000000 00000000  ................
+ 0230 00000000 00000000 00000000 00000000  ................
+ 0240 00000000 00000000 00000000 00000000  ................
+ 0250 00000000 00000000 00000000 00000000  ................
+ 0260 00000000 00000000 00000000 00000000  ................
+ 0270 00000000 00000000 00000000 00000000  ................
+ 0280 00000000 00000000 00000000 00000000  ................
+ 0290 00000000 00000000 00000000 00000000  ................
+ 02a0 00000000 00000000 00000000 00000000  ................
+ 02b0 00000000 00000000 00000000 00000000  ................
+ 02c0 00000000 00000000 00000000 00000000  ................
+ 02d0 00000000 00000000 00000000 00000000  ................
+ 02e0 00000000 00000000 00000000 00000000  ................
+ 02f0 00000000 00000000 00000000 00000000  ................
+ 0300 00000000 00000000 00000000 00000000  ................
+ 0310 00000000 00000000 00000000 00000000  ................
+ 0320 00000000 00000000 00000000 00000000  ................
+ 0330 00000000 00000000 00000000 00000000  ................
+ 0340 00000000 00000000 00000000 00000000  ................
+ 0350 00000000 00000000 00000000 00000000  ................
+ 0360 00000000 00000000 00000000 00000000  ................
+ 0370 00000000 00000000 00000000 00000000  ................
+ 0380 00000000 00000000 00000000 00000000  ................
+ 0390 00000000 00000000 00000000 00000000  ................
+ 03a0 00000000 00000000 00000000 00000000  ................
+ 03b0 00000000 00000000 00000000 00000000  ................
+ 03c0 00000000 00000000 00000000 00000000  ................
+ 03d0 00000000 00000000 00000000 00000000  ................
+ 03e0 00000000 00000000 00000000 00000000  ................
+ 03f0 00000000 00000000 00000000 00000000  ................
+ 0400 07ffffff ffffffff ffffffff ffffffff  ................
+ 0410 ffffffff ffffffff ffffffff ffffffff  ................
+ 0420 ffffffff ffffffff ffffffff ffffffff  ................
+ 0430 ffffffff ffffffff ffffffff ffffffff  ................
+ 0440 ffffffff ffffffff ffffffff ffffffff  ................
+ 0450 ffffffff ffffffff ffffffff ffffffff  ................
+ 0460 ffffffff ffffffff ffffffff ffffffff  ................
+ 0470 ffffffff ffffffff ffffffff ffffffff  ................
+ 0480 ffffffff ffffffff ffffffff ffffffff  ................
+ 0490 ffffffff ffffffff ffffffff ffffffff  ................
+ 04a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0500 ffffffff ffffffff ffffffff ffffffff  ................
+ 0510 ffffffff ffffffff ffffffff ffffffff  ................
+ 0520 ffffffff ffffffff ffffffff ffffffff  ................
+ 0530 ffffffff ffffffff ffffffff ffffffff  ................
+ 0540 ffffffff ffffffff ffffffff ffffffff  ................
+ 0550 ffffffff ffffffff ffffffff ffffffff  ................
+ 0560 ffffffff ffffffff ffffffff ffffffff  ................
+ 0570 ffffffff ffffffff ffffffff ffffffff  ................
+ 0580 ffffffff ffffffff ffffffff ffffffff  ................
+ 0590 ffffffff ffffffff ffffffff ffffffff  ................
+ 05a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0600 ffffffff ffffffff ffffffff ffffffff  ................
+ 0610 ffffffff ffffffff ffffffff ffffffff  ................
+ 0620 ffffffff ffffffff ffffffff ffffffff  ................
+ 0630 ffffffff ffffffff ffffffff ffffffff  ................
+ 0640 ffffffff ffffffff ffffffff ffffffff  ................
+ 0650 ffffffff ffffffff ffffffff ffffffff  ................
+ 0660 ffffffff ffffffff ffffffff ffffffff  ................
+ 0670 ffffffff ffffffff ffffffff ffffffff  ................
+ 0680 ffffffff ffffffff ffffffff ffffffff  ................
+ 0690 ffffffff ffffffff ffffffff ffffffff  ................
+ 06a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0700 ffffffff ffffffff ffffffff ffffffff  ................
+ 0710 ffffffff ffffffff ffffffff ffffffff  ................
+ 0720 ffffffff ffffffff ffffffff ffffffff  ................
+ 0730 ffffffff ffffffff ffffffff ffffffff  ................
+ 0740 ffffffff ffffffff ffffffff ffffffff  ................
+ 0750 ffffffff ffffffff ffffffff ffffffff  ................
+ 0760 ffffffff ffffffff ffffffff ffffffff  ................
+ 0770 ffffffff ffffffff ffffffff ffffffff  ................
+ 0780 ffffffff ffffffff ffffffff ffffffff  ................
+ 0790 ffffffff ffffffff ffffffff ffffffff  ................
+ 07a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0800 00000000 00000000 00000000 00000000  ................
+ 0810 00000000 00000000 00000000 00000000  ................
+ 0820 00000000 00000000 00000000 00000000  ................
+ 0830 00000000 00000000 00000000 00000000  ................
+ 0840 00000000 00000000 00000000 00000000  ................
+ 0850 00000000 00000000 00000000 00000000  ................
+ 0860 00000000 00000000 00000000 00000000  ................
+ 0870 00000000 00000000 00000000 00000000  ................
+ 0880 00000000 00000000 00000000 00000000  ................
+ 0890 00000000 00000000 00000000 00000000  ................
+ 08a0 00000000 00000000 00000000 00000000  ................
+ 08b0 00000000 00000000 00000000 00000000  ................
+ 08c0 00000000 00000000 00000000 00000000  ................
+ 08d0 00000000 00000000 00000000 00000000  ................
+ 08e0 00000000 00000000 00000000 00000000  ................
+ 08f0 00000000 00000000 00000000 00000000  ................
+ 0900 00000000 00000000 00000000 00000000  ................
+ 0910 00000000 00000000 00000000 00000000  ................
+ 0920 00000000 00000000 00000000 00000000  ................
+ 0930 00000000 00000000 00000000 00000000  ................
+ 0940 00000000 00000000 00000000 00000000  ................
+ 0950 00000000 00000000 00000000 00000000  ................
+ 0960 00000000 00000000 00000000 00000000  ................
+ 0970 00000000 00000000 00000000 00000000  ................
+ 0980 00000000 00000000 00000000 00000000  ................
+ 0990 00000000 00000000 00000000 00000000  ................
+ 09a0 00000000 00000000 00000000 00000000  ................
+ 09b0 00000000 00000000 00000000 00000000  ................
+ 09c0 00000000 00000000 00000000 00000000  ................
+ 09d0 00000000 00000000 00000000 00000000  ................
+ 09e0 00000000 00000000 00000000 00000000  ................
+ 09f0 00000000 00000000 00000000 00000000  ................
+ 0a00 00000000 00000000 00000000 00000000  ................
+ 0a10 00000000 00000000 00000000 00000000  ................
+ 0a20 00000000 00000000 00000000 00000000  ................
+ 0a30 00000000 00000000 00000000 00000000  ................
+ 0a40 00000000 00000000 00000000 00000000  ................
+ 0a50 00000000 00000000 00000000 00000000  ................
+ 0a60 00000000 00000000 00000000 00000000  ................
+ 0a70 00000000 00000000 00000000 00000000  ................
+ 0a80 00000000 00000000 00000000 00000000  ................
+ 0a90 00000000 00000000 00000000 00000000  ................
+ 0aa0 00000000 00000000 00000000 00000000  ................
+ 0ab0 00000000 00000000 00000000 00000000  ................
+ 0ac0 00000000 00000000 00000000 00000000  ................
+ 0ad0 00000000 00000000 00000000 00000000  ................
+ 0ae0 00000000 00000000 00000000 00000000  ................
+ 0af0 00000000 00000000 00000000 00000000  ................
+ 0b00 00000000 00000000 00000000 00000000  ................
+ 0b10 00000000 00000000 00000000 00000000  ................
+ 0b20 00000000 00000000 00000000 00000000  ................
+ 0b30 00000000 00000000 00000000 00000000  ................
+ 0b40 00000000 00000000 00000000 00000000  ................
+ 0b50 00000000 00000000 00000000 00000000  ................
+ 0b60 00000000 00000000 00000000 00000000  ................
+ 0b70 00000000 00000000 00000000 00000000  ................
+ 0b80 00000000 00000000 00000000 00000000  ................
+ 0b90 00000000 00000000 00000000 00000000  ................
+ 0ba0 00000000 00000000 00000000 00000000  ................
+ 0bb0 00000000 00000000 00000000 00000000  ................
+ 0bc0 00000000 00000000 00000000 00000000  ................
+ 0bd0 00000000 00000000 00000000 00000000  ................
+ 0be0 00000000 00000000 00000000 00000000  ................
+ 0bf0 00000000 00000000 00000000 00000000  ................
+ 0c00 04000000 00000000 00000000 00000000  ................
+ 0c10 00000000 00000000 00000000 00000000  ................
+ 0c20 00000000 00000000 00000000 00000000  ................
+ 0c30 00000000 00000000 00000000 00000000  ................
+ 0c40 00000000 00000000 00000000 00000000  ................
+ 0c50 00000000 00000000 00000000 00000000  ................
+ 0c60 00000000 00000000 00000000 00000000  ................
+ 0c70 00000000 00000000 00000000 00000000  ................
+ 0c80 00000000 00000000 00000000 00000000  ................
+ 0c90 00000000 00000000 00000000 00000000  ................
+ 0ca0 00000000 00000000 00000000 00000000  ................
+ 0cb0 00000000 00000000 00000000 00000000  ................
+ 0cc0 00000000 00000000 00000000 00000000  ................
+ 0cd0 00000000 00000000 00000000 00000000  ................
+ 0ce0 00000000 00000000 00000000 00000000  ................
+ 0cf0 00000000 00000000 00000000 00000000  ................
+ 0d00 00000000 00000000 00000000 00000000  ................
+ 0d10 00000000 00000000 00000000 00000000  ................
+ 0d20 00000000 00000000 00000000 00000000  ................
+ 0d30 00000000 00000000 00000000 00000000  ................
+ 0d40 00000000 00000000 00000000 00000000  ................
+ 0d50 00000000 00000000 00000000 00000000  ................
+ 0d60 00000000 00000000 00000000 00000000  ................
+ 0d70 00000000 00000000 00000000 00000000  ................
+ 0d80 00000000 00000000 00000000 00000000  ................
+ 0d90 00000000 00000000 00000000 00000000  ................
+ 0da0 00000000 00000000 00000000 00000000  ................
+ 0db0 00000000 00000000 00000000 00000000  ................
+ 0dc0 00000000 00000000 00000000 00000000  ................
+ 0dd0 00000000 00000000 00000000 00000000  ................
+ 0de0 00000000 00000000 00000000 00000000  ................
+ 0df0 00000000 00000000 00000000 00000000  ................
+ 0e00 00000000 00000000 00000000 00000000  ................
+ 0e10 00000000 00000000 00000000 00000000  ................
+ 0e20 00000000 00000000 00000000 00000000  ................
+ 0e30 00000000 00000000 00000000 00000000  ................
+ 0e40 00000000 00000000 00000000 00000000  ................
+ 0e50 00000000 00000000 00000000 00000000  ................
+ 0e60 00000000 00000000 00000000 00000000  ................
+ 0e70 00000000 00000000 00000000 00000000  ................
+ 0e80 00000000 00000000 00000000 00000000  ................
+ 0e90 00000000 00000000 00000000 00000000  ................
+ 0ea0 00000000 00000000 00000000 00000000  ................
+ 0eb0 00000000 00000000 00000000 00000000  ................
+ 0ec0 00000000 00000000 00000000 00000000  ................
+ 0ed0 00000000 00000000 00000000 00000000  ................
+ 0ee0 00000000 00000000 00000000 00000000  ................
+ 0ef0 00000000 00000000 00000000 00000000  ................
+ 0f00 00000000 00000000 00000000 00000000  ................
+ 0f10 00000000 00000000 00000000 00000000  ................
+ 0f20 00000000 00000000 00000000 00000000  ................
+ 0f30 00000000 00000000 00000000 00000000  ................
+ 0f40 00000000 00000000 00000000 00000000  ................
+ 0f50 00000000 00000000 00000000 00000000  ................
+ 0f60 00000000 00000000 00000000 00000000  ................
+ 0f70 00000000 00000000 00000000 00000000  ................
+ 0f80 00000000 00000000 00000000 00000000  ................
+ 0f90 00000000 00000000 00000000 00000000  ................
+ 0fa0 00000000 00000000 00000000 00000000  ................
+ 0fb0 00000000 00000000 00000000 00000000  ................
+ 0fc0 00000000 00000000 00000000 00000000  ................
+ 0fd0 00000000 00000000 00000000 00000000  ................
+ 0fe0 00000000 00000000 00000000 00000000  ................
+ 0ff0 00000000 00000000 00000000 00000000  ................
+ 1000 01000000 03000000 05000000 00000000  ................
+ 1010 00000000 00000000 00000000 00000000  ................
+ 1020 00000000 00000000 00000000 00000000  ................
+ 1030 00000000 00000000 00000000 00000000  ................
+ 1040 00000000 00000000 00000000 00000000  ................
+ 1050 00000000 00000000 00000000 00000000  ................
+ 1060 00000000 00000000 00000000 00000000  ................
+ 1070 00000000 00000000 00000000 00000000  ................
+ 1080 00000000 00000000 00000000 00000000  ................
+ 1090 00000000 00000000 00000000 00000000  ................
+ 10a0 00000000 00000000 00000000 00000000  ................
+ 10b0 00000000 00000000 00000000 00000000  ................
+ 10c0 00000000 00000000 00000000 00000000  ................
+ 10d0 00000000 00000000 00000000 00000000  ................
+ 10e0 00000000 00000000 00000000 00000000  ................
+ 10f0 00000000 00000000 00000000 00000000  ................
+ 1100 00000000 00000000 00000000 00000000  ................
+ 1110 00000000 00000000 00000000 00000000  ................
+ 1120 00000000 00000000 00000000 00000000  ................
+ 1130 00000000 00000000 00000000 00000000  ................
+ 1140 00000000 00000000 00000000 00000000  ................
+ 1150 00000000 00000000 00000000 00000000  ................
+ 1160 00000000 00000000 00000000 00000000  ................
+ 1170 00000000 00000000 00000000 00000000  ................
+ 1180 00000000 00000000 00000000 00000000  ................
+ 1190 00000000 00000000 00000000 00000000  ................
+ 11a0 00000000 00000000 00000000 00000000  ................
+ 11b0 00000000 00000000 00000000 00000000  ................
+ 11c0 00000000 00000000 00000000 00000000  ................
+ 11d0 00000000 00000000 00000000 00000000  ................
+ 11e0 00000000 00000000 00000000 00000000  ................
+ 11f0 00000000 00000000 00000000 00000000  ................
+ 1200 00000000 00000000 00000000 00000000  ................
+ 1210 00000000 00000000 00000000 00000000  ................
+ 1220 00000000 00000000 00000000 00000000  ................
+ 1230 00000000 00000000 00000000 00000000  ................
+ 1240 00000000 00000000 00000000 00000000  ................
+ 1250 00000000 00000000 00000000 00000000  ................
+ 1260 00000000 00000000 00000000 00000000  ................
+ 1270 00000000 00000000 00000000 00000000  ................
+ 1280 00000000 00000000 00000000 00000000  ................
+ 1290 00000000 00000000 00000000 00000000  ................
+ 12a0 00000000 00000000 00000000 00000000  ................
+ 12b0 00000000 00000000 00000000 00000000  ................
+ 12c0 00000000 00000000 00000000 00000000  ................
+ 12d0 00000000 00000000 00000000 00000000  ................
+ 12e0 00000000 00000000 00000000 00000000  ................
+ 12f0 00000000 00000000 00000000 00000000  ................
+ 1300 00000000 00000000 00000000 00000000  ................
+ 1310 00000000 00000000 00000000 00000000  ................
+ 1320 00000000 00000000 00000000 00000000  ................
+ 1330 00000000 00000000 00000000 00000000  ................
+ 1340 00000000 00000000 00000000 00000000  ................
+ 1350 00000000 00000000 00000000 00000000  ................
+ 1360 00000000 00000000 00000000 00000000  ................
+ 1370 00000000 00000000 00000000 00000000  ................
+ 1380 00000000 00000000 00000000 00000000  ................
+ 1390 00000000 00000000 00000000 00000000  ................
+ 13a0 00000000 00000000 00000000 00000000  ................
+ 13b0 00000000 00000000 00000000 00000000  ................
+ 13c0 00000000 00000000 00000000 00000000  ................
+ 13d0 00000000 00000000 00000000 00000000  ................
+ 13e0 00000000 00000000 00000000 00000000  ................
+ 13f0 00000000 00000000 00000000 00000000  ................
+ 1400 666f6f00 00000000 00000000 00000000  foo.............
+ 1410 00000000 00000000 00000000 00000000  ................
+ 1420 00000000 00000000 00000000 00000000  ................
+ 1430 00000000 00000000 00000000 00000000  ................
+ 1440 00000000 00000000 00000000 00000000  ................
+ 1450 00000000 00000000 00000000 00000000  ................
+ 1460 00000000 00000000 00000000 00000000  ................
+ 1470 00000000 00000000 00000000 00000000  ................
+ 1480 00000000 00000000 00000000 00000000  ................
+ 1490 00000000 00000000 00000000 00000000  ................
+ 14a0 00000000 00000000 00000000 00000000  ................
+ 14b0 00000000 00000000 00000000 00000000  ................
+ 14c0 00000000 00000000 00000000 00000000  ................
+ 14d0 00000000 00000000 00000000 00000000  ................
+ 14e0 00000000 00000000 00000000 00000000  ................
+ 14f0 00000000 00000000 00000000 00000000  ................
+ 1500 00000000 00000000 00000000 00000000  ................
+ 1510 00000000 00000000 00000000 00000000  ................
+ 1520 00000000 00000000 00000000 00000000  ................
+ 1530 00000000 00000000 00000000 00000000  ................
+ 1540 00000000 00000000 00000000 00000000  ................
+ 1550 00000000 00000000 00000000 00000000  ................
+ 1560 00000000 00000000 00000000 00000000  ................
+ 1570 00000000 00000000 00000000 00000000  ................
+ 1580 00000000 00000000 00000000 00000000  ................
+ 1590 00000000 00000000 00000000 00000000  ................
+ 15a0 00000000 00000000 00000000 00000000  ................
+ 15b0 00000000 00000000 00000000 00000000  ................
+ 15c0 00000000 00000000 00000000 00000000  ................
+ 15d0 00000000 00000000 00000000 00000000  ................
+ 15e0 00000000 00000000 00000000 00000000  ................
+ 15f0 00000000 00000000 00000000 00000000  ................
+ 1600 00000000 00000000 00000000 00000000  ................
+ 1610 00000000 00000000 00000000 00000000  ................
+ 1620 00000000 00000000 00000000 00000000  ................
+ 1630 00000000 00000000 00000000 00000000  ................
+ 1640 00000000 00000000 00000000 00000000  ................
+ 1650 00000000 00000000 00000000 00000000  ................
+ 1660 00000000 00000000 00000000 00000000  ................
+ 1670 00000000 00000000 00000000 00000000  ................
+ 1680 00000000 00000000 00000000 00000000  ................
+ 1690 00000000 00000000 00000000 00000000  ................
+ 16a0 00000000 00000000 00000000 00000000  ................
+ 16b0 00000000 00000000 00000000 00000000  ................
+ 16c0 00000000 00000000 00000000 00000000  ................
+ 16d0 00000000 00000000 00000000 00000000  ................
+ 16e0 00000000 00000000 00000000 00000000  ................
+ 16f0 00000000 00000000 00000000 00000000  ................
+ 1700 00000000 00000000 00000000 00000000  ................
+ 1710 00000000 00000000 00000000 00000000  ................
+ 1720 00000000 00000000 00000000 00000000  ................
+ 1730 00000000 00000000 00000000 00000000  ................
+ 1740 00000000 00000000 00000000 00000000  ................
+ 1750 00000000 00000000 00000000 00000000  ................
+ 1760 00000000 00000000 00000000 00000000  ................
+ 1770 00000000 00000000 00000000 00000000  ................
+ 1780 00000000 00000000 00000000 00000000  ................
+ 1790 00000000 00000000 00000000 00000000  ................
+ 17a0 00000000 00000000 00000000 00000000  ................
+ 17b0 00000000 00000000 00000000 00000000  ................
+ 17c0 00000000 00000000 00000000 00000000  ................
+ 17d0 00000000 00000000 00000000 00000000  ................
+ 17e0 00000000 00000000 00000000 00000000  ................
+ 17f0 00000000 00000000 00000000 00000000  ................
diff --git a/binutils/testsuite/binutils-all/pdb2.d b/binutils/testsuite/binutils-all/pdb2.d
new file mode 100644
index 00000000000..08bcbe4865c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdb2.d
@@ -0,0 +1,388 @@
+
+tmpdir/test.pdb:     file format binary
+
+Contents of section .data:
+ 0000 4d696372 6f736f66 7420432f 432b2b20  Microsoft C/C++ 
+ 0010 4d534620 372e3030 0d0a1a44 53000000  MSF 7.00...DS...
+ 0020 00040000 01000000 06000000 10000000  ................
+ 0030 00000000 03000000 00000000 00000000  ................
+ 0040 00000000 00000000 00000000 00000000  ................
+ 0050 00000000 00000000 00000000 00000000  ................
+ 0060 00000000 00000000 00000000 00000000  ................
+ 0070 00000000 00000000 00000000 00000000  ................
+ 0080 00000000 00000000 00000000 00000000  ................
+ 0090 00000000 00000000 00000000 00000000  ................
+ 00a0 00000000 00000000 00000000 00000000  ................
+ 00b0 00000000 00000000 00000000 00000000  ................
+ 00c0 00000000 00000000 00000000 00000000  ................
+ 00d0 00000000 00000000 00000000 00000000  ................
+ 00e0 00000000 00000000 00000000 00000000  ................
+ 00f0 00000000 00000000 00000000 00000000  ................
+ 0100 00000000 00000000 00000000 00000000  ................
+ 0110 00000000 00000000 00000000 00000000  ................
+ 0120 00000000 00000000 00000000 00000000  ................
+ 0130 00000000 00000000 00000000 00000000  ................
+ 0140 00000000 00000000 00000000 00000000  ................
+ 0150 00000000 00000000 00000000 00000000  ................
+ 0160 00000000 00000000 00000000 00000000  ................
+ 0170 00000000 00000000 00000000 00000000  ................
+ 0180 00000000 00000000 00000000 00000000  ................
+ 0190 00000000 00000000 00000000 00000000  ................
+ 01a0 00000000 00000000 00000000 00000000  ................
+ 01b0 00000000 00000000 00000000 00000000  ................
+ 01c0 00000000 00000000 00000000 00000000  ................
+ 01d0 00000000 00000000 00000000 00000000  ................
+ 01e0 00000000 00000000 00000000 00000000  ................
+ 01f0 00000000 00000000 00000000 00000000  ................
+ 0200 00000000 00000000 00000000 00000000  ................
+ 0210 00000000 00000000 00000000 00000000  ................
+ 0220 00000000 00000000 00000000 00000000  ................
+ 0230 00000000 00000000 00000000 00000000  ................
+ 0240 00000000 00000000 00000000 00000000  ................
+ 0250 00000000 00000000 00000000 00000000  ................
+ 0260 00000000 00000000 00000000 00000000  ................
+ 0270 00000000 00000000 00000000 00000000  ................
+ 0280 00000000 00000000 00000000 00000000  ................
+ 0290 00000000 00000000 00000000 00000000  ................
+ 02a0 00000000 00000000 00000000 00000000  ................
+ 02b0 00000000 00000000 00000000 00000000  ................
+ 02c0 00000000 00000000 00000000 00000000  ................
+ 02d0 00000000 00000000 00000000 00000000  ................
+ 02e0 00000000 00000000 00000000 00000000  ................
+ 02f0 00000000 00000000 00000000 00000000  ................
+ 0300 00000000 00000000 00000000 00000000  ................
+ 0310 00000000 00000000 00000000 00000000  ................
+ 0320 00000000 00000000 00000000 00000000  ................
+ 0330 00000000 00000000 00000000 00000000  ................
+ 0340 00000000 00000000 00000000 00000000  ................
+ 0350 00000000 00000000 00000000 00000000  ................
+ 0360 00000000 00000000 00000000 00000000  ................
+ 0370 00000000 00000000 00000000 00000000  ................
+ 0380 00000000 00000000 00000000 00000000  ................
+ 0390 00000000 00000000 00000000 00000000  ................
+ 03a0 00000000 00000000 00000000 00000000  ................
+ 03b0 00000000 00000000 00000000 00000000  ................
+ 03c0 00000000 00000000 00000000 00000000  ................
+ 03d0 00000000 00000000 00000000 00000000  ................
+ 03e0 00000000 00000000 00000000 00000000  ................
+ 03f0 00000000 00000000 00000000 00000000  ................
+ 0400 07ffffff ffffffff ffffffff ffffffff  ................
+ 0410 ffffffff ffffffff ffffffff ffffffff  ................
+ 0420 ffffffff ffffffff ffffffff ffffffff  ................
+ 0430 ffffffff ffffffff ffffffff ffffffff  ................
+ 0440 ffffffff ffffffff ffffffff ffffffff  ................
+ 0450 ffffffff ffffffff ffffffff ffffffff  ................
+ 0460 ffffffff ffffffff ffffffff ffffffff  ................
+ 0470 ffffffff ffffffff ffffffff ffffffff  ................
+ 0480 ffffffff ffffffff ffffffff ffffffff  ................
+ 0490 ffffffff ffffffff ffffffff ffffffff  ................
+ 04a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0500 ffffffff ffffffff ffffffff ffffffff  ................
+ 0510 ffffffff ffffffff ffffffff ffffffff  ................
+ 0520 ffffffff ffffffff ffffffff ffffffff  ................
+ 0530 ffffffff ffffffff ffffffff ffffffff  ................
+ 0540 ffffffff ffffffff ffffffff ffffffff  ................
+ 0550 ffffffff ffffffff ffffffff ffffffff  ................
+ 0560 ffffffff ffffffff ffffffff ffffffff  ................
+ 0570 ffffffff ffffffff ffffffff ffffffff  ................
+ 0580 ffffffff ffffffff ffffffff ffffffff  ................
+ 0590 ffffffff ffffffff ffffffff ffffffff  ................
+ 05a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0600 ffffffff ffffffff ffffffff ffffffff  ................
+ 0610 ffffffff ffffffff ffffffff ffffffff  ................
+ 0620 ffffffff ffffffff ffffffff ffffffff  ................
+ 0630 ffffffff ffffffff ffffffff ffffffff  ................
+ 0640 ffffffff ffffffff ffffffff ffffffff  ................
+ 0650 ffffffff ffffffff ffffffff ffffffff  ................
+ 0660 ffffffff ffffffff ffffffff ffffffff  ................
+ 0670 ffffffff ffffffff ffffffff ffffffff  ................
+ 0680 ffffffff ffffffff ffffffff ffffffff  ................
+ 0690 ffffffff ffffffff ffffffff ffffffff  ................
+ 06a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0700 ffffffff ffffffff ffffffff ffffffff  ................
+ 0710 ffffffff ffffffff ffffffff ffffffff  ................
+ 0720 ffffffff ffffffff ffffffff ffffffff  ................
+ 0730 ffffffff ffffffff ffffffff ffffffff  ................
+ 0740 ffffffff ffffffff ffffffff ffffffff  ................
+ 0750 ffffffff ffffffff ffffffff ffffffff  ................
+ 0760 ffffffff ffffffff ffffffff ffffffff  ................
+ 0770 ffffffff ffffffff ffffffff ffffffff  ................
+ 0780 ffffffff ffffffff ffffffff ffffffff  ................
+ 0790 ffffffff ffffffff ffffffff ffffffff  ................
+ 07a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0800 00000000 00000000 00000000 00000000  ................
+ 0810 00000000 00000000 00000000 00000000  ................
+ 0820 00000000 00000000 00000000 00000000  ................
+ 0830 00000000 00000000 00000000 00000000  ................
+ 0840 00000000 00000000 00000000 00000000  ................
+ 0850 00000000 00000000 00000000 00000000  ................
+ 0860 00000000 00000000 00000000 00000000  ................
+ 0870 00000000 00000000 00000000 00000000  ................
+ 0880 00000000 00000000 00000000 00000000  ................
+ 0890 00000000 00000000 00000000 00000000  ................
+ 08a0 00000000 00000000 00000000 00000000  ................
+ 08b0 00000000 00000000 00000000 00000000  ................
+ 08c0 00000000 00000000 00000000 00000000  ................
+ 08d0 00000000 00000000 00000000 00000000  ................
+ 08e0 00000000 00000000 00000000 00000000  ................
+ 08f0 00000000 00000000 00000000 00000000  ................
+ 0900 00000000 00000000 00000000 00000000  ................
+ 0910 00000000 00000000 00000000 00000000  ................
+ 0920 00000000 00000000 00000000 00000000  ................
+ 0930 00000000 00000000 00000000 00000000  ................
+ 0940 00000000 00000000 00000000 00000000  ................
+ 0950 00000000 00000000 00000000 00000000  ................
+ 0960 00000000 00000000 00000000 00000000  ................
+ 0970 00000000 00000000 00000000 00000000  ................
+ 0980 00000000 00000000 00000000 00000000  ................
+ 0990 00000000 00000000 00000000 00000000  ................
+ 09a0 00000000 00000000 00000000 00000000  ................
+ 09b0 00000000 00000000 00000000 00000000  ................
+ 09c0 00000000 00000000 00000000 00000000  ................
+ 09d0 00000000 00000000 00000000 00000000  ................
+ 09e0 00000000 00000000 00000000 00000000  ................
+ 09f0 00000000 00000000 00000000 00000000  ................
+ 0a00 00000000 00000000 00000000 00000000  ................
+ 0a10 00000000 00000000 00000000 00000000  ................
+ 0a20 00000000 00000000 00000000 00000000  ................
+ 0a30 00000000 00000000 00000000 00000000  ................
+ 0a40 00000000 00000000 00000000 00000000  ................
+ 0a50 00000000 00000000 00000000 00000000  ................
+ 0a60 00000000 00000000 00000000 00000000  ................
+ 0a70 00000000 00000000 00000000 00000000  ................
+ 0a80 00000000 00000000 00000000 00000000  ................
+ 0a90 00000000 00000000 00000000 00000000  ................
+ 0aa0 00000000 00000000 00000000 00000000  ................
+ 0ab0 00000000 00000000 00000000 00000000  ................
+ 0ac0 00000000 00000000 00000000 00000000  ................
+ 0ad0 00000000 00000000 00000000 00000000  ................
+ 0ae0 00000000 00000000 00000000 00000000  ................
+ 0af0 00000000 00000000 00000000 00000000  ................
+ 0b00 00000000 00000000 00000000 00000000  ................
+ 0b10 00000000 00000000 00000000 00000000  ................
+ 0b20 00000000 00000000 00000000 00000000  ................
+ 0b30 00000000 00000000 00000000 00000000  ................
+ 0b40 00000000 00000000 00000000 00000000  ................
+ 0b50 00000000 00000000 00000000 00000000  ................
+ 0b60 00000000 00000000 00000000 00000000  ................
+ 0b70 00000000 00000000 00000000 00000000  ................
+ 0b80 00000000 00000000 00000000 00000000  ................
+ 0b90 00000000 00000000 00000000 00000000  ................
+ 0ba0 00000000 00000000 00000000 00000000  ................
+ 0bb0 00000000 00000000 00000000 00000000  ................
+ 0bc0 00000000 00000000 00000000 00000000  ................
+ 0bd0 00000000 00000000 00000000 00000000  ................
+ 0be0 00000000 00000000 00000000 00000000  ................
+ 0bf0 00000000 00000000 00000000 00000000  ................
+ 0c00 04000000 00000000 00000000 00000000  ................
+ 0c10 00000000 00000000 00000000 00000000  ................
+ 0c20 00000000 00000000 00000000 00000000  ................
+ 0c30 00000000 00000000 00000000 00000000  ................
+ 0c40 00000000 00000000 00000000 00000000  ................
+ 0c50 00000000 00000000 00000000 00000000  ................
+ 0c60 00000000 00000000 00000000 00000000  ................
+ 0c70 00000000 00000000 00000000 00000000  ................
+ 0c80 00000000 00000000 00000000 00000000  ................
+ 0c90 00000000 00000000 00000000 00000000  ................
+ 0ca0 00000000 00000000 00000000 00000000  ................
+ 0cb0 00000000 00000000 00000000 00000000  ................
+ 0cc0 00000000 00000000 00000000 00000000  ................
+ 0cd0 00000000 00000000 00000000 00000000  ................
+ 0ce0 00000000 00000000 00000000 00000000  ................
+ 0cf0 00000000 00000000 00000000 00000000  ................
+ 0d00 00000000 00000000 00000000 00000000  ................
+ 0d10 00000000 00000000 00000000 00000000  ................
+ 0d20 00000000 00000000 00000000 00000000  ................
+ 0d30 00000000 00000000 00000000 00000000  ................
+ 0d40 00000000 00000000 00000000 00000000  ................
+ 0d50 00000000 00000000 00000000 00000000  ................
+ 0d60 00000000 00000000 00000000 00000000  ................
+ 0d70 00000000 00000000 00000000 00000000  ................
+ 0d80 00000000 00000000 00000000 00000000  ................
+ 0d90 00000000 00000000 00000000 00000000  ................
+ 0da0 00000000 00000000 00000000 00000000  ................
+ 0db0 00000000 00000000 00000000 00000000  ................
+ 0dc0 00000000 00000000 00000000 00000000  ................
+ 0dd0 00000000 00000000 00000000 00000000  ................
+ 0de0 00000000 00000000 00000000 00000000  ................
+ 0df0 00000000 00000000 00000000 00000000  ................
+ 0e00 00000000 00000000 00000000 00000000  ................
+ 0e10 00000000 00000000 00000000 00000000  ................
+ 0e20 00000000 00000000 00000000 00000000  ................
+ 0e30 00000000 00000000 00000000 00000000  ................
+ 0e40 00000000 00000000 00000000 00000000  ................
+ 0e50 00000000 00000000 00000000 00000000  ................
+ 0e60 00000000 00000000 00000000 00000000  ................
+ 0e70 00000000 00000000 00000000 00000000  ................
+ 0e80 00000000 00000000 00000000 00000000  ................
+ 0e90 00000000 00000000 00000000 00000000  ................
+ 0ea0 00000000 00000000 00000000 00000000  ................
+ 0eb0 00000000 00000000 00000000 00000000  ................
+ 0ec0 00000000 00000000 00000000 00000000  ................
+ 0ed0 00000000 00000000 00000000 00000000  ................
+ 0ee0 00000000 00000000 00000000 00000000  ................
+ 0ef0 00000000 00000000 00000000 00000000  ................
+ 0f00 00000000 00000000 00000000 00000000  ................
+ 0f10 00000000 00000000 00000000 00000000  ................
+ 0f20 00000000 00000000 00000000 00000000  ................
+ 0f30 00000000 00000000 00000000 00000000  ................
+ 0f40 00000000 00000000 00000000 00000000  ................
+ 0f50 00000000 00000000 00000000 00000000  ................
+ 0f60 00000000 00000000 00000000 00000000  ................
+ 0f70 00000000 00000000 00000000 00000000  ................
+ 0f80 00000000 00000000 00000000 00000000  ................
+ 0f90 00000000 00000000 00000000 00000000  ................
+ 0fa0 00000000 00000000 00000000 00000000  ................
+ 0fb0 00000000 00000000 00000000 00000000  ................
+ 0fc0 00000000 00000000 00000000 00000000  ................
+ 0fd0 00000000 00000000 00000000 00000000  ................
+ 0fe0 00000000 00000000 00000000 00000000  ................
+ 0ff0 00000000 00000000 00000000 00000000  ................
+ 1000 02000000 03000000 00000000 05000000  ................
+ 1010 00000000 00000000 00000000 00000000  ................
+ 1020 00000000 00000000 00000000 00000000  ................
+ 1030 00000000 00000000 00000000 00000000  ................
+ 1040 00000000 00000000 00000000 00000000  ................
+ 1050 00000000 00000000 00000000 00000000  ................
+ 1060 00000000 00000000 00000000 00000000  ................
+ 1070 00000000 00000000 00000000 00000000  ................
+ 1080 00000000 00000000 00000000 00000000  ................
+ 1090 00000000 00000000 00000000 00000000  ................
+ 10a0 00000000 00000000 00000000 00000000  ................
+ 10b0 00000000 00000000 00000000 00000000  ................
+ 10c0 00000000 00000000 00000000 00000000  ................
+ 10d0 00000000 00000000 00000000 00000000  ................
+ 10e0 00000000 00000000 00000000 00000000  ................
+ 10f0 00000000 00000000 00000000 00000000  ................
+ 1100 00000000 00000000 00000000 00000000  ................
+ 1110 00000000 00000000 00000000 00000000  ................
+ 1120 00000000 00000000 00000000 00000000  ................
+ 1130 00000000 00000000 00000000 00000000  ................
+ 1140 00000000 00000000 00000000 00000000  ................
+ 1150 00000000 00000000 00000000 00000000  ................
+ 1160 00000000 00000000 00000000 00000000  ................
+ 1170 00000000 00000000 00000000 00000000  ................
+ 1180 00000000 00000000 00000000 00000000  ................
+ 1190 00000000 00000000 00000000 00000000  ................
+ 11a0 00000000 00000000 00000000 00000000  ................
+ 11b0 00000000 00000000 00000000 00000000  ................
+ 11c0 00000000 00000000 00000000 00000000  ................
+ 11d0 00000000 00000000 00000000 00000000  ................
+ 11e0 00000000 00000000 00000000 00000000  ................
+ 11f0 00000000 00000000 00000000 00000000  ................
+ 1200 00000000 00000000 00000000 00000000  ................
+ 1210 00000000 00000000 00000000 00000000  ................
+ 1220 00000000 00000000 00000000 00000000  ................
+ 1230 00000000 00000000 00000000 00000000  ................
+ 1240 00000000 00000000 00000000 00000000  ................
+ 1250 00000000 00000000 00000000 00000000  ................
+ 1260 00000000 00000000 00000000 00000000  ................
+ 1270 00000000 00000000 00000000 00000000  ................
+ 1280 00000000 00000000 00000000 00000000  ................
+ 1290 00000000 00000000 00000000 00000000  ................
+ 12a0 00000000 00000000 00000000 00000000  ................
+ 12b0 00000000 00000000 00000000 00000000  ................
+ 12c0 00000000 00000000 00000000 00000000  ................
+ 12d0 00000000 00000000 00000000 00000000  ................
+ 12e0 00000000 00000000 00000000 00000000  ................
+ 12f0 00000000 00000000 00000000 00000000  ................
+ 1300 00000000 00000000 00000000 00000000  ................
+ 1310 00000000 00000000 00000000 00000000  ................
+ 1320 00000000 00000000 00000000 00000000  ................
+ 1330 00000000 00000000 00000000 00000000  ................
+ 1340 00000000 00000000 00000000 00000000  ................
+ 1350 00000000 00000000 00000000 00000000  ................
+ 1360 00000000 00000000 00000000 00000000  ................
+ 1370 00000000 00000000 00000000 00000000  ................
+ 1380 00000000 00000000 00000000 00000000  ................
+ 1390 00000000 00000000 00000000 00000000  ................
+ 13a0 00000000 00000000 00000000 00000000  ................
+ 13b0 00000000 00000000 00000000 00000000  ................
+ 13c0 00000000 00000000 00000000 00000000  ................
+ 13d0 00000000 00000000 00000000 00000000  ................
+ 13e0 00000000 00000000 00000000 00000000  ................
+ 13f0 00000000 00000000 00000000 00000000  ................
+ 1400 666f6f00 00000000 00000000 00000000  foo.............
+ 1410 00000000 00000000 00000000 00000000  ................
+ 1420 00000000 00000000 00000000 00000000  ................
+ 1430 00000000 00000000 00000000 00000000  ................
+ 1440 00000000 00000000 00000000 00000000  ................
+ 1450 00000000 00000000 00000000 00000000  ................
+ 1460 00000000 00000000 00000000 00000000  ................
+ 1470 00000000 00000000 00000000 00000000  ................
+ 1480 00000000 00000000 00000000 00000000  ................
+ 1490 00000000 00000000 00000000 00000000  ................
+ 14a0 00000000 00000000 00000000 00000000  ................
+ 14b0 00000000 00000000 00000000 00000000  ................
+ 14c0 00000000 00000000 00000000 00000000  ................
+ 14d0 00000000 00000000 00000000 00000000  ................
+ 14e0 00000000 00000000 00000000 00000000  ................
+ 14f0 00000000 00000000 00000000 00000000  ................
+ 1500 00000000 00000000 00000000 00000000  ................
+ 1510 00000000 00000000 00000000 00000000  ................
+ 1520 00000000 00000000 00000000 00000000  ................
+ 1530 00000000 00000000 00000000 00000000  ................
+ 1540 00000000 00000000 00000000 00000000  ................
+ 1550 00000000 00000000 00000000 00000000  ................
+ 1560 00000000 00000000 00000000 00000000  ................
+ 1570 00000000 00000000 00000000 00000000  ................
+ 1580 00000000 00000000 00000000 00000000  ................
+ 1590 00000000 00000000 00000000 00000000  ................
+ 15a0 00000000 00000000 00000000 00000000  ................
+ 15b0 00000000 00000000 00000000 00000000  ................
+ 15c0 00000000 00000000 00000000 00000000  ................
+ 15d0 00000000 00000000 00000000 00000000  ................
+ 15e0 00000000 00000000 00000000 00000000  ................
+ 15f0 00000000 00000000 00000000 00000000  ................
+ 1600 00000000 00000000 00000000 00000000  ................
+ 1610 00000000 00000000 00000000 00000000  ................
+ 1620 00000000 00000000 00000000 00000000  ................
+ 1630 00000000 00000000 00000000 00000000  ................
+ 1640 00000000 00000000 00000000 00000000  ................
+ 1650 00000000 00000000 00000000 00000000  ................
+ 1660 00000000 00000000 00000000 00000000  ................
+ 1670 00000000 00000000 00000000 00000000  ................
+ 1680 00000000 00000000 00000000 00000000  ................
+ 1690 00000000 00000000 00000000 00000000  ................
+ 16a0 00000000 00000000 00000000 00000000  ................
+ 16b0 00000000 00000000 00000000 00000000  ................
+ 16c0 00000000 00000000 00000000 00000000  ................
+ 16d0 00000000 00000000 00000000 00000000  ................
+ 16e0 00000000 00000000 00000000 00000000  ................
+ 16f0 00000000 00000000 00000000 00000000  ................
+ 1700 00000000 00000000 00000000 00000000  ................
+ 1710 00000000 00000000 00000000 00000000  ................
+ 1720 00000000 00000000 00000000 00000000  ................
+ 1730 00000000 00000000 00000000 00000000  ................
+ 1740 00000000 00000000 00000000 00000000  ................
+ 1750 00000000 00000000 00000000 00000000  ................
+ 1760 00000000 00000000 00000000 00000000  ................
+ 1770 00000000 00000000 00000000 00000000  ................
+ 1780 00000000 00000000 00000000 00000000  ................
+ 1790 00000000 00000000 00000000 00000000  ................
+ 17a0 00000000 00000000 00000000 00000000  ................
+ 17b0 00000000 00000000 00000000 00000000  ................
+ 17c0 00000000 00000000 00000000 00000000  ................
+ 17d0 00000000 00000000 00000000 00000000  ................
+ 17e0 00000000 00000000 00000000 00000000  ................
+ 17f0 00000000 00000000 00000000 00000000  ................
diff --git a/binutils/testsuite/binutils-all/pdb3.d b/binutils/testsuite/binutils-all/pdb3.d
new file mode 100644
index 00000000000..50673857fd7
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdb3.d
@@ -0,0 +1,516 @@
+
+tmpdir/test.pdb:     file format binary
+
+Contents of section .data:
+ 0000 4d696372 6f736f66 7420432f 432b2b20  Microsoft C/C++ 
+ 0010 4d534620 372e3030 0d0a1a44 53000000  MSF 7.00...DS...
+ 0020 00040000 01000000 08000000 1c000000  ................
+ 0030 00000000 03000000 00000000 00000000  ................
+ 0040 00000000 00000000 00000000 00000000  ................
+ 0050 00000000 00000000 00000000 00000000  ................
+ 0060 00000000 00000000 00000000 00000000  ................
+ 0070 00000000 00000000 00000000 00000000  ................
+ 0080 00000000 00000000 00000000 00000000  ................
+ 0090 00000000 00000000 00000000 00000000  ................
+ 00a0 00000000 00000000 00000000 00000000  ................
+ 00b0 00000000 00000000 00000000 00000000  ................
+ 00c0 00000000 00000000 00000000 00000000  ................
+ 00d0 00000000 00000000 00000000 00000000  ................
+ 00e0 00000000 00000000 00000000 00000000  ................
+ 00f0 00000000 00000000 00000000 00000000  ................
+ 0100 00000000 00000000 00000000 00000000  ................
+ 0110 00000000 00000000 00000000 00000000  ................
+ 0120 00000000 00000000 00000000 00000000  ................
+ 0130 00000000 00000000 00000000 00000000  ................
+ 0140 00000000 00000000 00000000 00000000  ................
+ 0150 00000000 00000000 00000000 00000000  ................
+ 0160 00000000 00000000 00000000 00000000  ................
+ 0170 00000000 00000000 00000000 00000000  ................
+ 0180 00000000 00000000 00000000 00000000  ................
+ 0190 00000000 00000000 00000000 00000000  ................
+ 01a0 00000000 00000000 00000000 00000000  ................
+ 01b0 00000000 00000000 00000000 00000000  ................
+ 01c0 00000000 00000000 00000000 00000000  ................
+ 01d0 00000000 00000000 00000000 00000000  ................
+ 01e0 00000000 00000000 00000000 00000000  ................
+ 01f0 00000000 00000000 00000000 00000000  ................
+ 0200 00000000 00000000 00000000 00000000  ................
+ 0210 00000000 00000000 00000000 00000000  ................
+ 0220 00000000 00000000 00000000 00000000  ................
+ 0230 00000000 00000000 00000000 00000000  ................
+ 0240 00000000 00000000 00000000 00000000  ................
+ 0250 00000000 00000000 00000000 00000000  ................
+ 0260 00000000 00000000 00000000 00000000  ................
+ 0270 00000000 00000000 00000000 00000000  ................
+ 0280 00000000 00000000 00000000 00000000  ................
+ 0290 00000000 00000000 00000000 00000000  ................
+ 02a0 00000000 00000000 00000000 00000000  ................
+ 02b0 00000000 00000000 00000000 00000000  ................
+ 02c0 00000000 00000000 00000000 00000000  ................
+ 02d0 00000000 00000000 00000000 00000000  ................
+ 02e0 00000000 00000000 00000000 00000000  ................
+ 02f0 00000000 00000000 00000000 00000000  ................
+ 0300 00000000 00000000 00000000 00000000  ................
+ 0310 00000000 00000000 00000000 00000000  ................
+ 0320 00000000 00000000 00000000 00000000  ................
+ 0330 00000000 00000000 00000000 00000000  ................
+ 0340 00000000 00000000 00000000 00000000  ................
+ 0350 00000000 00000000 00000000 00000000  ................
+ 0360 00000000 00000000 00000000 00000000  ................
+ 0370 00000000 00000000 00000000 00000000  ................
+ 0380 00000000 00000000 00000000 00000000  ................
+ 0390 00000000 00000000 00000000 00000000  ................
+ 03a0 00000000 00000000 00000000 00000000  ................
+ 03b0 00000000 00000000 00000000 00000000  ................
+ 03c0 00000000 00000000 00000000 00000000  ................
+ 03d0 00000000 00000000 00000000 00000000  ................
+ 03e0 00000000 00000000 00000000 00000000  ................
+ 03f0 00000000 00000000 00000000 00000000  ................
+ 0400 01ffffff ffffffff ffffffff ffffffff  ................
+ 0410 ffffffff ffffffff ffffffff ffffffff  ................
+ 0420 ffffffff ffffffff ffffffff ffffffff  ................
+ 0430 ffffffff ffffffff ffffffff ffffffff  ................
+ 0440 ffffffff ffffffff ffffffff ffffffff  ................
+ 0450 ffffffff ffffffff ffffffff ffffffff  ................
+ 0460 ffffffff ffffffff ffffffff ffffffff  ................
+ 0470 ffffffff ffffffff ffffffff ffffffff  ................
+ 0480 ffffffff ffffffff ffffffff ffffffff  ................
+ 0490 ffffffff ffffffff ffffffff ffffffff  ................
+ 04a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 04f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0500 ffffffff ffffffff ffffffff ffffffff  ................
+ 0510 ffffffff ffffffff ffffffff ffffffff  ................
+ 0520 ffffffff ffffffff ffffffff ffffffff  ................
+ 0530 ffffffff ffffffff ffffffff ffffffff  ................
+ 0540 ffffffff ffffffff ffffffff ffffffff  ................
+ 0550 ffffffff ffffffff ffffffff ffffffff  ................
+ 0560 ffffffff ffffffff ffffffff ffffffff  ................
+ 0570 ffffffff ffffffff ffffffff ffffffff  ................
+ 0580 ffffffff ffffffff ffffffff ffffffff  ................
+ 0590 ffffffff ffffffff ffffffff ffffffff  ................
+ 05a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 05f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0600 ffffffff ffffffff ffffffff ffffffff  ................
+ 0610 ffffffff ffffffff ffffffff ffffffff  ................
+ 0620 ffffffff ffffffff ffffffff ffffffff  ................
+ 0630 ffffffff ffffffff ffffffff ffffffff  ................
+ 0640 ffffffff ffffffff ffffffff ffffffff  ................
+ 0650 ffffffff ffffffff ffffffff ffffffff  ................
+ 0660 ffffffff ffffffff ffffffff ffffffff  ................
+ 0670 ffffffff ffffffff ffffffff ffffffff  ................
+ 0680 ffffffff ffffffff ffffffff ffffffff  ................
+ 0690 ffffffff ffffffff ffffffff ffffffff  ................
+ 06a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 06f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0700 ffffffff ffffffff ffffffff ffffffff  ................
+ 0710 ffffffff ffffffff ffffffff ffffffff  ................
+ 0720 ffffffff ffffffff ffffffff ffffffff  ................
+ 0730 ffffffff ffffffff ffffffff ffffffff  ................
+ 0740 ffffffff ffffffff ffffffff ffffffff  ................
+ 0750 ffffffff ffffffff ffffffff ffffffff  ................
+ 0760 ffffffff ffffffff ffffffff ffffffff  ................
+ 0770 ffffffff ffffffff ffffffff ffffffff  ................
+ 0780 ffffffff ffffffff ffffffff ffffffff  ................
+ 0790 ffffffff ffffffff ffffffff ffffffff  ................
+ 07a0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07b0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07c0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07d0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07e0 ffffffff ffffffff ffffffff ffffffff  ................
+ 07f0 ffffffff ffffffff ffffffff ffffffff  ................
+ 0800 00000000 00000000 00000000 00000000  ................
+ 0810 00000000 00000000 00000000 00000000  ................
+ 0820 00000000 00000000 00000000 00000000  ................
+ 0830 00000000 00000000 00000000 00000000  ................
+ 0840 00000000 00000000 00000000 00000000  ................
+ 0850 00000000 00000000 00000000 00000000  ................
+ 0860 00000000 00000000 00000000 00000000  ................
+ 0870 00000000 00000000 00000000 00000000  ................
+ 0880 00000000 00000000 00000000 00000000  ................
+ 0890 00000000 00000000 00000000 00000000  ................
+ 08a0 00000000 00000000 00000000 00000000  ................
+ 08b0 00000000 00000000 00000000 00000000  ................
+ 08c0 00000000 00000000 00000000 00000000  ................
+ 08d0 00000000 00000000 00000000 00000000  ................
+ 08e0 00000000 00000000 00000000 00000000  ................
+ 08f0 00000000 00000000 00000000 00000000  ................
+ 0900 00000000 00000000 00000000 00000000  ................
+ 0910 00000000 00000000 00000000 00000000  ................
+ 0920 00000000 00000000 00000000 00000000  ................
+ 0930 00000000 00000000 00000000 00000000  ................
+ 0940 00000000 00000000 00000000 00000000  ................
+ 0950 00000000 00000000 00000000 00000000  ................
+ 0960 00000000 00000000 00000000 00000000  ................
+ 0970 00000000 00000000 00000000 00000000  ................
+ 0980 00000000 00000000 00000000 00000000  ................
+ 0990 00000000 00000000 00000000 00000000  ................
+ 09a0 00000000 00000000 00000000 00000000  ................
+ 09b0 00000000 00000000 00000000 00000000  ................
+ 09c0 00000000 00000000 00000000 00000000  ................
+ 09d0 00000000 00000000 00000000 00000000  ................
+ 09e0 00000000 00000000 00000000 00000000  ................
+ 09f0 00000000 00000000 00000000 00000000  ................
+ 0a00 00000000 00000000 00000000 00000000  ................
+ 0a10 00000000 00000000 00000000 00000000  ................
+ 0a20 00000000 00000000 00000000 00000000  ................
+ 0a30 00000000 00000000 00000000 00000000  ................
+ 0a40 00000000 00000000 00000000 00000000  ................
+ 0a50 00000000 00000000 00000000 00000000  ................
+ 0a60 00000000 00000000 00000000 00000000  ................
+ 0a70 00000000 00000000 00000000 00000000  ................
+ 0a80 00000000 00000000 00000000 00000000  ................
+ 0a90 00000000 00000000 00000000 00000000  ................
+ 0aa0 00000000 00000000 00000000 00000000  ................
+ 0ab0 00000000 00000000 00000000 00000000  ................
+ 0ac0 00000000 00000000 00000000 00000000  ................
+ 0ad0 00000000 00000000 00000000 00000000  ................
+ 0ae0 00000000 00000000 00000000 00000000  ................
+ 0af0 00000000 00000000 00000000 00000000  ................
+ 0b00 00000000 00000000 00000000 00000000  ................
+ 0b10 00000000 00000000 00000000 00000000  ................
+ 0b20 00000000 00000000 00000000 00000000  ................
+ 0b30 00000000 00000000 00000000 00000000  ................
+ 0b40 00000000 00000000 00000000 00000000  ................
+ 0b50 00000000 00000000 00000000 00000000  ................
+ 0b60 00000000 00000000 00000000 00000000  ................
+ 0b70 00000000 00000000 00000000 00000000  ................
+ 0b80 00000000 00000000 00000000 00000000  ................
+ 0b90 00000000 00000000 00000000 00000000  ................
+ 0ba0 00000000 00000000 00000000 00000000  ................
+ 0bb0 00000000 00000000 00000000 00000000  ................
+ 0bc0 00000000 00000000 00000000 00000000  ................
+ 0bd0 00000000 00000000 00000000 00000000  ................
+ 0be0 00000000 00000000 00000000 00000000  ................
+ 0bf0 00000000 00000000 00000000 00000000  ................
+ 0c00 04000000 00000000 00000000 00000000  ................
+ 0c10 00000000 00000000 00000000 00000000  ................
+ 0c20 00000000 00000000 00000000 00000000  ................
+ 0c30 00000000 00000000 00000000 00000000  ................
+ 0c40 00000000 00000000 00000000 00000000  ................
+ 0c50 00000000 00000000 00000000 00000000  ................
+ 0c60 00000000 00000000 00000000 00000000  ................
+ 0c70 00000000 00000000 00000000 00000000  ................
+ 0c80 00000000 00000000 00000000 00000000  ................
+ 0c90 00000000 00000000 00000000 00000000  ................
+ 0ca0 00000000 00000000 00000000 00000000  ................
+ 0cb0 00000000 00000000 00000000 00000000  ................
+ 0cc0 00000000 00000000 00000000 00000000  ................
+ 0cd0 00000000 00000000 00000000 00000000  ................
+ 0ce0 00000000 00000000 00000000 00000000  ................
+ 0cf0 00000000 00000000 00000000 00000000  ................
+ 0d00 00000000 00000000 00000000 00000000  ................
+ 0d10 00000000 00000000 00000000 00000000  ................
+ 0d20 00000000 00000000 00000000 00000000  ................
+ 0d30 00000000 00000000 00000000 00000000  ................
+ 0d40 00000000 00000000 00000000 00000000  ................
+ 0d50 00000000 00000000 00000000 00000000  ................
+ 0d60 00000000 00000000 00000000 00000000  ................
+ 0d70 00000000 00000000 00000000 00000000  ................
+ 0d80 00000000 00000000 00000000 00000000  ................
+ 0d90 00000000 00000000 00000000 00000000  ................
+ 0da0 00000000 00000000 00000000 00000000  ................
+ 0db0 00000000 00000000 00000000 00000000  ................
+ 0dc0 00000000 00000000 00000000 00000000  ................
+ 0dd0 00000000 00000000 00000000 00000000  ................
+ 0de0 00000000 00000000 00000000 00000000  ................
+ 0df0 00000000 00000000 00000000 00000000  ................
+ 0e00 00000000 00000000 00000000 00000000  ................
+ 0e10 00000000 00000000 00000000 00000000  ................
+ 0e20 00000000 00000000 00000000 00000000  ................
+ 0e30 00000000 00000000 00000000 00000000  ................
+ 0e40 00000000 00000000 00000000 00000000  ................
+ 0e50 00000000 00000000 00000000 00000000  ................
+ 0e60 00000000 00000000 00000000 00000000  ................
+ 0e70 00000000 00000000 00000000 00000000  ................
+ 0e80 00000000 00000000 00000000 00000000  ................
+ 0e90 00000000 00000000 00000000 00000000  ................
+ 0ea0 00000000 00000000 00000000 00000000  ................
+ 0eb0 00000000 00000000 00000000 00000000  ................
+ 0ec0 00000000 00000000 00000000 00000000  ................
+ 0ed0 00000000 00000000 00000000 00000000  ................
+ 0ee0 00000000 00000000 00000000 00000000  ................
+ 0ef0 00000000 00000000 00000000 00000000  ................
+ 0f00 00000000 00000000 00000000 00000000  ................
+ 0f10 00000000 00000000 00000000 00000000  ................
+ 0f20 00000000 00000000 00000000 00000000  ................
+ 0f30 00000000 00000000 00000000 00000000  ................
+ 0f40 00000000 00000000 00000000 00000000  ................
+ 0f50 00000000 00000000 00000000 00000000  ................
+ 0f60 00000000 00000000 00000000 00000000  ................
+ 0f70 00000000 00000000 00000000 00000000  ................
+ 0f80 00000000 00000000 00000000 00000000  ................
+ 0f90 00000000 00000000 00000000 00000000  ................
+ 0fa0 00000000 00000000 00000000 00000000  ................
+ 0fb0 00000000 00000000 00000000 00000000  ................
+ 0fc0 00000000 00000000 00000000 00000000  ................
+ 0fd0 00000000 00000000 00000000 00000000  ................
+ 0fe0 00000000 00000000 00000000 00000000  ................
+ 0ff0 00000000 00000000 00000000 00000000  ................
+ 1000 03000000 03000000 00000000 08040000  ................
+ 1010 05000000 06000000 07000000 00000000  ................
+ 1020 00000000 00000000 00000000 00000000  ................
+ 1030 00000000 00000000 00000000 00000000  ................
+ 1040 00000000 00000000 00000000 00000000  ................
+ 1050 00000000 00000000 00000000 00000000  ................
+ 1060 00000000 00000000 00000000 00000000  ................
+ 1070 00000000 00000000 00000000 00000000  ................
+ 1080 00000000 00000000 00000000 00000000  ................
+ 1090 00000000 00000000 00000000 00000000  ................
+ 10a0 00000000 00000000 00000000 00000000  ................
+ 10b0 00000000 00000000 00000000 00000000  ................
+ 10c0 00000000 00000000 00000000 00000000  ................
+ 10d0 00000000 00000000 00000000 00000000  ................
+ 10e0 00000000 00000000 00000000 00000000  ................
+ 10f0 00000000 00000000 00000000 00000000  ................
+ 1100 00000000 00000000 00000000 00000000  ................
+ 1110 00000000 00000000 00000000 00000000  ................
+ 1120 00000000 00000000 00000000 00000000  ................
+ 1130 00000000 00000000 00000000 00000000  ................
+ 1140 00000000 00000000 00000000 00000000  ................
+ 1150 00000000 00000000 00000000 00000000  ................
+ 1160 00000000 00000000 00000000 00000000  ................
+ 1170 00000000 00000000 00000000 00000000  ................
+ 1180 00000000 00000000 00000000 00000000  ................
+ 1190 00000000 00000000 00000000 00000000  ................
+ 11a0 00000000 00000000 00000000 00000000  ................
+ 11b0 00000000 00000000 00000000 00000000  ................
+ 11c0 00000000 00000000 00000000 00000000  ................
+ 11d0 00000000 00000000 00000000 00000000  ................
+ 11e0 00000000 00000000 00000000 00000000  ................
+ 11f0 00000000 00000000 00000000 00000000  ................
+ 1200 00000000 00000000 00000000 00000000  ................
+ 1210 00000000 00000000 00000000 00000000  ................
+ 1220 00000000 00000000 00000000 00000000  ................
+ 1230 00000000 00000000 00000000 00000000  ................
+ 1240 00000000 00000000 00000000 00000000  ................
+ 1250 00000000 00000000 00000000 00000000  ................
+ 1260 00000000 00000000 00000000 00000000  ................
+ 1270 00000000 00000000 00000000 00000000  ................
+ 1280 00000000 00000000 00000000 00000000  ................
+ 1290 00000000 00000000 00000000 00000000  ................
+ 12a0 00000000 00000000 00000000 00000000  ................
+ 12b0 00000000 00000000 00000000 00000000  ................
+ 12c0 00000000 00000000 00000000 00000000  ................
+ 12d0 00000000 00000000 00000000 00000000  ................
+ 12e0 00000000 00000000 00000000 00000000  ................
+ 12f0 00000000 00000000 00000000 00000000  ................
+ 1300 00000000 00000000 00000000 00000000  ................
+ 1310 00000000 00000000 00000000 00000000  ................
+ 1320 00000000 00000000 00000000 00000000  ................
+ 1330 00000000 00000000 00000000 00000000  ................
+ 1340 00000000 00000000 00000000 00000000  ................
+ 1350 00000000 00000000 00000000 00000000  ................
+ 1360 00000000 00000000 00000000 00000000  ................
+ 1370 00000000 00000000 00000000 00000000  ................
+ 1380 00000000 00000000 00000000 00000000  ................
+ 1390 00000000 00000000 00000000 00000000  ................
+ 13a0 00000000 00000000 00000000 00000000  ................
+ 13b0 00000000 00000000 00000000 00000000  ................
+ 13c0 00000000 00000000 00000000 00000000  ................
+ 13d0 00000000 00000000 00000000 00000000  ................
+ 13e0 00000000 00000000 00000000 00000000  ................
+ 13f0 00000000 00000000 00000000 00000000  ................
+ 1400 666f6f00 00000000 00000000 00000000  foo.............
+ 1410 00000000 00000000 00000000 00000000  ................
+ 1420 00000000 00000000 00000000 00000000  ................
+ 1430 00000000 00000000 00000000 00000000  ................
+ 1440 00000000 00000000 00000000 00000000  ................
+ 1450 00000000 00000000 00000000 00000000  ................
+ 1460 00000000 00000000 00000000 00000000  ................
+ 1470 00000000 00000000 00000000 00000000  ................
+ 1480 00000000 00000000 00000000 00000000  ................
+ 1490 00000000 00000000 00000000 00000000  ................
+ 14a0 00000000 00000000 00000000 00000000  ................
+ 14b0 00000000 00000000 00000000 00000000  ................
+ 14c0 00000000 00000000 00000000 00000000  ................
+ 14d0 00000000 00000000 00000000 00000000  ................
+ 14e0 00000000 00000000 00000000 00000000  ................
+ 14f0 00000000 00000000 00000000 00000000  ................
+ 1500 00000000 00000000 00000000 00000000  ................
+ 1510 00000000 00000000 00000000 00000000  ................
+ 1520 00000000 00000000 00000000 00000000  ................
+ 1530 00000000 00000000 00000000 00000000  ................
+ 1540 00000000 00000000 00000000 00000000  ................
+ 1550 00000000 00000000 00000000 00000000  ................
+ 1560 00000000 00000000 00000000 00000000  ................
+ 1570 00000000 00000000 00000000 00000000  ................
+ 1580 00000000 00000000 00000000 00000000  ................
+ 1590 00000000 00000000 00000000 00000000  ................
+ 15a0 00000000 00000000 00000000 00000000  ................
+ 15b0 00000000 00000000 00000000 00000000  ................
+ 15c0 00000000 00000000 00000000 00000000  ................
+ 15d0 00000000 00000000 00000000 00000000  ................
+ 15e0 00000000 00000000 00000000 00000000  ................
+ 15f0 00000000 00000000 00000000 00000000  ................
+ 1600 00000000 00000000 00000000 00000000  ................
+ 1610 00000000 00000000 00000000 00000000  ................
+ 1620 00000000 00000000 00000000 00000000  ................
+ 1630 00000000 00000000 00000000 00000000  ................
+ 1640 00000000 00000000 00000000 00000000  ................
+ 1650 00000000 00000000 00000000 00000000  ................
+ 1660 00000000 00000000 00000000 00000000  ................
+ 1670 00000000 00000000 00000000 00000000  ................
+ 1680 00000000 00000000 00000000 00000000  ................
+ 1690 00000000 00000000 00000000 00000000  ................
+ 16a0 00000000 00000000 00000000 00000000  ................
+ 16b0 00000000 00000000 00000000 00000000  ................
+ 16c0 00000000 00000000 00000000 00000000  ................
+ 16d0 00000000 00000000 00000000 00000000  ................
+ 16e0 00000000 00000000 00000000 00000000  ................
+ 16f0 00000000 00000000 00000000 00000000  ................
+ 1700 00000000 00000000 00000000 00000000  ................
+ 1710 00000000 00000000 00000000 00000000  ................
+ 1720 00000000 00000000 00000000 00000000  ................
+ 1730 00000000 00000000 00000000 00000000  ................
+ 1740 00000000 00000000 00000000 00000000  ................
+ 1750 00000000 00000000 00000000 00000000  ................
+ 1760 00000000 00000000 00000000 00000000  ................
+ 1770 00000000 00000000 00000000 00000000  ................
+ 1780 00000000 00000000 00000000 00000000  ................
+ 1790 00000000 00000000 00000000 00000000  ................
+ 17a0 00000000 00000000 00000000 00000000  ................
+ 17b0 00000000 00000000 00000000 00000000  ................
+ 17c0 00000000 00000000 00000000 00000000  ................
+ 17d0 00000000 00000000 00000000 00000000  ................
+ 17e0 00000000 00000000 00000000 00000000  ................
+ 17f0 00000000 00000000 00000000 00000000  ................
+ 1800 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1810 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1820 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1830 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1840 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1850 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1860 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1870 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1880 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1890 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18a0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18b0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18c0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18d0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18e0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 18f0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1900 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1910 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1920 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1930 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1940 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1950 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1960 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1970 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1980 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1990 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19a0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19b0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19c0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19d0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19e0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 19f0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a00 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a10 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a20 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a30 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a40 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a50 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a60 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a70 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a80 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1a90 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1aa0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1ab0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1ac0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1ad0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1ae0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1af0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b00 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b10 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b20 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b30 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b40 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b50 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b60 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b70 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b80 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1b90 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1ba0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1bb0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1bc0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1bd0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1be0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1bf0 3e3e3e3e 3c3c3c3c 3e3e3e3e 3c3c3c3c  >>>><<<<>>>><<<<
+ 1c00 3e3e3e3e 3c3c3c3c 00000000 00000000  >>>><<<<........
+ 1c10 00000000 00000000 00000000 00000000  ................
+ 1c20 00000000 00000000 00000000 00000000  ................
+ 1c30 00000000 00000000 00000000 00000000  ................
+ 1c40 00000000 00000000 00000000 00000000  ................
+ 1c50 00000000 00000000 00000000 00000000  ................
+ 1c60 00000000 00000000 00000000 00000000  ................
+ 1c70 00000000 00000000 00000000 00000000  ................
+ 1c80 00000000 00000000 00000000 00000000  ................
+ 1c90 00000000 00000000 00000000 00000000  ................
+ 1ca0 00000000 00000000 00000000 00000000  ................
+ 1cb0 00000000 00000000 00000000 00000000  ................
+ 1cc0 00000000 00000000 00000000 00000000  ................
+ 1cd0 00000000 00000000 00000000 00000000  ................
+ 1ce0 00000000 00000000 00000000 00000000  ................
+ 1cf0 00000000 00000000 00000000 00000000  ................
+ 1d00 00000000 00000000 00000000 00000000  ................
+ 1d10 00000000 00000000 00000000 00000000  ................
+ 1d20 00000000 00000000 00000000 00000000  ................
+ 1d30 00000000 00000000 00000000 00000000  ................
+ 1d40 00000000 00000000 00000000 00000000  ................
+ 1d50 00000000 00000000 00000000 00000000  ................
+ 1d60 00000000 00000000 00000000 00000000  ................
+ 1d70 00000000 00000000 00000000 00000000  ................
+ 1d80 00000000 00000000 00000000 00000000  ................
+ 1d90 00000000 00000000 00000000 00000000  ................
+ 1da0 00000000 00000000 00000000 00000000  ................
+ 1db0 00000000 00000000 00000000 00000000  ................
+ 1dc0 00000000 00000000 00000000 00000000  ................
+ 1dd0 00000000 00000000 00000000 00000000  ................
+ 1de0 00000000 00000000 00000000 00000000  ................
+ 1df0 00000000 00000000 00000000 00000000  ................
+ 1e00 00000000 00000000 00000000 00000000  ................
+ 1e10 00000000 00000000 00000000 00000000  ................
+ 1e20 00000000 00000000 00000000 00000000  ................
+ 1e30 00000000 00000000 00000000 00000000  ................
+ 1e40 00000000 00000000 00000000 00000000  ................
+ 1e50 00000000 00000000 00000000 00000000  ................
+ 1e60 00000000 00000000 00000000 00000000  ................
+ 1e70 00000000 00000000 00000000 00000000  ................
+ 1e80 00000000 00000000 00000000 00000000  ................
+ 1e90 00000000 00000000 00000000 00000000  ................
+ 1ea0 00000000 00000000 00000000 00000000  ................
+ 1eb0 00000000 00000000 00000000 00000000  ................
+ 1ec0 00000000 00000000 00000000 00000000  ................
+ 1ed0 00000000 00000000 00000000 00000000  ................
+ 1ee0 00000000 00000000 00000000 00000000  ................
+ 1ef0 00000000 00000000 00000000 00000000  ................
+ 1f00 00000000 00000000 00000000 00000000  ................
+ 1f10 00000000 00000000 00000000 00000000  ................
+ 1f20 00000000 00000000 00000000 00000000  ................
+ 1f30 00000000 00000000 00000000 00000000  ................
+ 1f40 00000000 00000000 00000000 00000000  ................
+ 1f50 00000000 00000000 00000000 00000000  ................
+ 1f60 00000000 00000000 00000000 00000000  ................
+ 1f70 00000000 00000000 00000000 00000000  ................
+ 1f80 00000000 00000000 00000000 00000000  ................
+ 1f90 00000000 00000000 00000000 00000000  ................
+ 1fa0 00000000 00000000 00000000 00000000  ................
+ 1fb0 00000000 00000000 00000000 00000000  ................
+ 1fc0 00000000 00000000 00000000 00000000  ................
+ 1fd0 00000000 00000000 00000000 00000000  ................
+ 1fe0 00000000 00000000 00000000 00000000  ................
+ 1ff0 00000000 00000000 00000000 00000000  ................
diff --git a/binutils/testsuite/binutils-all/pdbfile1 b/binutils/testsuite/binutils-all/pdbfile1
new file mode 100644
index 00000000000..19102815663
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdbfile1
@@ -0,0 +1 @@
+foo
\ No newline at end of file
diff --git a/binutils/testsuite/binutils-all/pdbfile2 b/binutils/testsuite/binutils-all/pdbfile2
new file mode 100644
index 00000000000..81199f273eb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/pdbfile2
@@ -0,0 +1 @@
+>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><<<<
\ No newline at end of file
-- 
2.35.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add pdb archive target
  2022-07-25 23:44 [PATCH] Add pdb archive target Mark Harmstone
@ 2022-08-11 13:02 ` Jan Beulich
  2022-08-11 23:26   ` Mark Harmstone
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2022-08-11 13:02 UTC (permalink / raw)
  To: Mark Harmstone; +Cc: binutils

On 26.07.2022 01:44, Mark Harmstone wrote:
> This adds support for the "Multi-Stream Format" container format that
> MSVC uses for its PDB debugging files, as documented at
> https://llvm.org/docs/PDB/MsfFile.html.

Looking at binutils/testsuite/binutils-all/pdb*.d I wonder what "support"
here means: What is dumped is the binary contents of the file (claimed
to be coming from section .data) rather than the inner file structure.
Also this looks to cover only one of several flavors/versions, which may
want calling out here and which also may influence the naming of certain
things throughout the patch.

> This is a prerequisite for gdb to be able to read Microsoft's debug
> files, and for gcc and ld to generate debugging info that can be read by
> Microsoft's tools.

Are there plans in any of those three directions?

> --- a/bfd/config.bfd
> +++ b/bfd/config.bfd
> @@ -388,7 +388,7 @@ case "${targ}" in
>      ;;
>    arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*)
>      targ_defvec=arm_pe_wince_le_vec
> -    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec"
> +    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec pdb_vec"
>      targ_underscore=no
>      targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX"
>      ;;
> @@ -708,7 +708,7 @@ case "${targ}" in
>      ;;
>    x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin)
>      targ_defvec=x86_64_pe_vec
> -    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
> +    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec pdb_vec"

I'm not sure adding this as a default for -pe and -pep is appropriate; I
certainly agree with MingW and Cygwin. Same for ix86's -pe then, whereas
I'm unclear about what arm*-*-cegcc* is.

> --- a/bfd/configure.ac
> +++ b/bfd/configure.ac
> @@ -416,7 +416,7 @@ tb=
>  
>  elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo
>       dwarf1.lo dwarf2.lo"
> -coffgen="coffgen.lo dwarf2.lo"
> +coffgen="coffgen.lo dwarf2.lo pdb.lo"
>  coff="cofflink.lo $coffgen"
>  ecoff="ecofflink.lo $coffgen"
>  xcoff="xcofflink.lo $coffgen"

Similarly here - is this really relevant to ecoff and xcoff as well?
I'm not even convinced this wants universally tying to coff.

> --- /dev/null
> +++ b/bfd/pdb.c
> @@ -0,0 +1,804 @@
> +/* BFD back-end for PDB Multi-Stream Format archives.
> +   Copyright (C) 2022 Free Software Foundation, Inc.
> +
> +   This file is part of BFD, the Binary File Descriptor library.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +   MA 02110-1301, USA. */
> +
> +/* This describes the MSF file archive format, which is used for the
> +   PDB debug info generated by MSVC. See https://llvm.org/docs/PDB/MsfFile.html
> +   for a full description of the format. */
> +
> +#include "sysdep.h"
> +#include "bfd.h"
> +#include "libbfd.h"
> +
> +/* "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0\0" */
> +static const uint8_t pdb_magic[] =
> +{ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
> +  0x74, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, 0x20,
> +  0x4d, 0x53, 0x46, 0x20, 0x37, 0x2e, 0x30, 0x30,
> +  0x0d, 0x0a, 0x1a, 0x44, 0x53, 0x00, 0x00, 0x00 };
> +
> +#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
> +
> +static bfd_cleanup
> +pdb_archive_p (bfd *abfd)
> +{
> +  int ret;
> +  char magic[sizeof (pdb_magic)];
> +
> +  ret = bfd_bread (magic, sizeof (magic), abfd);
> +  if (ret != sizeof (magic))
> +    {
> +      bfd_set_error (bfd_error_wrong_format);
> +      return NULL;
> +    }
> +
> +  if (memcmp (magic, pdb_magic, sizeof (magic)))
> +    {
> +      bfd_set_error (bfd_error_wrong_format);
> +      return NULL;
> +    }
> +
> +  return _bfd_no_cleanup;
> +}
> +
> +static bfd *
> +pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
> +{
> +  char int_buf[sizeof (uint32_t)];
> +  uint32_t block_size, block_map_addr, block, num_files;
> +  uint32_t first_dir_block, dir_offset, file_size, block_off, left;
> +  char name[10];
> +  bfd *file;
> +  char *buf;
> +
> +  /* get block_size */
> +
> +  if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
> +    return NULL;
> +
> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +    {
> +      bfd_set_error (bfd_error_malformed_archive);
> +      return NULL;
> +    }
> +
> +  block_size = bfd_getl32 (int_buf);
> +
> +  /* get block_map_addr */
> +
> +  if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
> +    return NULL;
> +
> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +    {
> +      bfd_set_error (bfd_error_malformed_archive);
> +      return NULL;
> +    }
> +
> +  block_map_addr = bfd_getl32 (int_buf);
> +
> +  /* get num_files */
> +
> +  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
> +    return NULL;
> +
> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +    {
> +      bfd_set_error (bfd_error_malformed_archive);
> +      return NULL;
> +    }
> +
> +  first_dir_block = bfd_getl32 (int_buf);
> +
> +  if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
> +    return NULL;
> +
> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +    {
> +      bfd_set_error (bfd_error_malformed_archive);
> +      return NULL;
> +    }
> +
> +  num_files = bfd_getl32 (int_buf);
> +
> +  if (sym_index >= num_files)
> +    {
> +      bfd_set_error (bfd_error_no_more_archived_files);
> +      return NULL;
> +    }
> +
> +  /* read file size */
> +
> +  dir_offset = sizeof (uint32_t) * (sym_index + 1);
> +
> +  if (dir_offset >= block_size)
> +    {
> +      uint32_t block_map_addr_off;
> +
> +      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
> +
> +      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
> +		    SEEK_SET))
> +	return NULL;
> +
> +      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +	{
> +	  bfd_set_error (bfd_error_malformed_archive);
> +	  return NULL;
> +	}
> +
> +      block = bfd_getl32 (int_buf);
> +    }
> +  else
> +    {
> +      block = first_dir_block;
> +    }
> +
> +  if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
> +		SEEK_SET))
> +    return NULL;
> +
> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
> +    {
> +      bfd_set_error (bfd_error_malformed_archive);
> +      return NULL;
> +    }
> +
> +  file_size = bfd_getl32 (int_buf);
> +
> +  /* create BFD */
> +
> +  sprintf (name, "%04lx", sym_index);

Is there a reason for this 4-or-more digits naming of the file? Would
it make sense to use 8 digits (beyond which the index apparently
cannot grow)?

> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/pdb.exp
> @@ -0,0 +1,157 @@
> +#   Copyright (C) 2022 Free Software Foundation, Inc.
> +
> +# This file is part of the GNU Binutils.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +proc pdb_archive_1 { } {
> +    global AR
> +    global OBJDUMP
> +    global srcdir
> +    global subdir
> +
> +    set testname "pdb archive 1"
> +
> +    file delete tmpdir/test.pdb
> +
> +    # add short file (less than block size)
> +
> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile1"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
> +    if ![string match "rw-r--r-- 0/0      3 *0000*" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
> +    set exp [file_contents "$srcdir/$subdir/pdb1.d"]
> +    if ![string equal $got $exp] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "x tmpdir/test.pdb 0000 --output=tmpdir"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [file_contents tmpdir/0000]
> +    set exp [file_contents "$srcdir/$subdir/pdbfile1"]
> +    if ![string equal $got $exp] {
> +	fail $testname
> +	return
> +    }
> +
> +    pass $testname
> +}
> +
> +proc pdb_archive_2 { } {
> +    global AR
> +    global OBJDUMP
> +    global srcdir
> +    global subdir
> +
> +    set testname "pdb archive 2"
> +
> +    # add empty file
> +
> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb /dev/null"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
> +    if ![string match "*\nrw-r--r-- 0/0      0 *0001*" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
> +    set exp [file_contents "$srcdir/$subdir/pdb2.d"]
> +    if ![string equal $got $exp] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "x tmpdir/test.pdb 0001 --output=tmpdir"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [file_contents tmpdir/0001]
> +    if ![string equal $got ""] {
> +	fail $testname
> +	return
> +    }
> +
> +    pass $testname
> +}
> +
> +proc pdb_archive_3 { } {
> +    global AR
> +    global OBJDUMP
> +    global srcdir
> +    global subdir
> +
> +    set testname "pdb archive 3"
> +
> +    # add long file (greater than block size)
> +
> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile2"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
> +    if ![string match "*\nrw-r--r-- 0/0   1032 *0002*" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
> +    set exp [file_contents "$srcdir/$subdir/pdb3.d"]
> +    if ![string equal $got $exp] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [binutils_run $AR "x tmpdir/test.pdb 0002 --output=tmpdir"]
> +    if ![string match "" $got] {
> +	fail $testname
> +	return
> +    }
> +
> +    set got [file_contents tmpdir/0002]
> +    set exp [file_contents "$srcdir/$subdir/pdbfile2"]
> +    if ![string equal $got $exp] {
> +	fail $testname
> +	return
> +    }
> +
> +    pass $testname
> +}
> +
> +pdb_archive_1
> +pdb_archive_2
> +pdb_archive_3

The three functions look pretty similar. Any chance of folding them into
just one, suitably parametrized?

Jan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add pdb archive target
  2022-08-11 13:02 ` Jan Beulich
@ 2022-08-11 23:26   ` Mark Harmstone
  2022-08-12  6:14     ` Jan Beulich
  2022-08-15 19:27     ` NightStrike
  0 siblings, 2 replies; 6+ messages in thread
From: Mark Harmstone @ 2022-08-11 23:26 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

Thanks Jan.

On 11/8/22 14:02, Jan Beulich wrote:
 > On 26.07.2022 01:44, Mark Harmstone wrote:
 >> This adds support for the "Multi-Stream Format" container format that
 >> MSVC uses for its PDB debugging files, as documented at
 >> https://llvm.org/docs/PDB/MsfFile.html.
 >
 > Looking at binutils/testsuite/binutils-all/pdb*.d I wonder what "support"
 > here means: What is dumped is the binary contents of the file (claimed
 > to be coming from section .data) rather than the inner file structure.

I'm not quite sure what you're getting at. This is purely for PDB files as
archives, there is no inner file structure. The tests check that the hex
dump of the files matches one possible way to represent an archive of the
dummy files.

 > Also this looks to cover only one of several flavors/versions, which may
 > want calling out here and which also may influence the naming of certain
 > things throughout the patch.

I assume you're basing this off the "Microsoft C/C++ MSF 7.00" in the header.
MSVC++ 7 came out in 2002, and it's been the same since... there's only one
living version of the format.

 >> This is a prerequisite for gdb to be able to read Microsoft's debug
 >> files, and for gcc and ld to generate debugging info that can be read by
 >> Microsoft's tools.
 >
 > Are there plans in any of those three directions?

Yes! See https://github.com/maharmstone/binutils-gdb for my messy dev repo
which adds PDB support for ld - it needs cleaning up and rebasing, but it's
fully functional.

I submitted patches to gcc last year, which were rejected because they'd
changed their policy on how debug hooks should work, and I'd written it the
old way. See https://www.phoronix.com/news/GCC-PE-Specific-CodeView.

I've since come round to the view that it'd be pretty useless having the
patches in gcc before they're in ld, which is why I've not resubmitted them.

 >
 >> --- a/bfd/config.bfd
 >> +++ b/bfd/config.bfd
 >> @@ -388,7 +388,7 @@ case "${targ}" in
 >>      ;;
 >>    arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*)
 >>      targ_defvec=arm_pe_wince_le_vec
 >> -    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec"
 >> +    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec pdb_vec"
 >>      targ_underscore=no
 >>      targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX"
 >>      ;;
 >> @@ -708,7 +708,7 @@ case "${targ}" in
 >>      ;;
 >>    x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin)
 >>      targ_defvec=x86_64_pe_vec
 >> -    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
 >> +    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec pdb_vec"
 >
 > I'm not sure adding this as a default for -pe and -pep is appropriate; I
 > certainly agree with MingW and Cygwin.

I don't agree: the format's specific to PE files, not specific to Windows.
There's no reason why you can't have PDB files linked to EFI images (and
Microsoft's bootloaders do just that.)

 > Same for ix86's -pe then, whereas I'm unclear about what arm*-*-cegcc* is.

I'm not sure either. Happy to nix it for Windows CE.

 >> --- a/bfd/configure.ac
 >> +++ b/bfd/configure.ac
 >> @@ -416,7 +416,7 @@ tb=
 >>
 >>  elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo
 >>       dwarf1.lo dwarf2.lo"
 >> -coffgen="coffgen.lo dwarf2.lo"
 >> +coffgen="coffgen.lo dwarf2.lo pdb.lo"
 >>  coff="cofflink.lo $coffgen"
 >>  ecoff="ecofflink.lo $coffgen"
 >>  xcoff="xcofflink.lo $coffgen"
 >
 > Similarly here - is this really relevant to ecoff and xcoff as well?
 > I'm not even convinced this wants universally tying to coff.

I think quite possibly that I naively thought that COFF == PE, when I
now realize that's not the case...

 >> --- /dev/null
 >> +++ b/bfd/pdb.c
 >> @@ -0,0 +1,804 @@
 >> +/* BFD back-end for PDB Multi-Stream Format archives.
 >> +   Copyright (C) 2022 Free Software Foundation, Inc.
 >> +
 >> +   This file is part of BFD, the Binary File Descriptor library.
 >> +
 >> +   This program is free software; you can redistribute it and/or modify
 >> +   it under the terms of the GNU General Public License as published by
 >> +   the Free Software Foundation; either version 3 of the License, or
 >> +   (at your option) any later version.
 >> +
 >> +   This program is distributed in the hope that it will be useful,
 >> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 >> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 >> +   GNU General Public License for more details.
 >> +
 >> +   You should have received a copy of the GNU General Public License
 >> +   along with this program; if not, write to the Free Software
 >> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
 >> +   MA 02110-1301, USA. */
 >> +
 >> +/* This describes the MSF file archive format, which is used for the
 >> +   PDB debug info generated by MSVC. See https://llvm.org/docs/PDB/MsfFile.html
 >> +   for a full description of the format. */
 >> +
 >> +#include "sysdep.h"
 >> +#include "bfd.h"
 >> +#include "libbfd.h"
 >> +
 >> +/* "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0\0" */
 >> +static const uint8_t pdb_magic[] =
 >> +{ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
 >> +  0x74, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, 0x20,
 >> +  0x4d, 0x53, 0x46, 0x20, 0x37, 0x2e, 0x30, 0x30,
 >> +  0x0d, 0x0a, 0x1a, 0x44, 0x53, 0x00, 0x00, 0x00 };
 >> +
 >> +#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
 >> +
 >> +static bfd_cleanup
 >> +pdb_archive_p (bfd *abfd)
 >> +{
 >> +  int ret;
 >> +  char magic[sizeof (pdb_magic)];
 >> +
 >> +  ret = bfd_bread (magic, sizeof (magic), abfd);
 >> +  if (ret != sizeof (magic))
 >> +    {
 >> +      bfd_set_error (bfd_error_wrong_format);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  if (memcmp (magic, pdb_magic, sizeof (magic)))
 >> +    {
 >> +      bfd_set_error (bfd_error_wrong_format);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  return _bfd_no_cleanup;
 >> +}
 >> +
 >> +static bfd *
 >> +pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
 >> +{
 >> +  char int_buf[sizeof (uint32_t)];
 >> +  uint32_t block_size, block_map_addr, block, num_files;
 >> +  uint32_t first_dir_block, dir_offset, file_size, block_off, left;
 >> +  char name[10];
 >> +  bfd *file;
 >> +  char *buf;
 >> +
 >> +  /* get block_size */
 >> +
 >> +  if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
 >> +    return NULL;
 >> +
 >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  block_size = bfd_getl32 (int_buf);
 >> +
 >> +  /* get block_map_addr */
 >> +
 >> +  if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
 >> +    return NULL;
 >> +
 >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  block_map_addr = bfd_getl32 (int_buf);
 >> +
 >> +  /* get num_files */
 >> +
 >> +  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
 >> +    return NULL;
 >> +
 >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  first_dir_block = bfd_getl32 (int_buf);
 >> +
 >> +  if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
 >> +    return NULL;
 >> +
 >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  num_files = bfd_getl32 (int_buf);
 >> +
 >> +  if (sym_index >= num_files)
 >> +    {
 >> +      bfd_set_error (bfd_error_no_more_archived_files);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  /* read file size */
 >> +
 >> +  dir_offset = sizeof (uint32_t) * (sym_index + 1);
 >> +
 >> +  if (dir_offset >= block_size)
 >> +    {
 >> +      uint32_t block_map_addr_off;
 >> +
 >> +      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
 >> +
 >> +      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
 >> +            SEEK_SET))
 >> +    return NULL;
 >> +
 >> +      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +      block = bfd_getl32 (int_buf);
 >> +    }
 >> +  else
 >> +    {
 >> +      block = first_dir_block;
 >> +    }
 >> +
 >> +  if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
 >> +        SEEK_SET))
 >> +    return NULL;
 >> +
 >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
 >> +    {
 >> +      bfd_set_error (bfd_error_malformed_archive);
 >> +      return NULL;
 >> +    }
 >> +
 >> +  file_size = bfd_getl32 (int_buf);
 >> +
 >> +  /* create BFD */
 >> +
 >> +  sprintf (name, "%04lx", sym_index);
 >
 > Is there a reason for this 4-or-more digits naming of the file? Would
 > it make sense to use 8 digits (beyond which the index apparently
 > cannot grow)?

In practice, 4 digits is plenty. The number of files in the archive is
proportional to the number of object files linked into the image... for the
NT kernel, which is probably the most complicated EXE out there, the PDB
has 1,100 files. I can't imagine anybody will ever go over 65,535 - and it's
not visible anyway, unless you play around with ar.

 >
 >> --- /dev/null
 >> +++ b/binutils/testsuite/binutils-all/pdb.exp
 >> @@ -0,0 +1,157 @@
 >> +#   Copyright (C) 2022 Free Software Foundation, Inc.
 >> +
 >> +# This file is part of the GNU Binutils.
 >> +#
 >> +# This program is free software; you can redistribute it and/or modify
 >> +# it under the terms of the GNU General Public License as published by
 >> +# the Free Software Foundation; either version 3 of the License, or
 >> +# (at your option) any later version.
 >> +#
 >> +# This program is distributed in the hope that it will be useful,
 >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 >> +# GNU General Public License for more details.
 >> +#
 >> +# You should have received a copy of the GNU General Public License
 >> +# along with this program; if not, write to the Free Software
 >> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 >> +
 >> +proc pdb_archive_1 { } {
 >> +    global AR
 >> +    global OBJDUMP
 >> +    global srcdir
 >> +    global subdir
 >> +
 >> +    set testname "pdb archive 1"
 >> +
 >> +    file delete tmpdir/test.pdb
 >> +
 >> +    # add short file (less than block size)
 >> +
 >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile1"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
 >> +    if ![string match "rw-r--r-- 0/0      3 *0000*" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
 >> +    set exp [file_contents "$srcdir/$subdir/pdb1.d"]
 >> +    if ![string equal $got $exp] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0000 --output=tmpdir"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [file_contents tmpdir/0000]
 >> +    set exp [file_contents "$srcdir/$subdir/pdbfile1"]
 >> +    if ![string equal $got $exp] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    pass $testname
 >> +}
 >> +
 >> +proc pdb_archive_2 { } {
 >> +    global AR
 >> +    global OBJDUMP
 >> +    global srcdir
 >> +    global subdir
 >> +
 >> +    set testname "pdb archive 2"
 >> +
 >> +    # add empty file
 >> +
 >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb /dev/null"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
 >> +    if ![string match "*\nrw-r--r-- 0/0      0 *0001*" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
 >> +    set exp [file_contents "$srcdir/$subdir/pdb2.d"]
 >> +    if ![string equal $got $exp] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0001 --output=tmpdir"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [file_contents tmpdir/0001]
 >> +    if ![string equal $got ""] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    pass $testname
 >> +}
 >> +
 >> +proc pdb_archive_3 { } {
 >> +    global AR
 >> +    global OBJDUMP
 >> +    global srcdir
 >> +    global subdir
 >> +
 >> +    set testname "pdb archive 3"
 >> +
 >> +    # add long file (greater than block size)
 >> +
 >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile2"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
 >> +    if ![string match "*\nrw-r--r-- 0/0   1032 *0002*" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
 >> +    set exp [file_contents "$srcdir/$subdir/pdb3.d"]
 >> +    if ![string equal $got $exp] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0002 --output=tmpdir"]
 >> +    if ![string match "" $got] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    set got [file_contents tmpdir/0002]
 >> +    set exp [file_contents "$srcdir/$subdir/pdbfile2"]
 >> +    if ![string equal $got $exp] {
 >> +    fail $testname
 >> +    return
 >> +    }
 >> +
 >> +    pass $testname
 >> +}
 >> +
 >> +pdb_archive_1
 >> +pdb_archive_2
 >> +pdb_archive_3
 >
 > The three functions look pretty similar. Any chance of folding them into
 > just one, suitably parametrized?

I'm not sure - to my mind, that would imply that the functions were
independent, when they need to be run one after the other.

I think we do need to test a small file, an empty file, and a long file, but
could I get away with just having one test, which adds all three files?

Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add pdb archive target
  2022-08-11 23:26   ` Mark Harmstone
@ 2022-08-12  6:14     ` Jan Beulich
  2022-08-15 17:06       ` Mark Harmstone
  2022-08-15 19:27     ` NightStrike
  1 sibling, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2022-08-12  6:14 UTC (permalink / raw)
  To: Mark Harmstone; +Cc: binutils

On 12.08.2022 01:26, Mark Harmstone wrote:
> On 11/8/22 14:02, Jan Beulich wrote:
>  > On 26.07.2022 01:44, Mark Harmstone wrote:
>  >> This adds support for the "Multi-Stream Format" container format that
>  >> MSVC uses for its PDB debugging files, as documented at
>  >> https://llvm.org/docs/PDB/MsfFile.html.
>  >
>  > Looking at binutils/testsuite/binutils-all/pdb*.d I wonder what "support"
>  > here means: What is dumped is the binary contents of the file (claimed
>  > to be coming from section .data) rather than the inner file structure.
> 
> I'm not quite sure what you're getting at. This is purely for PDB files as
> archives, there is no inner file structure. The tests check that the hex
> dump of the files matches one possible way to represent an archive of the
> dummy files.

If it's an archive (and hence can hold multiple files), then surely it
has an internal structure. Or else your patch also wouldn't be needed,
btw. Dumping a *.a file gives you an idea what's in the file. I would
have expected the same for *.pdb (to a reasonable extent at least).
One might then easily see number of members, block size, etc. Perhaps
even the sizes of the individual members.

>  > Also this looks to cover only one of several flavors/versions, which may
>  > want calling out here and which also may influence the naming of certain
>  > things throughout the patch.
> 
> I assume you're basing this off the "Microsoft C/C++ MSF 7.00" in the header.
> MSVC++ 7 came out in 2002, and it's been the same since... there's only one
> living version of the format.

Well, bad luck with my picking of an older version of VC then - I
ended up checking a VC6 PDB file, which is version 2.00.

>  >> --- /dev/null
>  >> +++ b/bfd/pdb.c
>  >> @@ -0,0 +1,804 @@
>  >> +/* BFD back-end for PDB Multi-Stream Format archives.
>  >> +   Copyright (C) 2022 Free Software Foundation, Inc.
>  >> +
>  >> +   This file is part of BFD, the Binary File Descriptor library.
>  >> +
>  >> +   This program is free software; you can redistribute it and/or modify
>  >> +   it under the terms of the GNU General Public License as published by
>  >> +   the Free Software Foundation; either version 3 of the License, or
>  >> +   (at your option) any later version.
>  >> +
>  >> +   This program is distributed in the hope that it will be useful,
>  >> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>  >> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  >> +   GNU General Public License for more details.
>  >> +
>  >> +   You should have received a copy of the GNU General Public License
>  >> +   along with this program; if not, write to the Free Software
>  >> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
>  >> +   MA 02110-1301, USA. */
>  >> +
>  >> +/* This describes the MSF file archive format, which is used for the
>  >> +   PDB debug info generated by MSVC. See https://llvm.org/docs/PDB/MsfFile.html
>  >> +   for a full description of the format. */
>  >> +
>  >> +#include "sysdep.h"
>  >> +#include "bfd.h"
>  >> +#include "libbfd.h"
>  >> +
>  >> +/* "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0\0" */
>  >> +static const uint8_t pdb_magic[] =
>  >> +{ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
>  >> +  0x74, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, 0x20,
>  >> +  0x4d, 0x53, 0x46, 0x20, 0x37, 0x2e, 0x30, 0x30,
>  >> +  0x0d, 0x0a, 0x1a, 0x44, 0x53, 0x00, 0x00, 0x00 };
>  >> +
>  >> +#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
>  >> +
>  >> +static bfd_cleanup
>  >> +pdb_archive_p (bfd *abfd)
>  >> +{
>  >> +  int ret;
>  >> +  char magic[sizeof (pdb_magic)];
>  >> +
>  >> +  ret = bfd_bread (magic, sizeof (magic), abfd);
>  >> +  if (ret != sizeof (magic))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_wrong_format);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  if (memcmp (magic, pdb_magic, sizeof (magic)))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_wrong_format);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  return _bfd_no_cleanup;
>  >> +}
>  >> +
>  >> +static bfd *
>  >> +pdb_get_elt_at_index (bfd *abfd, symindex sym_index)
>  >> +{
>  >> +  char int_buf[sizeof (uint32_t)];
>  >> +  uint32_t block_size, block_map_addr, block, num_files;
>  >> +  uint32_t first_dir_block, dir_offset, file_size, block_off, left;
>  >> +  char name[10];
>  >> +  bfd *file;
>  >> +  char *buf;
>  >> +
>  >> +  /* get block_size */
>  >> +
>  >> +  if (bfd_seek (abfd, sizeof (pdb_magic), SEEK_SET))
>  >> +    return NULL;
>  >> +
>  >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  block_size = bfd_getl32 (int_buf);
>  >> +
>  >> +  /* get block_map_addr */
>  >> +
>  >> +  if (bfd_seek (abfd, 4 * sizeof (uint32_t), SEEK_CUR))
>  >> +    return NULL;
>  >> +
>  >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  block_map_addr = bfd_getl32 (int_buf);
>  >> +
>  >> +  /* get num_files */
>  >> +
>  >> +  if (bfd_seek (abfd, block_map_addr * block_size, SEEK_SET))
>  >> +    return NULL;
>  >> +
>  >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  first_dir_block = bfd_getl32 (int_buf);
>  >> +
>  >> +  if (bfd_seek (abfd, first_dir_block * block_size, SEEK_SET))
>  >> +    return NULL;
>  >> +
>  >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  num_files = bfd_getl32 (int_buf);
>  >> +
>  >> +  if (sym_index >= num_files)
>  >> +    {
>  >> +      bfd_set_error (bfd_error_no_more_archived_files);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  /* read file size */
>  >> +
>  >> +  dir_offset = sizeof (uint32_t) * (sym_index + 1);
>  >> +
>  >> +  if (dir_offset >= block_size)
>  >> +    {
>  >> +      uint32_t block_map_addr_off;
>  >> +
>  >> +      block_map_addr_off = ((dir_offset / block_size) * sizeof (uint32_t));
>  >> +
>  >> +      if (bfd_seek (abfd, (block_map_addr * block_size) + block_map_addr_off,
>  >> +            SEEK_SET))
>  >> +    return NULL;
>  >> +
>  >> +      if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +      block = bfd_getl32 (int_buf);
>  >> +    }
>  >> +  else
>  >> +    {
>  >> +      block = first_dir_block;
>  >> +    }
>  >> +
>  >> +  if (bfd_seek (abfd, (block * block_size) + (dir_offset % block_size),
>  >> +        SEEK_SET))
>  >> +    return NULL;
>  >> +
>  >> +  if (bfd_bread (int_buf, sizeof (uint32_t), abfd) != sizeof (uint32_t))
>  >> +    {
>  >> +      bfd_set_error (bfd_error_malformed_archive);
>  >> +      return NULL;
>  >> +    }
>  >> +
>  >> +  file_size = bfd_getl32 (int_buf);
>  >> +
>  >> +  /* create BFD */
>  >> +
>  >> +  sprintf (name, "%04lx", sym_index);
>  >
>  > Is there a reason for this 4-or-more digits naming of the file? Would
>  > it make sense to use 8 digits (beyond which the index apparently
>  > cannot grow)?
> 
> In practice, 4 digits is plenty. The number of files in the archive is
> proportional to the number of object files linked into the image... for the
> NT kernel, which is probably the most complicated EXE out there, the PDB
> has 1,100 files. I can't imagine anybody will ever go over 65,535 - and it's
> not visible anyway, unless you play around with ar.

Since you know the number of files in the archive, may I suggest that you
base the number of digits on that number of members, such that all
elements would be extracted to files with names of identical length?

>  >> --- /dev/null
>  >> +++ b/binutils/testsuite/binutils-all/pdb.exp
>  >> @@ -0,0 +1,157 @@
>  >> +#   Copyright (C) 2022 Free Software Foundation, Inc.
>  >> +
>  >> +# This file is part of the GNU Binutils.
>  >> +#
>  >> +# This program is free software; you can redistribute it and/or modify
>  >> +# it under the terms of the GNU General Public License as published by
>  >> +# the Free Software Foundation; either version 3 of the License, or
>  >> +# (at your option) any later version.
>  >> +#
>  >> +# This program is distributed in the hope that it will be useful,
>  >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>  >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  >> +# GNU General Public License for more details.
>  >> +#
>  >> +# You should have received a copy of the GNU General Public License
>  >> +# along with this program; if not, write to the Free Software
>  >> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
>  >> +
>  >> +proc pdb_archive_1 { } {
>  >> +    global AR
>  >> +    global OBJDUMP
>  >> +    global srcdir
>  >> +    global subdir
>  >> +
>  >> +    set testname "pdb archive 1"
>  >> +
>  >> +    file delete tmpdir/test.pdb
>  >> +
>  >> +    # add short file (less than block size)
>  >> +
>  >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile1"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
>  >> +    if ![string match "rw-r--r-- 0/0      3 *0000*" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
>  >> +    set exp [file_contents "$srcdir/$subdir/pdb1.d"]
>  >> +    if ![string equal $got $exp] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0000 --output=tmpdir"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [file_contents tmpdir/0000]
>  >> +    set exp [file_contents "$srcdir/$subdir/pdbfile1"]
>  >> +    if ![string equal $got $exp] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    pass $testname
>  >> +}
>  >> +
>  >> +proc pdb_archive_2 { } {
>  >> +    global AR
>  >> +    global OBJDUMP
>  >> +    global srcdir
>  >> +    global subdir
>  >> +
>  >> +    set testname "pdb archive 2"
>  >> +
>  >> +    # add empty file
>  >> +
>  >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb /dev/null"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
>  >> +    if ![string match "*\nrw-r--r-- 0/0      0 *0001*" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
>  >> +    set exp [file_contents "$srcdir/$subdir/pdb2.d"]
>  >> +    if ![string equal $got $exp] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0001 --output=tmpdir"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [file_contents tmpdir/0001]
>  >> +    if ![string equal $got ""] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    pass $testname
>  >> +}
>  >> +
>  >> +proc pdb_archive_3 { } {
>  >> +    global AR
>  >> +    global OBJDUMP
>  >> +    global srcdir
>  >> +    global subdir
>  >> +
>  >> +    set testname "pdb archive 3"
>  >> +
>  >> +    # add long file (greater than block size)
>  >> +
>  >> +    set got [binutils_run $AR "cr --target=pdb tmpdir/test.pdb $srcdir/$subdir/pdbfile2"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "tv tmpdir/test.pdb"]
>  >> +    if ![string match "*\nrw-r--r-- 0/0   1032 *0002*" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $OBJDUMP "-s --target=binary tmpdir/test.pdb"]
>  >> +    set exp [file_contents "$srcdir/$subdir/pdb3.d"]
>  >> +    if ![string equal $got $exp] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [binutils_run $AR "x tmpdir/test.pdb 0002 --output=tmpdir"]
>  >> +    if ![string match "" $got] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    set got [file_contents tmpdir/0002]
>  >> +    set exp [file_contents "$srcdir/$subdir/pdbfile2"]
>  >> +    if ![string equal $got $exp] {
>  >> +    fail $testname
>  >> +    return
>  >> +    }
>  >> +
>  >> +    pass $testname
>  >> +}
>  >> +
>  >> +pdb_archive_1
>  >> +pdb_archive_2
>  >> +pdb_archive_3
>  >
>  > The three functions look pretty similar. Any chance of folding them into
>  > just one, suitably parametrized?
> 
> I'm not sure - to my mind, that would imply that the functions were
> independent, when they need to be run one after the other.

Oh, that wasn't obvious to me at all. Would you mind adding a comment to
that effect then?

> I think we do need to test a small file, an empty file, and a long file, but
> could I get away with just having one test, which adds all three files?

This certainly makes sense.

Jan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add pdb archive target
  2022-08-12  6:14     ` Jan Beulich
@ 2022-08-15 17:06       ` Mark Harmstone
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Harmstone @ 2022-08-15 17:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On 12/8/22 07:14, Jan Beulich wrote:
 > On 12.08.2022 01:26, Mark Harmstone wrote:
 >> On 11/8/22 14:02, Jan Beulich wrote:
 >>  > On 26.07.2022 01:44, Mark Harmstone wrote:
 >>  >> This adds support for the "Multi-Stream Format" container format that
 >>  >> MSVC uses for its PDB debugging files, as documented at
 >>  >> https://llvm.org/docs/PDB/MsfFile.html.
 >>  >
 >>  > Looking at binutils/testsuite/binutils-all/pdb*.d I wonder what "support"
 >>  > here means: What is dumped is the binary contents of the file (claimed
 >>  > to be coming from section .data) rather than the inner file structure.
 >>
 >> I'm not quite sure what you're getting at. This is purely for PDB files as
 >> archives, there is no inner file structure. The tests check that the hex
 >> dump of the files matches one possible way to represent an archive of the
 >> dummy files.
 >
 > If it's an archive (and hence can hold multiple files), then surely it
 > has an internal structure. Or else your patch also wouldn't be needed,
 > btw. Dumping a *.a file gives you an idea what's in the file. I would
 > have expected the same for *.pdb (to a reasonable extent at least).
 > One might then easily see number of members, block size, etc. Perhaps
 > even the sizes of the individual members.

Right, I see what you mean - so that "objdump -x" gives you something
interesting...

 >>  > Is there a reason for this 4-or-more digits naming of the file? Would
 >>  > it make sense to use 8 digits (beyond which the index apparently
 >>  > cannot grow)?
 >>
 >> In practice, 4 digits is plenty. The number of files in the archive is
 >> proportional to the number of object files linked into the image... for the
 >> NT kernel, which is probably the most complicated EXE out there, the PDB
 >> has 1,100 files. I can't imagine anybody will ever go over 65,535 - and it's
 >> not visible anyway, unless you play around with ar.
 >
 > Since you know the number of files in the archive, may I suggest that you
 > base the number of digits on that number of members, such that all
 > elements would be extracted to files with names of identical length?

Yep, good idea.

Thanks for your help Jan - I'll submit another patch incorporating your
suggestions shortly.

Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add pdb archive target
  2022-08-11 23:26   ` Mark Harmstone
  2022-08-12  6:14     ` Jan Beulich
@ 2022-08-15 19:27     ` NightStrike
  1 sibling, 0 replies; 6+ messages in thread
From: NightStrike @ 2022-08-15 19:27 UTC (permalink / raw)
  To: Mark Harmstone; +Cc: Jan Beulich, binutils

On Thu, Aug 11, 2022, 19:27 Mark Harmstone <mark@harmstone.com> wrote:

> In practice, 4 digits is plenty. The number of files in the archive is
> proportional to the number of object files linked into the image... for the
> NT kernel, which is probably the most complicated EXE out there, the PDB
> has 1,100 files. I can't imagine anybody will ever go over 65,535 - and
> it's
> not visible anyway, unless you play around with ar.
>

The gcj Java runtime did, before it was removed from gcc. I recall it being
a big issue that that library had that much in it. I forget how, or if, it
was solved.

>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-08-15 19:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-25 23:44 [PATCH] Add pdb archive target Mark Harmstone
2022-08-11 13:02 ` Jan Beulich
2022-08-11 23:26   ` Mark Harmstone
2022-08-12  6:14     ` Jan Beulich
2022-08-15 17:06       ` Mark Harmstone
2022-08-15 19:27     ` NightStrike

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).