From patchwork Mon Oct 31 00:15:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 13076 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2025686wru; Sun, 30 Oct 2022 17:18:10 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4D0NB+D+9kTpRn64qAF7MAygjOvCAMyhJMJAEZDhf4ojMh2mKTPqyTqskbLKK6RrmN4gz2 X-Received: by 2002:a05:6402:10c2:b0:45c:3c87:721f with SMTP id p2-20020a05640210c200b0045c3c87721fmr11351030edu.251.1667175490327; Sun, 30 Oct 2022 17:18:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667175490; cv=none; d=google.com; s=arc-20160816; b=I+TUOsKQtAudxw5CekueT0GFLB9iHI6xf2tX5gZws0ROGatBwJffGcuRpt4LsesXY+ 205KGWp3Ck1OZCLVZrdQld4gXRumhWzRRUD7ummzUnvApvuSLICie42jy/0kHWWEOxG2 O4ATbZu8hhxVAQUmjO1Pw+sdDCN9sxwAwEW7HM3c+7cRymGr0mLJAo3+/lq6kX4utESF VNnpaqSPSPcb8xpXQHDjMnYPCFoGoPe1ZgE/GhnqtfKDEmEPlqXm16gGSIVtO2TCgUFq mgVsMFQNqYTaszvhDw8fLJrODx1XzZfRKPpfu2UBscKraVsFzj5or9fakMiucsmohZ1+ GDIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:to:from:dkim-signature :dmarc-filter:delivered-to; bh=nfz8ECdITOaIvBqHx4IwM9ghDrg5aL7at8aUHubhe6Q=; b=UXDbDSqG5Xx2weLCman1CayQAhGz22Idvc7ykgzWHTWfIEwChvoceNIr4NI9vY3ybh 1MAmZXWzQkmOB/dHCY4u0CuKT8UjwXn/+dhC53jLcJ5kpOIUdgAdj4iYX2KCfQErdL8f JNAQi4ACDND8dOH6sIfbGkVCE681ZYaldkhFHpErezvUD6mYR2wnv62GMYEtupQL+U4e ex1Q9HBltRCMwzrxiSyk8sM2/jVN/iJ/IpFNkLk8NxB8WKgTyh4CACPc2fO1zojysqDO kVnZFcbBX15izI58clTPfCOIBgyvBaMcnJjcNlBvW0iNp6M/lXzixz122a67ZgLFhwTy Q4nQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b=FSTTjbZb; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id nd12-20020a170907628c00b0078d2f0bf546si6947616ejc.186.2022.10.30.17.18.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:18:10 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b=FSTTjbZb; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 63F8C385802F for ; Mon, 31 Oct 2022 00:18:09 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by sourceware.org (Postfix) with ESMTPS id BA91A385800E for ; Mon, 31 Oct 2022 00:16:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BA91A385800E 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-x432.google.com with SMTP id v1so13832038wrt.11 for ; Sun, 30 Oct 2022 17:16:26 -0700 (PDT) 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=nfz8ECdITOaIvBqHx4IwM9ghDrg5aL7at8aUHubhe6Q=; b=FSTTjbZby2o1MyHF7Cu+gB4eGp6ymXSOcvf6Sokp6uSUIQCgsawo4HZf+qnKrzEf+v gEmRJo/VHLfqVdR5sjqVB2Cqfc5CHKv/oFmWKsxXjlcNq7f6COQLd9b2Bp0nb2EBfMLH +P56ehJfsQfJ+kmPbSfYdtwqx9X16kuSf1eQWb9QU7UJ8Ymd2MuMikj0l5L/GEqG+Bld b/TmomFIgY4aYwyfYP/G+IgLKhBVRIRDgyPWC7XsN8whQFfd5eXx73HLQ/krbNAebCI9 KmLxeBpwpAdhmrCqCbu/Ogb9D3ZhvjYglhmAVtAKU7TBE0z2Qx5Xn9BXEM89CF/i8lxH YgGQ== 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=nfz8ECdITOaIvBqHx4IwM9ghDrg5aL7at8aUHubhe6Q=; b=BXmnKZBGSahtCA6hA7Ihlh5/npEEBkV2jmMhk612zOVHdLBN3WCbiPtL9d2qZIhxvf 7Vp6qyeXOBYd3zchL+x6wNmngOEVTCzFkhz2UCYu70I6kWS4fFnCwZD8EWitY2GCmFpg njvp4JpLqTv1preN8U6j8blnh3u7+EagPhtArh+K/NLTxQHNrsZ4eOMljzH6kupVZ4pq 00vHvkobNUhoGzRVOZfK6qpSoqJcDIqM6Bg8hAJ+T2wT5PVY9Z1Fo4+TPeUW7AxkjWNk 9mn7uM1G37OjS2GNHGHAWdB/GEZBocKvEnERBuNIgSaIkg/wMp6esnarA6ztgwLf7Ntr AXZw== X-Gm-Message-State: ACrzQf2qTuEZsmyy/6uSHVw0ohv/wonsiiciZlV6+chzEqm2y7jTkqg4 nLCspXGpFGYjrR/yipp0Eza6WQnmaf4= X-Received: by 2002:a05:6000:10a:b0:236:6a79:f5cf with SMTP id o10-20020a056000010a00b002366a79f5cfmr5974222wrx.470.1667175385167; Sun, 30 Oct 2022 17:16:25 -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.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:16:24 -0700 (PDT) From: Mark Harmstone To: binutils@sourceware.org Subject: [PATCH v2 1/3] ld: Use %E in einfo in pdb.c Date: Mon, 31 Oct 2022 00:15:52 +0000 Message-Id: <20221031001554.14615-1-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 MIME-Version: 1.0 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Harmstone Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748160206945846524?= X-GMAIL-MSGID: =?utf-8?q?1748160206945846524?= Resubmission, taking into account https://sourceware.org/pipermail/binutils/2022-October/123948.html. --- ld/pdb.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/ld/pdb.c b/ld/pdb.c index 3452e2cbe5b..80ed31e257a 100644 --- a/ld/pdb.c +++ b/ld/pdb.c @@ -444,8 +444,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) pdb = bfd_openw (pdb_name, "pdb"); if (!pdb) { - einfo (_("%P: warning: cannot create PDB file: %s\n"), - bfd_errmsg (bfd_get_error ())); + einfo (_("%P: warning: cannot create PDB file: %E\n")); return false; } @@ -454,7 +453,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) if (!create_old_directory_stream (pdb)) { einfo (_("%P: warning: cannot create old directory stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } @@ -463,14 +462,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) if (!info_stream) { einfo (_("%P: warning: cannot create info stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } if (!create_type_stream (pdb)) { einfo (_("%P: warning: cannot create TPI stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } @@ -479,14 +478,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) if (!dbi_stream) { einfo (_("%P: warning: cannot create DBI stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } if (!create_type_stream (pdb)) { einfo (_("%P: warning: cannot create IPI stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } @@ -495,21 +494,21 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) if (!names_stream) { einfo (_("%P: warning: cannot create /names stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } if (!populate_dbi_stream (dbi_stream, abfd)) { einfo (_("%P: warning: cannot populate DBI stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } if (!populate_info_stream (pdb, info_stream, guid)) { einfo (_("%P: warning: cannot populate info stream " - "in PDB file: %s\n"), bfd_errmsg (bfd_get_error ())); + "in PDB file: %E\n")); goto end; } From patchwork Mon Oct 31 00:15:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 13078 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2026200wru; Sun, 30 Oct 2022 17:19:43 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4gnKngPogFwSkt1kQEUtou7rVB6gUhdn0p40lso2uBRUBY7mtVgrFYl89fiEzYwNKIOp5i X-Received: by 2002:a17:907:2cd1:b0:7ad:90dc:e7f4 with SMTP id hg17-20020a1709072cd100b007ad90dce7f4mr10438610ejc.489.1667175583544; Sun, 30 Oct 2022 17:19:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667175583; cv=none; d=google.com; s=arc-20160816; b=MOcc0NCe5rEzXQoPurqTofhCvN/hCEQhYdT8o4CGQ5VgCHvKHo01WjiUyftr6hdoSu KkmgJs5QpybV/rfi9balCbQ84PtvkRWeoY7487ebU/xcplF8ol72mBkm4HEQ3Xg9tnsn lmtzbhKDRmn5Y+xbNoi5kJeq3TEFO6l0Ms+saqWDoJo/OCtRmXV3JcjVTY9o1jyoOZ1O xV9/OcwdyytMp4EMu8Byom/aEDzB3mRutvEw6OJcO0iiPmtYAn36fwOlHYpbC57ObTnx 9/++t+FcxNrCaUsM29tRnx2ljbc+KE0xNhhvpnK3I8l4huBa2SpcfJgpY1kxtfAuBzLz ZwbA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dmarc-filter:delivered-to; bh=Dit1MVdyuTvSgUElqc/G67voGethGz02EpBRB7VcOyg=; b=LbkDtC8sQLy8eMOIG7wVKIUGnubvn7V/vbWq9Bs+3suxEy8Jd9kvpo+XN+pVsmc+V+ 6e+Cn98ZMzCxcovnZmIdJqmjFpr9GvILXOrQGOvyVrRmIcQmELyZa6pu5McJjfuGVwl5 VF3lsfcqrsWMUhXDpnmjsdy9rX9xRL3gCwWXa3YXIeGwOFzYbd2TC5r/cFChaLDii+0r QaLthbAKkLTp2V52U6E33gY8IXVYH/AZPEuUaMAmzwuw/gJ3lnIAJmiHjwbcG5taFWIg 7e7CMofGvShYGklvIJlZdknPRgDmR7UFqaSED7DLSFpR75TlFNaLf2a7RuD8V93igHLW 0dNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b="aohxa/Kj"; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id h22-20020aa7cdd6000000b004589ea2d983si5241918edw.287.2022.10.30.17.19.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:19:43 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b="aohxa/Kj"; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4578D385782F for ; Mon, 31 Oct 2022 00:19:17 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org 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-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) From: Mark Harmstone To: binutils@sourceware.org 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 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Harmstone Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748160304794593720?= X-GMAIL-MSGID: =?utf-8?q?1748160304794593720?= --- 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" +} From patchwork Mon Oct 31 00:15:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 13077 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2025998wru; Sun, 30 Oct 2022 17:19:01 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5ssCB6W8uu4ZnaBRfUZIhLxPPpyPVqE4tXH9pkxXli9h80KBIumOXouMnf32YBzxRnIMuW X-Received: by 2002:a17:906:fe45:b0:791:9624:9ea5 with SMTP id wz5-20020a170906fe4500b0079196249ea5mr10535989ejb.282.1667175541736; Sun, 30 Oct 2022 17:19:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667175541; cv=none; d=google.com; s=arc-20160816; b=fWCzSYA/jageIFHktqbb5+s5hXD4ZCwoN2Z7IE2kHMXChT50b9AadPmk2YPy6PR1YT +Q5ft1kjLyWO6vz2dE1vt6cXajgMmTgl1znX/PDvLqaXnfj3mpmYz/xoFt/5QtO2UUEy jNTehy2S5hy0fCzJxsUI4/4K+WKHcKLImRNcyX9MYMT6NA5i5K0Bx92pNoTNVz8WYty0 WCI/76T1IhGRnfP4MVGVAgRvkzZNIL47mih+TARyJ2LQWERV5x/SpXsvHVRRu/RwRde4 1z9uxfZrhgMKseXfSZq+4Hysh093jUNLBWDeZ4ecZWoJC7Xw37ZGF1MZFfNtD7fNZ4ZL 4FIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dmarc-filter:delivered-to; bh=xdPDA8BUFoRf3u1gMYnxHSUsRi/wVUhv+nxFt0ZV43U=; b=Hyt+xVr7x9dXqj8BOmpR3xMH9dK7zAOUjAhH4O58iwF8qS5y1jFAr9uZTdCunr/SzR 5KZmII8YGTA4tgrM4omRXPLeDYX0l8YpxmY9BdQ6R8NiUh/5kXVHoBmdtDgR3DR/wOgU YQ+bbFc4XVdu0esIIhmsdIYD61Xaf6arhRxNAziftf9HZyVV9DrPccksEXc1S+5OKpio yH7DeUITIkYWu2bwtOXI65xx3OxsCyNd5MAj3bLQpnixZf77sua2XJnygL7RgHuE+Ohg OevN/d1lbkYlq0LQeN/CYOS1vie/RpiJFtL49KtQ16TkG2AhUEX1PjQzyYmIV0FT24h6 wSbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b="Py8cgM/v"; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id p11-20020a056402500b00b00459563e2c60si6376669eda.329.2022.10.30.17.19.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:19:01 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b="Py8cgM/v"; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D76333857B9C for ; Mon, 31 Oct 2022 00:18:57 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by sourceware.org (Postfix) with ESMTPS id E50C03858020 for ; Mon, 31 Oct 2022 00:16:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E50C03858020 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-x430.google.com with SMTP id g12so13834568wrs.10 for ; Sun, 30 Oct 2022 17:16:29 -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=xdPDA8BUFoRf3u1gMYnxHSUsRi/wVUhv+nxFt0ZV43U=; b=Py8cgM/vc3dH0vQnCzOgLhLEWanEXT5Tbxg7U6wSOhFadB5BjYym9rxRjD+a1micah 3A16BarhBLMLX+PZglZH6FT/bIL+DNdOW7dlXx+fXshNut9GUOreHYq1RF1uK9HTiVM/ eoD53QGKOhYbMXPhYcix5W3mtbCWgRvFoOIcUAe/mmt0wdq+uO+yb/DV3jkQ4Q/aTLoE q+yxZ0W0xa/tD9zJzglpMG9a82e5L0kDaTtWGMLWUQOyeRt1orWfLMoilivt2A9iY6zU BIfN5kTjjWouzcw/UL4r4EknzTWtSzTsnmrktJ1taP4+6TAmkvtqogeu2EENjusreuOy eF8Q== 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=xdPDA8BUFoRf3u1gMYnxHSUsRi/wVUhv+nxFt0ZV43U=; b=Bn1wLcb1dg5pohgg/BgXkOZYb0pNsvFxR69Tl0xQc+6xLdV/mxKFcZKl2lq0klZzLv 06lDWA6xpMUUiIIEqBEyDdXKrfb1Ta3tbuQcG4XCgg+Q9/34dy1yQBdM8+GKUaf4invp rm4cb23rXbiVHB9CdWbnmWjGjmfgTzLehJcD7HSYz1YR1U3ceAf1IbSo2AM/auLQIRvL fxcRw14E64h7RL44jl+nG3B7o3q974A7hUpdDZ4HFEjdHH9skpQ5HbwuhwKEL+I38o2X r/SAehIvLKs2/5mLEhAwESPtt2bu5UL/6XexWeOcSFDio39EcAOXuNTQTrOEeyAtd6be IWZw== X-Gm-Message-State: ACrzQf1k6ZE+qRDuTtf030PtO+OuhDlQSDSxaRpPBdq1clh2FbXFLP7d 2HpHkSuteUElbr3aCbXBEWcsPmXEXEA= X-Received: by 2002:a5d:484f:0:b0:236:9c97:6f85 with SMTP id n15-20020a5d484f000000b002369c976f85mr6340604wrs.636.1667175388232; Sun, 30 Oct 2022 17:16:28 -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.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Oct 2022 17:16:27 -0700 (PDT) From: Mark Harmstone To: binutils@sourceware.org Subject: [PATCH v2 3/3] ld: Add publics stream to PDB files Date: Mon, 31 Oct 2022 00:15:54 +0000 Message-Id: <20221031001554.14615-3-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 X-Spam-Status: No, score=-10.7 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, KAM_STOCKGEN, 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Harmstone Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748160260505999520?= X-GMAIL-MSGID: =?utf-8?q?1748160260505999520?= --- ld/pdb.c | 347 ++++++++++++++++++++++++++- ld/pdb.h | 47 ++++ ld/testsuite/ld-pe/pdb.exp | 107 ++++++++- ld/testsuite/ld-pe/pdb1-publics.d | 41 ++++ ld/testsuite/ld-pe/pdb1-sym-record.d | 7 + ld/testsuite/ld-pe/pdb1.s | 18 +- 6 files changed, 559 insertions(+), 8 deletions(-) create mode 100644 ld/testsuite/ld-pe/pdb1-publics.d create mode 100644 ld/testsuite/ld-pe/pdb1-sym-record.d diff --git a/ld/pdb.c b/ld/pdb.c index 1190dcf6cdf..a2cdb84e271 100644 --- a/ld/pdb.c +++ b/ld/pdb.c @@ -383,10 +383,31 @@ get_arch_number (bfd *abfd) return IMAGE_FILE_MACHINE_I386; } +/* Return the index of a given output section. */ +static uint16_t +find_section_number (bfd *abfd, asection *sect) +{ + uint16_t i = 1; + + for (asection *s = abfd->sections; s; s = s->next) + { + if (s == sect) + return i; + + /* Empty sections aren't output. */ + if (s->size != 0) + i++; + } + + return 0; +} + /* Stream 4 is the debug information (DBI) stream. */ static bool populate_dbi_stream (bfd *stream, bfd *abfd, - uint16_t section_header_stream_num) + uint16_t section_header_stream_num, + uint16_t sym_rec_stream_num, + uint16_t publics_stream_num) { struct pdb_dbi_stream_header h; struct optional_dbg_header opt; @@ -396,9 +417,9 @@ populate_dbi_stream (bfd *stream, bfd *abfd, bfd_putl32 (1, &h.age); bfd_putl16 (0xffff, &h.global_stream_index); bfd_putl16 (0x8e1d, &h.build_number); // MSVC 14.29 - bfd_putl16 (0xffff, &h.public_stream_index); + bfd_putl16 (publics_stream_num, &h.public_stream_index); bfd_putl16 (0, &h.pdb_dll_version); - bfd_putl16 (0xffff, &h.sym_record_stream); + bfd_putl16 (sym_rec_stream_num, &h.sym_record_stream); bfd_putl16 (0, &h.pdb_dll_rbld); bfd_putl32 (0, &h.mod_info_size); bfd_putl32 (0, &h.section_contribution_size); @@ -433,6 +454,293 @@ populate_dbi_stream (bfd *stream, bfd *abfd, return true; } +/* Used as parameter to qsort, to sort publics by hash. */ +static int +public_compare_hash (const void *s1, const void *s2) +{ + const struct public *p1 = *(const struct public **) s1; + const struct public *p2 = *(const struct public **) s2; + + if (p1->hash < p2->hash) + return -1; + if (p1->hash > p2->hash) + return 1; + + return 0; +} + +/* Used as parameter to qsort, to sort publics by address. */ +static int +public_compare_addr (const void *s1, const void *s2) +{ + const struct public *p1 = *(const struct public **) s1; + const struct public *p2 = *(const struct public **) s2; + + if (p1->section < p2->section) + return -1; + if (p1->section > p2->section) + return 1; + + if (p1->address < p2->address) + return -1; + if (p1->address > p2->address) + return 1; + + return 0; +} + +/* The publics stream is a hash map of S_PUB32 records, which are stored + in the symbol record stream. Each S_PUB32 entry represents a symbol + from the point of view of the linker: a section index, an offset within + the section, and a mangled name. Compare with S_GDATA32 and S_GPROC32, + which are the same thing but generated by the compiler. */ +static bool +populate_publics_stream (bfd *stream, bfd *abfd, bfd *sym_rec_stream) +{ + struct publics_header header; + struct globals_hash_header hash_header; + const unsigned int num_buckets = 4096; + unsigned int num_entries = 0, filled_buckets = 0; + unsigned int buckets_size, sym_hash_size; + char int_buf[sizeof (uint32_t)]; + struct public *publics_head = NULL, *publics_tail = NULL; + struct public **buckets; + struct public **sorted = NULL; + bool ret = false; + + buckets = xmalloc (sizeof (struct public *) * num_buckets); + memset (buckets, 0, sizeof (struct public *) * num_buckets); + + /* Loop through the global symbols in our input files, and write S_PUB32 + records in the symbol record stream for those that make it into the + final image. */ + for (bfd *in = coff_data (abfd)->link_info->input_bfds; in; + in = in->link.next) + { + for (unsigned int i = 0; i < in->symcount; i++) + { + struct bfd_symbol *sym = in->outsymbols[i]; + + if (sym->flags & BSF_GLOBAL) + { + struct pubsym ps; + uint16_t record_length; + const char *name = sym->name; + size_t name_len = strlen (name); + struct public *p = xmalloc (sizeof (struct public)); + unsigned int padding = 0; + uint16_t section; + uint32_t flags = 0; + + section = + find_section_number (abfd, sym->section->output_section); + + if (section == 0) + continue; + + p->next = NULL; + p->offset = bfd_tell (sym_rec_stream); + p->hash = calc_hash (name, name_len) % num_buckets; + p->section = section; + p->address = sym->section->output_offset + sym->value; + + record_length = sizeof (struct pubsym) + name_len + 1; + + if (record_length % 4) + padding = 4 - (record_length % 4); + + /* Assume that all global symbols in executable sections + are functions. */ + if (sym->section->flags & SEC_CODE) + flags = PUBSYM_FUNCTION; + + bfd_putl16 (record_length + padding - sizeof (uint16_t), + &ps.record_length); + bfd_putl16 (S_PUB32, &ps.record_type); + bfd_putl32 (flags, &ps.flags); + bfd_putl32 (p->address, &ps.offset); + bfd_putl16 (p->section, &ps.section); + + if (bfd_bwrite (&ps, sizeof (struct pubsym), sym_rec_stream) != + sizeof (struct pubsym)) + goto end; + + if (bfd_bwrite (name, name_len + 1, sym_rec_stream) != + name_len + 1) + goto end; + + for (unsigned int j = 0; j < padding; j++) + { + uint8_t b = 0; + + if (bfd_bwrite (&b, sizeof (uint8_t), sym_rec_stream) != + sizeof (uint8_t)) + goto end; + } + + if (!publics_head) + publics_head = p; + else + publics_tail->next = p; + + publics_tail = p; + num_entries++; + } + } + } + + + if (num_entries > 0) + { + /* Create an array of pointers, sorted by hash value. */ + + sorted = xmalloc (sizeof (struct public *) * num_entries); + + struct public *p = publics_head; + for (unsigned int i = 0; i < num_entries; i++) + { + sorted[i] = p; + p = p->next; + } + + qsort (sorted, num_entries, sizeof (struct public *), + public_compare_hash); + + /* Populate the buckets. */ + + for (unsigned int i = 0; i < num_entries; i++) + { + if (!buckets[sorted[i]->hash]) + { + buckets[sorted[i]->hash] = sorted[i]; + filled_buckets++; + } + + sorted[i]->index = i; + } + } + + buckets_size = num_buckets / 8; + buckets_size += sizeof (uint32_t); + buckets_size += filled_buckets * sizeof (uint32_t); + + sym_hash_size = sizeof (hash_header); + sym_hash_size += num_entries * sizeof (struct hash_record); + sym_hash_size += buckets_size; + + /* Output the publics header. */ + + bfd_putl32 (sym_hash_size, &header.sym_hash_size); + bfd_putl32 (num_entries * sizeof (uint32_t), &header.addr_map_size); + bfd_putl32 (0, &header.num_thunks); + bfd_putl32 (0, &header.thunks_size); + bfd_putl32 (0, &header.thunk_table); + bfd_putl32 (0, &header.thunk_table_offset); + bfd_putl32 (0, &header.num_sects); + + if (bfd_bwrite (&header, sizeof (header), stream) != sizeof (header)) + goto end; + + /* Output the global hash header. */ + + bfd_putl32 (GLOBALS_HASH_SIGNATURE, &hash_header.signature); + bfd_putl32 (GLOBALS_HASH_VERSION_70, &hash_header.version); + bfd_putl32 (num_entries * sizeof (struct hash_record), + &hash_header.entries_size); + bfd_putl32 (buckets_size, &hash_header.buckets_size); + + if (bfd_bwrite (&hash_header, sizeof (hash_header), stream) != + sizeof (hash_header)) + goto end; + + /* Write the entries in hash order. */ + + for (unsigned int i = 0; i < num_entries; i++) + { + struct hash_record hr; + + bfd_putl32 (sorted[i]->offset + 1, &hr.offset); + bfd_putl32 (1, &hr.reference); + + if (bfd_bwrite (&hr, sizeof (hr), stream) != sizeof (hr)) + goto end; + } + + /* Write the bitmap for filled and unfilled buckets. */ + + for (unsigned int i = 0; i < num_buckets; i += 8) + { + uint8_t v = 0; + + for (unsigned int j = 0; j < 8; j++) + { + if (buckets[i + j]) + v |= 1 << j; + } + + if (bfd_bwrite (&v, sizeof (v), stream) != sizeof (v)) + goto end; + } + + /* Add a 4-byte gap. */ + + bfd_putl32 (0, int_buf); + + if (bfd_bwrite (int_buf, sizeof (uint32_t), stream) != sizeof (uint32_t)) + goto end; + + /* Write the bucket offsets. */ + + for (unsigned int i = 0; i < num_buckets; i++) + { + if (buckets[i]) + { + /* 0xc is size of internal hash_record structure in + Microsoft's parser. */ + bfd_putl32 (buckets[i]->index * 0xc, int_buf); + + if (bfd_bwrite (int_buf, sizeof (uint32_t), stream) != + sizeof (uint32_t)) + goto end; + } + } + + /* Write the address map: offsets into the symbol record stream of + S_PUB32 records, ordered by address. */ + + if (num_entries > 0) + { + qsort (sorted, num_entries, sizeof (struct public *), + public_compare_addr); + + for (unsigned int i = 0; i < num_entries; i++) + { + bfd_putl32 (sorted[i]->offset, int_buf); + + if (bfd_bwrite (int_buf, sizeof (uint32_t), stream) != + sizeof (uint32_t)) + goto end; + } + } + + ret = true; + +end: + free (buckets); + + while (publics_head) + { + struct public *p = publics_head->next; + + free (publics_head); + publics_head = p; + } + + free (sorted); + + return ret; +} + /* The section header stream contains a copy of the section headers from the PE file, in the same format. */ static bool @@ -494,8 +802,9 @@ 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; + bfd *info_stream, *dbi_stream, *names_stream, *sym_rec_stream, + *publics_stream; + uint16_t section_header_stream_num, sym_rec_stream_num, publics_stream_num; pdb = bfd_openw (pdb_name, "pdb"); if (!pdb) @@ -554,6 +863,24 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) goto end; } + sym_rec_stream = add_stream (pdb, NULL, &sym_rec_stream_num); + + if (!sym_rec_stream) + { + einfo (_("%P: warning: cannot create symbol record stream " + "in PDB file: %E\n")); + goto end; + } + + publics_stream = add_stream (pdb, NULL, &publics_stream_num); + + if (!publics_stream) + { + einfo (_("%P: warning: cannot create publics stream " + "in PDB file: %E\n")); + goto end; + } + if (!create_section_header_stream (pdb, abfd, §ion_header_stream_num)) { einfo (_("%P: warning: cannot create section header stream " @@ -561,13 +888,21 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid) goto end; } - if (!populate_dbi_stream (dbi_stream, abfd, section_header_stream_num)) + if (!populate_dbi_stream (dbi_stream, abfd, section_header_stream_num, + sym_rec_stream_num, publics_stream_num)) { einfo (_("%P: warning: cannot populate DBI stream " "in PDB file: %E\n")); goto end; } + if (!populate_publics_stream (publics_stream, abfd, sym_rec_stream)) + { + einfo (_("%P: warning: cannot populate publics stream " + "in PDB file: %E\n")); + goto end; + } + if (!populate_info_stream (pdb, info_stream, guid)) { einfo (_("%P: warning: cannot populate info stream " diff --git a/ld/pdb.h b/ld/pdb.h index e5f53b44f39..1a80101d288 100644 --- a/ld/pdb.h +++ b/ld/pdb.h @@ -28,6 +28,8 @@ #include "bfd.h" #include +#define S_PUB32 0x110e + /* PDBStream70 in pdb1.h */ struct pdb_stream_70 { @@ -91,6 +93,51 @@ struct pdb_dbi_stream_header #define DBI_STREAM_VERSION_70 19990903 +/* PSGSIHDR in gsi.h */ +struct publics_header +{ + uint32_t sym_hash_size; + uint32_t addr_map_size; + uint32_t num_thunks; + uint32_t thunks_size; + uint32_t thunk_table; + uint32_t thunk_table_offset; + uint32_t num_sects; +}; + +/* GSIHashHdr in gsi.h */ +struct globals_hash_header +{ + uint32_t signature; + uint32_t version; + uint32_t entries_size; + uint32_t buckets_size; +}; + +/* HRFile in gsi.h */ +struct hash_record +{ + uint32_t offset; + uint32_t reference; +}; + +#define GLOBALS_HASH_SIGNATURE 0xffffffff +#define GLOBALS_HASH_VERSION_70 0xf12f091a + +/* PUBSYM32 in cvinfo.h */ +struct pubsym +{ + uint16_t record_length; + uint16_t record_type; + uint32_t flags; + uint32_t offset; + uint16_t section; + /* followed by null-terminated string */ +} ATTRIBUTE_PACKED; + +/* see bitset CV_PUBSYMFLAGS in cvinfo.h */ +#define PUBSYM_FUNCTION 0x2 + struct optional_dbg_header { uint16_t fpo_stream; diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp index cee072187de..ee314c41f9b 100644 --- a/ld/testsuite/ld-pe/pdb.exp +++ b/ld/testsuite/ld-pe/pdb.exp @@ -395,12 +395,111 @@ proc check_section_stream { img pdb } { return 1 } +proc get_publics_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 16 + + # read substream sizes + + set data [read $fi 2] + binary scan $data s index + + close $fi + + return $index +} + +proc get_sym_record_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 20 + + # read substream sizes + + set data [read $fi 2] + binary scan $data s index + + close $fi + + return $index +} + +proc check_publics_stream { pdb } { + global ar + global objdump + global srcdir + global subdir + + set publics_index [get_publics_stream_index $pdb] + + if { $publics_index == -1 } { + return 0 + } + + set index_str [format "%04x" $publics_index] + + set exec_output [run_host_cmd "$ar" "x --output tmpdir $pdb $index_str"] + + if ![string match "" $exec_output] { + return 0 + } + + set exp [file_contents "$srcdir/$subdir/pdb1-publics.d"] + set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/$index_str"] + if ![string match $exp $got] { + return 0 + } + + set sym_record_index [get_sym_record_stream_index $pdb] + + if { $sym_record_index == -1 } { + return 0 + } + + set index_str [format "%04x" $sym_record_index] + + set exec_output [run_host_cmd "$ar" "x --output tmpdir $pdb $index_str"] + + if ![string match "" $exec_output] { + return 0 + } + + set exp [file_contents "$srcdir/$subdir/pdb1-sym-record.d"] + set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/$index_str"] + if ![string match $exp $got] { + return 0 + } + + return 1 +} + if ![ld_assemble $as $srcdir/$subdir/pdb1.s tmpdir/pdb1.o] { unsupported "Build pdb1.o" return } -if ![ld_link $ld "tmpdir/pdb1.exe" "--pdb=tmpdir/pdb1.pdb tmpdir/pdb1.o"] { +if ![ld_link $ld "tmpdir/pdb1.exe" "--pdb=tmpdir/pdb1.pdb --gc-sections -e foo tmpdir/pdb1.o"] { fail "Could not create a PE image with a PDB file" return } @@ -441,3 +540,9 @@ if [check_section_stream tmpdir/pdb1.exe tmpdir/pdb1.pdb] { } else { fail "Invalid section stream" } + +if [check_publics_stream tmpdir/pdb1.pdb] { + pass "Valid publics stream" +} else { + fail "Invalid publics stream" +} diff --git a/ld/testsuite/ld-pe/pdb1-publics.d b/ld/testsuite/ld-pe/pdb1-publics.d new file mode 100644 index 00000000000..f7df2d90782 --- /dev/null +++ b/ld/testsuite/ld-pe/pdb1-publics.d @@ -0,0 +1,41 @@ + +*: file format binary + +Contents of section .data: + 0000 2c020000 08000000 00000000 00000000 ,............... + 0010 00000000 00000000 00000000 ffffffff ................ + 0020 1a092ff1 10000000 0c020000 15000000 ../............. + 0030 01000000 01000000 01000000 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 00000001 ................ + 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 01000000 ................ + 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 0c000000 00000000 14000000 ................ \ No newline at end of file diff --git a/ld/testsuite/ld-pe/pdb1-sym-record.d b/ld/testsuite/ld-pe/pdb1-sym-record.d new file mode 100644 index 00000000000..2078a5e8a57 --- /dev/null +++ b/ld/testsuite/ld-pe/pdb1-sym-record.d @@ -0,0 +1,7 @@ + +*: file format binary + +Contents of section .data: + 0000 12000e11 02000000 08000000 0100666f ..............fo + 0010 6f000000 12000e11 00000000 04000000 o............... + 0020 02006261 72000000 ..bar... \ No newline at end of file diff --git a/ld/testsuite/ld-pe/pdb1.s b/ld/testsuite/ld-pe/pdb1.s index 30a8cfcca2c..846814b1e79 100644 --- a/ld/testsuite/ld-pe/pdb1.s +++ b/ld/testsuite/ld-pe/pdb1.s @@ -1,5 +1,21 @@ .text + .long 0x12345678 + .long 0x9abcdef0 + .global foo -foo: +foo: # section 0001, offset 00000008 + .secrel32 bar + +.data + .long 0x12345678 + +.global bar +bar: # section 0002, offset 00000004 + .long 0x9abcdef0 + +.section "gcsect" + +.global baz +baz: # unreferenced, will be GC'd out .long 0x12345678