From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by sourceware.org (Postfix) with ESMTPS id F0A0D3858D35 for ; Fri, 11 Nov 2022 03:30:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F0A0D3858D35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-x32b.google.com with SMTP id l39-20020a05600c1d2700b003cf93c8156dso2381429wms.4 for ; Thu, 10 Nov 2022 19:30:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:from:to:cc:subject:date:message-id:reply-to; bh=Gz2LzgpXBXRQV19JOmNJBw+oNSJX14x24MaPlc/GoWM=; b=XBZw2dtvdx9cs6r9sQWHu2iHnXXPIFBf4CGArBeGPSEVfDiva0n1RcXGRe4eKLouZt YlGTPwYOeq/AHyI86L2zvH2dv0RGqXVxN+HLmomKtoDln4ef92Cnwy63iKDfsIcTVgfC IBRcqJjD7yPImvOC7xllhmIAn56z0Cb5hjTludn0SzDfgePrCJHSeWEb3WTFF++hsnSX 6l+4jEmaoB6xG1Ki5O2T01qi8qWNMs+IlpCHtTWtxIS9uFEeiEQQ+6s2+GMef/fRFi/j 3d1zcyFZmZ2+8Nj+kJaAF2Ftf9f1HbDWFzEm+P7Pr55LLzw4pp45JwOQd0E9mm9AZsLy 4b3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:sender:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Gz2LzgpXBXRQV19JOmNJBw+oNSJX14x24MaPlc/GoWM=; b=Rbqu7x7qjEZ9CAB6RP3yiXeqSmpJUlYwVcknZeWU1HDYx6kDDCy9tqE6kbpsrePYg8 phj78RS/Q3FkX2P+Qyap7jEVRLiRB7l6WtSxUboN/NfFLnLQnoWWyynaxI+VLzErP/nR kDHzqZWWICpRfl9RZ2OBNpoEUBC8bVQODw1yI7YLSBE+3Uoa0smWG6TzAbPy/aCa0fio /sT8aN3ElV6fzV3czcJn16/sfE915274CU0mZNE3Dj77MkPlyyghBDOGFD/87iQeAlFx 5DDJaur4+bbNlGRKhHcdi7Hiaz4fdhP692myvfTaPqBQE14+A5sXJS+q9x6FPTH+Jdoq mo8g== X-Gm-Message-State: ACrzQf0FL0zcRZjOsYaBYWodcBWMurFKq7tlmMxI3Tz1cAZLUQ9Dd37l 0oJ/44zbZro3GDdVaCWe02ii+6AbTis= X-Google-Smtp-Source: AMsMyM5cePQ5diDKkXUTfiRP+Qe17lHSUTnkDe+55m1kTm5D9h+yiGfKOrNb0XVUVNqSAl0RI4zrLQ== X-Received: by 2002:a05:600c:5101:b0:3cf:8e70:f34f with SMTP id o1-20020a05600c510100b003cf8e70f34fmr1084905wms.93.1668137443289; Thu, 10 Nov 2022 19:30:43 -0800 (PST) Received: from beren.harmstone.com ([2a02:8010:64ea:0:8eb8:7eff:fe53:9d5f]) by smtp.gmail.com with ESMTPSA id bk3-20020a0560001d8300b002366c3eefccsm661354wrb.109.2022.11.10.19.30.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Nov 2022 19:30:42 -0800 (PST) Sender: Mark Harmstone From: Mark Harmstone To: binutils@sourceware.org Cc: Mark Harmstone Subject: [PATCH] ld: Add section contributions substream to PDB files Date: Fri, 11 Nov 2022 03:30:40 +0000 Message-Id: <20221111033040.23115-1-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --- 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