From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7904) id 5B45A3858C33; Wed, 23 Nov 2022 01:15:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B45A3858C33 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Mark Harmstone To: bfd-cvs@sourceware.org Subject: [binutils-gdb] ld: Add section contributions substream to PDB files X-Act-Checkin: binutils-gdb X-Git-Author: Mark Harmstone X-Git-Refname: refs/heads/master X-Git-Oldrev: c392c0e0ae1b654c3fafc42e2a9ed7cbfcee0769 X-Git-Newrev: e2a1b0a0d1bf0e9282e4902b2a2b2e75400104b4 Message-Id: <20221123011550.5B45A3858C33@sourceware.org> Date: Wed, 23 Nov 2022 01:15:50 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2022 01:15:50 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3De2a1b0a0d1bf= 0e9282e4902b2a2b2e75400104b4 commit e2a1b0a0d1bf0e9282e4902b2a2b2e75400104b4 Author: Mark Harmstone Date: Fri Nov 11 03:30:40 2022 +0000 ld: Add section contributions substream to PDB files Diff: --- 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(-) 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; } =20 +/* 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 =3D 0; + struct section_contribution *sc; + uint16_t mod_index; + char *sect_flags; + file_ptr offset; + + for (bfd *in =3D coff_data (abfd)->link_info->input_bfds; in; + in =3D in->link.next) + { + for (asection *s =3D in->sections; s; s =3D s->next) + { + if (s->size =3D=3D 0 || discarded_section (s)) + continue; + + num_sc++; + } + } + + *size =3D sizeof (uint32_t) + (num_sc * sizeof (struct section_contribut= ion)); + *data =3D xmalloc (*size); + + bfd_putl32 (SECTION_CONTRIB_VERSION_60, *data); + + /* Read characteristics of outputted sections. */ + + sect_flags =3D xmalloc (sizeof (uint32_t) * abfd->section_count); + + offset =3D bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); + offset +=3D offsetof (struct external_scnhdr, s_flags); + + for (unsigned int i =3D 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) !=3D sizeof (uint32_t)) + { + free (*data); + free (sect_flags); + return false; + } + + offset +=3D sizeof (struct external_scnhdr); + } + + sc =3D + (struct section_contribution *) ((uint8_t *) *data + sizeof (uint32_t)= ); + + mod_index =3D 0; + for (bfd *in =3D coff_data (abfd)->link_info->input_bfds; in; + in =3D in->link.next) + { + for (asection *s =3D in->sections; s; s =3D s->next) + { + uint16_t sect_num; + + if (s->size =3D=3D 0 || discarded_section (s)) + continue; + + sect_num =3D 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; =20 if (!create_module_info_substream (abfd, pdb, &mod_info, &mod_info_size)) return false; =20 + 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, =20 if (bfd_bwrite (&h, sizeof (h), stream) !=3D sizeof (h)) { + free (sc); free (mod_info); return false; } =20 if (bfd_bwrite (mod_info, mod_info_size, stream) !=3D mod_info_size) { + free (sc); free (mod_info); return false; } =20 free (mod_info); =20 + if (bfd_bwrite (sc, sc_size, stream) !=3D 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 =20 #define CV_SIGNATURE_C13 4 =20 +#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 } { } } =20 +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=3Dbinary 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 } =20 - if ![ld_link $ld "tmpdir/pdb2.exe" "--pdb=3Dtmpdir/pdb2.pdb -e foo tmp= dir/pdb2a.o tmpdir/pdb2b.a"] { + if ![ld_link $ld "tmpdir/pdb2.exe" "--pdb=3Dtmpdir/pdb2.pdb --gc-secti= ons -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 =20 - seek $fi 36 current + set data [read $fi 4] + binary scan $data i section_contrib_size + + seek $fi 32 current =20 set mod_info [read $fi $mod_info_size] + set section_contrib [read $fi $section_contrib_size] =20 close $fi =20 test_mod_info $mod_info + test_section_contrib $section_contrib } =20 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 .... =20 \ 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