From patchwork Sat Nov 13 13:10:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 47607 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DA92A3858403 for ; Sat, 13 Nov 2021 13:11:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DA92A3858403 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636809073; bh=PnkfsNW2JhgdzUUyVnLmggivYk0ye4nNq8u5joGhBBs=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Ic1Df0E2ZmGoy2jg6ok+elYWRULWimXrYxy8PHd5EghMRAi4nnYFN9+FWcVH0uFYP E33kRRtiMwvPydB2ShZ4CjwssgdDY+VacqdvF0m98MXHomhTUYTTyi6E2OoJ6MP93T MjssqeAGsMgDKRhL7RYO+Sl5pc4v6mFNe3q5kFY0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id 141E43858403 for ; Sat, 13 Nov 2021 13:10:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 141E43858403 Received: by mail-wm1-x335.google.com with SMTP id 133so10000564wme.0 for ; Sat, 13 Nov 2021 05:10:42 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :mime-version:content-transfer-encoding; bh=PnkfsNW2JhgdzUUyVnLmggivYk0ye4nNq8u5joGhBBs=; b=Q0fQ71JkS70a3EKHr75xbJ7gpd7n6z0DewBTvo4hH6O3/46/fm7P5KcT7/6s7h2RSy Dg/0WwfKy1KygVFp7TvbNZMlKUgfG5P1F7/ZuyuXQjgjTcfIEOC7sLydSFI6ikD8mz8S LUAhISn6rFX2LfAV0c9NJA8z6pnzc9UalAonscKCKpY5ydJSaUxvtn5sqMWANJA+LBES FgSNXSgdNWMcR4gAfmGNzZ0md8DKkYo69yOfPB6l6NJeZ2HEbYFCv9aZVZfsh2ctp0kV M9lWyAUJRp/GG2ZRHp8h2fZa3r0Ru+X5BbUUdZUn88210FxrLXZ79xFogPOueN6fllEO MvCw== X-Gm-Message-State: AOAM530GHcvLzFxNz6IH6AeJ4NkxYp25ybOFfguOQcziRXe6ugrDmkYu 90K9fLOjcAZrloQcWnUpPSJHXysyJyU= X-Google-Smtp-Source: ABdhPJwgZVPFz6buxuUclU4RT3fZKZvTX/LKtD6SebBX/ZQBHjJ7QjR+y93JRwV4p2DIfov2kU+nSA== X-Received: by 2002:a1c:9a89:: with SMTP id c131mr25362788wme.80.1636809040813; Sat, 13 Nov 2021 05:10:40 -0800 (PST) Received: from localhost.localdomain (host81-138-1-83.in-addr.btopenworld.com. [81.138.1.83]) by smtp.gmail.com with ESMTPSA id n184sm13878148wme.2.2021.11.13.05.10.40 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 13 Nov 2021 05:10:40 -0800 (PST) X-Google-Original-From: Iain Sandoe To: gcc-patches@gcc.gnu.org Subject: [PATCH] PCH: Make the save and restore diagnostics more robust. Date: Sat, 13 Nov 2021 13:10:34 +0000 Message-Id: <20211113131034.35955-1-iain@sandoe.co.uk> X-Mailer: git-send-email 2.24.3 (Apple Git-128) MIME-Version: 1.0 X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Sandoe via Gcc-patches From: Iain Sandoe Reply-To: iain@sandoe.co.uk Cc: Iain Sandoe , jakub@redhat.com Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" When saving, if we cannot obtain a suitable memory segment there is no point in continuing, so exit with an error. When reading in the PCH, we have a situation that the read-in data will replace the line tables used by the diagnostics output. However, the state of the read-in line tables is indeterminate at some points where diagnostics might be needed. To make this more robust, we save the existing line tables at the start and, once we have read in the pointer to the new one, put that to one side and restore the original table. This avoids compiler hangs if the read or memory acquisition code issues an assert, fatal_error, segv etc. Once the read is complete, we swap in the new line table that came from the PCH. If the read-in PCH is corrupted then we still have a broken compilation w.r.t any future diagnostics - but there is little that can be done about that without more careful validation of the file. I've tested this by hacking and rebuilding the compiler to produce various kinds of failure. At present, it is hard to see how to make testcases to do this. Now reg-testing on more systems, OK for master if reg-tests pass? thanks Iain Signed-off-by: Iain Sandoe gcc/ChangeLog: * ggc-common.c (gt_pch_save): If we cannot find a suitable memory segment for save, then error-out, do not try to continue. (gt_pch_restore): Save the existing line table, and when the replacement is being read, use that when constructing diagnostics. --- gcc/ggc-common.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 32ba5be42b2..b6abed1d9a2 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -440,6 +440,10 @@ gt_pch_save (FILE *f) (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and HOST_HOOKS_GT_PCH_USE_ADDRESS.) */ mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f)); + /* If the host cannot supply any suitable address for this, we are stuck. */ + if (mmi.preferred_base == NULL) + fatal_error (input_location, + "cannot write PCH file: required memory segment unavailable"); ggc_pch_this_base (state.d, mmi.preferred_base); @@ -589,6 +593,13 @@ gt_pch_restore (FILE *f) struct mmap_info mmi; int result; + /* We are about to reload the line maps along with the rest of the PCH + data, which means that the (loaded) ones cannot be guaranteed to be + in any valid state for reporting diagnostics that happen during the + load. Save the current table (and use it during the loading process + below). */ + class line_maps *save_line_table = line_table; + /* Delete any deletable objects. This makes ggc_pch_read much faster, as it can be sure that no GCable objects remain other than the ones just read in. */ @@ -603,20 +614,40 @@ gt_pch_restore (FILE *f) fatal_error (input_location, "cannot read PCH file: %m"); /* Read in all the global pointers, in 6 easy loops. */ + bool error_reading_pointers = false; for (rt = gt_ggc_rtab; *rt; rt++) for (rti = *rt; rti->base != NULL; rti++) for (i = 0; i < rti->nelt; i++) if (fread ((char *)rti->base + rti->stride * i, sizeof (void *), 1, f) != 1) - fatal_error (input_location, "cannot read PCH file: %m"); + error_reading_pointers = true; + + /* Stash the newly read-in line table pointer - it does not point to + anything meaningful yet, so swap the old one back in. */ + class line_maps *new_line_table = line_table; + line_table = save_line_table; + if (error_reading_pointers) + fatal_error (input_location, "cannot read PCH file: %m"); if (fread (&mmi, sizeof (mmi), 1, f) != 1) fatal_error (input_location, "cannot read PCH file: %m"); result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size, fileno (f), mmi.offset); + + /* We could not mmap or otherwise allocate the required memory at the + address needed. */ if (result < 0) - fatal_error (input_location, "had to relocate PCH"); + { + sorry_at (input_location, "PCH relocation is not yet supported"); + /* There is no point in continuing from here, we will only end up + with a crashed (most likely hanging) compiler. */ + exit (-1); + } + + /* (0) We allocated memory, but did not mmap the file, so we need to read + the data in manually. (>0) Otherwise the mmap succeed for the address + we wanted. */ if (result == 0) { if (fseek (f, mmi.offset, SEEK_SET) != 0 @@ -629,6 +660,10 @@ gt_pch_restore (FILE *f) ggc_pch_read (f, mmi.preferred_base); gt_pch_restore_stringpool (); + + /* Barring corruption of the PCH file, the restored line table should be + complete and usable. */ + line_table = new_line_table; } /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.