From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id 4BBD03858017 for ; Mon, 31 Oct 2022 00:16:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4BBD03858017 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-wr1-x42a.google.com with SMTP id z14so13832224wrn.7 for ; Sun, 30 Oct 2022 17:16:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=Dit1MVdyuTvSgUElqc/G67voGethGz02EpBRB7VcOyg=; b=aohxa/KjmAphIN0AOBg2jmA5cX4vmGghoE+OdW0u0wEYpWvFe3K8GxHi0ykFAt3FCM bOPjM+LSPAftaKXTQ8JZyo5SW1f+lvI3af7cpDOwvyx/uE3YVKRPu390khg136/mpvG6 d6QQs+N1VuuyqzztdAhkMctMAGqJLz3cWZirLDEEoMLgJVF4GUHFXqypEVs0dGKgXDja Xc/LSSNBMNqR7okEhh/L5CBkCQJoKtqYX9XsoNaBVcoEnHttDE3g7xffxSTQD8Di7an8 HkCSv1p7IfkohM//woyeJ5FB5Ph91BO+mCpQC19cfvjVfoU1nsY9mLu1WvrXMcaDsnbT FEcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Dit1MVdyuTvSgUElqc/G67voGethGz02EpBRB7VcOyg=; b=LUaoprW6rpL4KKkJLTF22kp8DPZY/oQY9xANlS1ngst7HmTpKcLzaXCHlGkXa+p+h9 YaXOi6NsvomiTOVETI2sqsxmBa66s6kZYuwFxhXG+CkcKN0YPD7Q/M45W7HH+8B1bfxD HlzBIanCLWwRbSy5XTWp5x9h1tGWXgbatqYXvMcQ2iNGPpdhdSZ9pIh0EKTUL6gHKu0o QhNuQgkZI0C8fhXi7FEVgGSGWaXKEagBBJA2b52d8awSM250TZalqVov28eoqBYNQmqZ QKSpCMNc6ZNTTDilHEgB9JTuXCV2zYkePUwoTKtsTWnVxghIRl4jeHB4JR9gEqVUtjL/ iu2Q== X-Gm-Message-State: ACrzQf0TiGgfZbhDMsw7/t6hLquE70ov9uNhDRMaZ9vUXmyByndVq6cY 8txZEmabIHItU9FR3EksEVv0mjE3H6Q= X-Google-Smtp-Source: AMsMyM712ebJJiX/FzqdyrXyFzFILCa88N6OcnSEtW+KFWk06++obGuOg8MI4hPHpzchwuB9MfTG5A== X-Received: by 2002:a5d:5292:0:b0:236:ccb9:673b with SMTP id c18-20020a5d5292000000b00236ccb9673bmr1126363wrv.317.1667175386787; Sun, 30 Oct 2022 17:16:26 -0700 (PDT) Received: from beren.harmstone.com ([2a02:8010:64ea:0:8eb8:7eff:fe53:9d5f]) by smtp.gmail.com with ESMTPSA id bp21-20020a5d5a95000000b002302dc43d77sm5389067wrb.115.2022.10.30.17.16.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:16:26 -0700 (PDT) Sender: Mark Harmstone From: Mark Harmstone To: binutils@sourceware.org Cc: Mark Harmstone Subject: [PATCH v2 2/3] ld: Add section header stream to PDB files Date: Mon, 31 Oct 2022 00:15:53 +0000 Message-Id: <20221031001554.14615-2-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221031001554.14615-1-mark@harmstone.com> References: <20221031001554.14615-1-mark@harmstone.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.4 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 | 69 ++++++++++++++++++++- ld/testsuite/ld-pe/pdb.exp | 123 +++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 3 deletions(-) diff --git a/ld/pdb.c b/ld/pdb.c index 80ed31e257a..1190dcf6cdf 100644 --- a/ld/pdb.c +++ b/ld/pdb.c @@ -385,7 +385,8 @@ get_arch_number (bfd *abfd) /* Stream 4 is the debug information (DBI) stream. */ static bool -populate_dbi_stream (bfd *stream, bfd *abfd) +populate_dbi_stream (bfd *stream, bfd *abfd, + uint16_t section_header_stream_num) { struct pdb_dbi_stream_header h; struct optional_dbg_header opt; @@ -419,7 +420,7 @@ populate_dbi_stream (bfd *stream, bfd *abfd) bfd_putl16 (0xffff, &opt.fixup_stream); bfd_putl16 (0xffff, &opt.omap_to_src_stream); bfd_putl16 (0xffff, &opt.omap_from_src_stream); - bfd_putl16 (0xffff, &opt.section_header_stream); + bfd_putl16 (section_header_stream_num, &opt.section_header_stream); bfd_putl16 (0xffff, &opt.token_map_stream); bfd_putl16 (0xffff, &opt.xdata_stream); bfd_putl16 (0xffff, &opt.pdata_stream); @@ -432,6 +433,60 @@ populate_dbi_stream (bfd *stream, bfd *abfd) return true; } +/* The section header stream contains a copy of the section headers + from the PE file, in the same format. */ +static bool +create_section_header_stream (bfd *pdb, bfd *abfd, uint16_t *num) +{ + bfd *stream; + unsigned int section_count; + file_ptr scn_base; + size_t len; + char *buf; + + stream = add_stream (pdb, NULL, num); + if (!stream) + return false; + + section_count = abfd->section_count; + + /* Empty sections aren't output. */ + for (asection *sect = abfd->sections; sect; sect = sect->next) + { + if (sect->size == 0) + section_count--; + } + + if (section_count == 0) + return true; + + /* Copy section table from output - it's already been written at this + point. */ + + scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); + + bfd_seek (abfd, scn_base, SEEK_SET); + + len = section_count * sizeof (struct external_scnhdr); + buf = xmalloc (len); + + if (bfd_bread (buf, len, abfd) != len) + { + free (buf); + return false; + } + + if (bfd_bwrite (buf, len, stream) != len) + { + free (buf); + return false; + } + + free (buf); + + return true; +} + /* Create a PDB debugging file for the PE image file abfd with the build ID guid, stored at pdb_name. */ bool @@ -440,6 +495,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) bfd *pdb; bool ret = false; bfd *info_stream, *dbi_stream, *names_stream; + uint16_t section_header_stream_num; pdb = bfd_openw (pdb_name, "pdb"); if (!pdb) @@ -498,7 +554,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) goto end; } - if (!populate_dbi_stream (dbi_stream, abfd)) + if (!create_section_header_stream (pdb, abfd, §ion_header_stream_num)) + { + einfo (_("%P: warning: cannot create section header stream " + "in PDB file: %E\n")); + goto end; + } + + if (!populate_dbi_stream (dbi_stream, abfd, section_header_stream_num)) { einfo (_("%P: warning: cannot populate DBI stream " "in PDB file: %E\n")); diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp index b62ce6da6f8..cee072187de 100644 --- a/ld/testsuite/ld-pe/pdb.exp +++ b/ld/testsuite/ld-pe/pdb.exp @@ -278,6 +278,123 @@ proc check_dbi_stream { pdb } { return 1 } +proc get_section_stream_index { pdb } { + global ar + + set exec_output [run_host_cmd "$ar" "x --output tmpdir $pdb 0003"] + + if ![string match "" $exec_output] { + return -1 + } + + set fi [open tmpdir/0003] + fconfigure $fi -translation binary + + # skip fields + seek $fi 24 + + # read substream sizes + + set data [read $fi 4] + binary scan $data i mod_info_size + + set data [read $fi 4] + binary scan $data i section_contribution_size + + set data [read $fi 4] + binary scan $data i section_map_size + + set data [read $fi 4] + binary scan $data i source_info_size + + set data [read $fi 4] + binary scan $data i type_server_map_size + + # skip type server index + seek $fi 4 current + + set data [read $fi 4] + binary scan $data i optional_dbg_header_size + + if { $optional_dbg_header_size < 12 } { + close $fi + return -1 + } + + # skip data + seek $fi [expr 12 + $mod_info_size + $section_contribution_size + $section_map_size + $source_info_size + $type_server_map_size + 10] current + + set data [read $fi 2] + binary scan $data s section_stream_index + + close $fi + + return $section_stream_index +} + +proc check_section_stream { img pdb } { + global ar + + # read sections stream + + set index [get_section_stream_index $pdb] + + if { $index == -1 } { + return 0 + } + + set index_str [format "%04x" $index] + + set exec_output [run_host_cmd "$ar" "x --output tmpdir $pdb $index_str"] + + if ![string match "" $exec_output] { + return 0 + } + + set stream_length [file size tmpdir/$index_str] + + set fi [open tmpdir/$index_str] + fconfigure $fi -translation binary + + set stream_data [read $fi $stream_length] + + close $fi + + # read sections from PE file + + set fi [open $img] + fconfigure $fi -translation binary + + # read PE offset + read $fi 0x3c + set data [read $fi 4] + binary scan $data i pe_offset + + # read number of sections + seek $fi [expr $pe_offset + 6] + set data [read $fi 2] + binary scan $data s num_sections + + # read size of optional header + seek $fi 12 current + set data [read $fi 2] + binary scan $data s opt_header_size + + # read section headers + seek $fi [expr $opt_header_size + 2] current + set section_data [read $fi [expr $num_sections * 40]] + + close $fi + + # compare + + if { $stream_data ne $section_data} { + return 0 + } + + return 1 +} + if ![ld_assemble $as $srcdir/$subdir/pdb1.s tmpdir/pdb1.o] { unsupported "Build pdb1.o" return @@ -318,3 +435,9 @@ if [check_dbi_stream tmpdir/pdb1.pdb] { } else { fail "Invalid DBI stream" } + +if [check_section_stream tmpdir/pdb1.exe tmpdir/pdb1.pdb] { + pass "Valid section stream" +} else { + fail "Invalid section stream" +} -- 2.37.4