From patchwork Thu Dec 10 17:36:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Kahn Gillmor X-Patchwork-Id: 555227 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C7908140273 for ; Fri, 11 Dec 2015 04:36:39 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=GJICYY/V; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=aB+DHa98yiKO7OT+3cKI+4Xk7S+rVfFV98ZFEkN2JOxasKuad6WVo shSXCWMI584djYf/YZr2SqgNTdEANvWMDOsuYxYQuX7biuxwbAC2vY9LT5O/nTZJ x5fWyrZbLdC5dY9W7JdyIJULRXFVpLjKdytQauK0PZPdHYl+g6f77E= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=z3+8yYURcn5a6br8zhNzx0k9mz8=; b=GJICYY/VboS57nOONsDk T9M6j/T93T8NiX46I1IGn1YHyRp6ukGfEgkdpq43wQVwXNA8k7zW4eJ4/nEUpX3h 4OjEJ1QL9bsf8aizXqlIZJ/yY5G8wQeJOfw2LFjqprQVUX1alpxJT1d/AeDfC9+N GwLdBH8C/QS5HPkjyV2epao= Received: (qmail 130881 invoked by alias); 10 Dec 2015 17:36:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 130858 invoked by uid 89); 10 Dec 2015 17:36:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: che.mayfirst.org Received: from che.mayfirst.org (HELO che.mayfirst.org) (209.234.253.108) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 10 Dec 2015 17:36:30 +0000 Received: from fifthhorseman.net (unknown [38.109.115.130]) by che.mayfirst.org (Postfix) with ESMTPSA id 2E3E0F984; Thu, 10 Dec 2015 12:36:24 -0500 (EST) Received: by fifthhorseman.net (Postfix, from userid 1000) id BA0DD207F2; Thu, 10 Dec 2015 12:36:23 -0500 (EST) From: Daniel Kahn Gillmor To: gcc-patches@gcc.gnu.org Cc: rb-general@lists.reproducible-builds.org, anthraxx@archlinux.org, niels@thykier.net, Daniel Kahn Gillmor Subject: [PATCH] gcc: read -fdebug-prefix-map OLD from environment (improved reproducibility) Date: Thu, 10 Dec 2015 12:36:18 -0500 Message-Id: <1449768978-3872-1-git-send-email-dkg@fifthhorseman.net> In-Reply-To: <87egf1mxfl.fsf@alice.fifthhorseman.net> References: <87egf1mxfl.fsf@alice.fifthhorseman.net> X-IsSubscribed: yes Work on the reproducible-builds project [0] has identified that build paths are one cause of output variation between builds. This changeset allows users to avoid this variation when building C objects with debug symbols, while leaving the default behavior unchanged. Background ---------- gcc includes the build path in any generated DWARF debugging symbols, specifically in DW_AT_comp_dir, but allows the embedded path to be changed via -fdebug-prefix-map. When -fdebug-prefix-map is used with the current build path, it removes the build path from DW_AT_comp_dir but places it instead in DW_AT_producer, so the reproducibility problem isn't resolved. When building software for binary redistribution, the actual build path on the build machine is irrelevant, and doesn't need to be exposed in the debug symbols. Resolution ---------- This patch extends the first argument to -fdebug-prefix-map ("old") to be able to read from the environment, which allows a packager to avoid embedded build paths in the debugging symbols with something like: export SOURCE_BUILD_DIR="$(pwd)" gcc -fdebug-prefix-map=\$SOURCE_BUILD_DIR=/usr/src Details ------- Specifically, if the first character of the "old" argument is a literal $, then gcc will treat it as an environment variable name, and use the value of the env var for prefix mapping. As a result, DW_AT_producer contains the literal envvar name, DW_AT_comp_dir contains the transformed build path, and the actual build path is not at all present in the generated object file. This has been tested successfully on amd64 machines, and i see no reason why it would be platform-specific. More discussion of alternate approaches considered and discarded in the development of this change can be found at [1] for those interested. Feedback welcome! [0] https://reproducible-builds.org [1] https://lists.alioth.debian.org/pipermail/reproducible-builds/Week-of-Mon-20151130/004051.html --- gcc/doc/invoke.texi | 4 +++- gcc/final.c | 27 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5256031..234432f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6440,7 +6440,9 @@ link processing time. Merging is enabled by default. @item -fdebug-prefix-map=@var{old}=@var{new} @opindex fdebug-prefix-map When compiling files in directory @file{@var{old}}, record debugging -information describing them as in @file{@var{new}} instead. +information describing them as in @file{@var{new}} instead. If +@file{@var{old}} starts with a @samp{$}, the corresponding environment +variable will be dereferenced, and its value will be used instead. @item -fno-dwarf2-cfi-asm @opindex fdwarf2-cfi-asm diff --git a/gcc/final.c b/gcc/final.c index 8cb5533..bc43b61 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1525,6 +1525,9 @@ add_debug_prefix_map (const char *arg) { debug_prefix_map *map; const char *p; + char *env; + const char *old; + size_t oldlen; p = strchr (arg, '='); if (!p) @@ -1532,9 +1535,29 @@ add_debug_prefix_map (const char *arg) error ("invalid argument %qs to -fdebug-prefix-map", arg); return; } + if (*arg == '$') + { + env = xstrndup (arg+1, p - (arg+1)); + old = getenv(env); + if (!old) + { + warning (0, "environment variable %qs not set in argument to " + "-fdebug-prefix-map", env); + free(env); + return; + } + oldlen = strlen(old); + free(env); + } + else + { + old = xstrndup (arg, p - arg); + oldlen = p - arg; + } + map = XNEW (debug_prefix_map); - map->old_prefix = xstrndup (arg, p - arg); - map->old_len = p - arg; + map->old_prefix = old; + map->old_len = oldlen; p++; map->new_prefix = xstrdup (p); map->new_len = strlen (p);