public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] ld: Add section contributions substream to PDB files
@ 2022-11-11  3:30 Mark Harmstone
  2022-11-22 14:12 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Harmstone @ 2022-11-11  3:30 UTC (permalink / raw)
  To: binutils; +Cc: Mark Harmstone

---
 ld/pdb.c                                  | 112 +++++++++++++++++++++-
 ld/pdb.h                                  |   2 +
 ld/testsuite/ld-pe/pdb.exp                |  29 +++++-
 ld/testsuite/ld-pe/pdb2-section-contrib.d |  12 +++
 ld/testsuite/ld-pe/pdb2a.s                |   9 ++
 ld/testsuite/ld-pe/pdb2b.s                |   3 +
 6 files changed, 162 insertions(+), 5 deletions(-)
 create mode 100644 ld/testsuite/ld-pe/pdb2-section-contrib.d

diff --git a/ld/pdb.c b/ld/pdb.c
index 910589b4d09..6f69574289d 100644
--- a/ld/pdb.c
+++ b/ld/pdb.c
@@ -592,6 +592,96 @@ find_section_number (bfd *abfd, asection *sect)
   return 0;
 }
 
+/* Create the substream which maps addresses in the image file to locations
+   in the original object files.  */
+static bool
+create_section_contrib_substream (bfd *abfd, void **data, uint32_t *size)
+{
+  unsigned int num_sc = 0;
+  struct section_contribution *sc;
+  uint16_t mod_index;
+  char *sect_flags;
+  file_ptr offset;
+
+  for (bfd *in = coff_data (abfd)->link_info->input_bfds; in;
+       in = in->link.next)
+    {
+      for (asection *s = in->sections; s; s = s->next)
+	{
+	  if (s->size == 0 || discarded_section (s))
+	    continue;
+
+	  num_sc++;
+	}
+    }
+
+  *size = sizeof (uint32_t) + (num_sc * sizeof (struct section_contribution));
+  *data = xmalloc (*size);
+
+  bfd_putl32 (SECTION_CONTRIB_VERSION_60, *data);
+
+  /* Read characteristics of outputted sections.  */
+
+  sect_flags = xmalloc (sizeof (uint32_t) * abfd->section_count);
+
+  offset = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
+  offset += offsetof (struct external_scnhdr, s_flags);
+
+  for (unsigned int i = 0; i < abfd->section_count; i++)
+    {
+      bfd_seek (abfd, offset, SEEK_SET);
+
+      if (bfd_bread (sect_flags + (i * sizeof (uint32_t)), sizeof (uint32_t),
+		     abfd) != sizeof (uint32_t))
+	{
+	  free (*data);
+	  free (sect_flags);
+	  return false;
+	}
+
+      offset += sizeof (struct external_scnhdr);
+    }
+
+  sc =
+    (struct section_contribution *) ((uint8_t *) *data + sizeof (uint32_t));
+
+  mod_index = 0;
+  for (bfd *in = coff_data (abfd)->link_info->input_bfds; in;
+       in = in->link.next)
+    {
+      for (asection *s = in->sections; s; s = s->next)
+	{
+	  uint16_t sect_num;
+
+	  if (s->size == 0 || discarded_section (s))
+	    continue;
+
+	  sect_num = find_section_number (abfd, s->output_section);
+
+	  memcpy (&sc->characteristics,
+		  sect_flags + ((sect_num - 1) * sizeof (uint32_t)),
+		  sizeof (uint32_t));
+
+	  bfd_putl16 (sect_num, &sc->section);
+	  bfd_putl16 (0, &sc->padding1);
+	  bfd_putl32 (s->output_offset, &sc->offset);
+	  bfd_putl32 (s->size, &sc->size);
+	  bfd_putl16 (mod_index, &sc->module_index);
+	  bfd_putl16 (0, &sc->padding2);
+	  bfd_putl32 (0, &sc->data_crc);
+	  bfd_putl32 (0, &sc->reloc_crc);
+
+	  sc++;
+	}
+
+      mod_index++;
+    }
+
+  free (sect_flags);
+
+  return true;
+}
+
 /* Stream 4 is the debug information (DBI) stream.  */
 static bool
 populate_dbi_stream (bfd *stream, bfd *abfd, bfd *pdb,
@@ -601,12 +691,18 @@ populate_dbi_stream (bfd *stream, bfd *abfd, bfd *pdb,
 {
   struct pdb_dbi_stream_header h;
   struct optional_dbg_header opt;
-  void *mod_info;
-  uint32_t mod_info_size;
+  void *mod_info, *sc;
+  uint32_t mod_info_size, sc_size;
 
   if (!create_module_info_substream (abfd, pdb, &mod_info, &mod_info_size))
     return false;
 
+  if (!create_section_contrib_substream (abfd, &sc, &sc_size))
+    {
+      free (mod_info);
+      return false;
+    }
+
   bfd_putl32 (0xffffffff, &h.version_signature);
   bfd_putl32 (DBI_STREAM_VERSION_70, &h.version_header);
   bfd_putl32 (1, &h.age);
@@ -617,7 +713,7 @@ populate_dbi_stream (bfd *stream, bfd *abfd, bfd *pdb,
   bfd_putl16 (sym_rec_stream_num, &h.sym_record_stream);
   bfd_putl16 (0, &h.pdb_dll_rbld);
   bfd_putl32 (mod_info_size, &h.mod_info_size);
-  bfd_putl32 (0, &h.section_contribution_size);
+  bfd_putl32 (sc_size, &h.section_contribution_size);
   bfd_putl32 (0, &h.section_map_size);
   bfd_putl32 (0, &h.source_info_size);
   bfd_putl32 (0, &h.type_server_map_size);
@@ -630,18 +726,28 @@ populate_dbi_stream (bfd *stream, bfd *abfd, bfd *pdb,
 
   if (bfd_bwrite (&h, sizeof (h), stream) != sizeof (h))
     {
+      free (sc);
       free (mod_info);
       return false;
     }
 
   if (bfd_bwrite (mod_info, mod_info_size, stream) != mod_info_size)
     {
+      free (sc);
       free (mod_info);
       return false;
     }
 
   free (mod_info);
 
+  if (bfd_bwrite (sc, sc_size, stream) != sc_size)
+    {
+      free (sc);
+      return false;
+    }
+
+  free (sc);
+
   bfd_putl16 (0xffff, &opt.fpo_stream);
   bfd_putl16 (0xffff, &opt.exception_stream);
   bfd_putl16 (0xffff, &opt.fixup_stream);
diff --git a/ld/pdb.h b/ld/pdb.h
index a44618578b7..e22dea18eca 100644
--- a/ld/pdb.h
+++ b/ld/pdb.h
@@ -155,6 +155,8 @@ struct optional_dbg_header
 
 #define CV_SIGNATURE_C13		4
 
+#define SECTION_CONTRIB_VERSION_60	0xf12eba2d
+
 /* SC in dbicommon.h */
 struct section_contribution
 {
diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp
index ab22506d0f2..0be65e22fb6 100644
--- a/ld/testsuite/ld-pe/pdb.exp
+++ b/ld/testsuite/ld-pe/pdb.exp
@@ -626,6 +626,26 @@ proc test_mod_info { mod_info } {
     }
 }
 
+proc test_section_contrib { section_contrib } {
+    global objdump
+    global srcdir
+    global subdir
+
+    set fi [open tmpdir/pdb2-sc w]
+    fconfigure $fi -translation binary
+    puts -nonewline $fi $section_contrib
+    close $fi
+
+    set exp [file_contents "$srcdir/$subdir/pdb2-section-contrib.d"]
+    set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/pdb2-sc"]
+
+    if [string equal $exp $got] {
+	pass "Correct section contribution substream"
+    } else {
+	fail "Incorrect section contribution substream"
+    }
+}
+
 proc test2 { } {
     global as
     global ar
@@ -650,7 +670,7 @@ proc test2 { } {
 	return
     }
 
-    if ![ld_link $ld "tmpdir/pdb2.exe" "--pdb=tmpdir/pdb2.pdb -e foo tmpdir/pdb2a.o tmpdir/pdb2b.a"] {
+    if ![ld_link $ld "tmpdir/pdb2.exe" "--pdb=tmpdir/pdb2.pdb --gc-sections -e foo tmpdir/pdb2a.o tmpdir/pdb2b.a"] {
 	unsupported "Create PE image with PDB file"
 	return
     }
@@ -669,13 +689,18 @@ proc test2 { } {
     set data [read $fi 4]
     binary scan $data i mod_info_size
 
-    seek $fi 36 current
+    set data [read $fi 4]
+    binary scan $data i section_contrib_size
+
+    seek $fi 32 current
 
     set mod_info [read $fi $mod_info_size]
+    set section_contrib [read $fi $section_contrib_size]
 
     close $fi
 
     test_mod_info $mod_info
+    test_section_contrib $section_contrib
 }
 
 test1
diff --git a/ld/testsuite/ld-pe/pdb2-section-contrib.d b/ld/testsuite/ld-pe/pdb2-section-contrib.d
new file mode 100644
index 00000000000..3afeb149e4b
--- /dev/null
+++ b/ld/testsuite/ld-pe/pdb2-section-contrib.d
@@ -0,0 +1,12 @@
+
+tmpdir/pdb2-sc:     file format binary
+
+Contents of section .data:
+ 0000 2dba2ef1 01000000 00000000 10000000  -...............
+ 0010 20000060 00000000 00000000 00000000   ..`............
+ 0020 02000000 00000000 44000000 40000040  ........D...@..@
+ 0030 00000000 00000000 00000000 01000000  ................
+ 0040 10000000 10000000 20000060 01000000  ........ ..`....
+ 0050 00000000 00000000 04000000 00000000  ................
+ 0060 0c000000 40000042 02000000 00000000  ....@..B........
+ 0070 00000000                             ....            
\ No newline at end of file
diff --git a/ld/testsuite/ld-pe/pdb2a.s b/ld/testsuite/ld-pe/pdb2a.s
index 414edeb2eec..beeea8b284b 100644
--- a/ld/testsuite/ld-pe/pdb2a.s
+++ b/ld/testsuite/ld-pe/pdb2a.s
@@ -3,3 +3,12 @@
 .global foo
 foo:
 	.secrel32 bar
+	.long 0
+	.long 0
+	.long 0
+
+.section "gcsect"
+
+.global baz
+baz:
+	.long 0x12345678
diff --git a/ld/testsuite/ld-pe/pdb2b.s b/ld/testsuite/ld-pe/pdb2b.s
index 64010237975..3a633866c08 100644
--- a/ld/testsuite/ld-pe/pdb2b.s
+++ b/ld/testsuite/ld-pe/pdb2b.s
@@ -3,3 +3,6 @@
 .global bar
 bar:
 	.long 0x12345678
+	.long 0
+	.long 0
+	.long 0
-- 
2.37.4


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

* Re: [PATCH] ld: Add section contributions substream to PDB files
  2022-11-11  3:30 [PATCH] ld: Add section contributions substream to PDB files Mark Harmstone
@ 2022-11-22 14:12 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2022-11-22 14:12 UTC (permalink / raw)
  To: Mark Harmstone, binutils

Hi Mark,

>   ld/pdb.c                                  | 112 +++++++++++++++++++++-
>   ld/pdb.h                                  |   2 +
>   ld/testsuite/ld-pe/pdb.exp                |  29 +++++-
>   ld/testsuite/ld-pe/pdb2-section-contrib.d |  12 +++
>   ld/testsuite/ld-pe/pdb2a.s                |   9 ++
>   ld/testsuite/ld-pe/pdb2b.s                |   3 +
>

Patch approved - please apply.

Cheers
   Nick



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

end of thread, other threads:[~2022-11-22 14:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-11  3:30 [PATCH] ld: Add section contributions substream to PDB files Mark Harmstone
2022-11-22 14:12 ` Nick Clifton

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).