From patchwork Tue Apr 11 11:34:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ximin Luo X-Patchwork-Id: 749428 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 3w2Q4D1HJYz9sNS for ; Tue, 11 Apr 2017 21:36:27 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="fQNqg6Dn"; 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=a6Z0xV11bC00UCvWSfIavEiZv5F9X2hhKk0enTyfLxVPZwmv7mfmn D19/YoFfS5+zUinYt9IErF6qiC3FNwrhb3DdqsE6+iNn/1aOk6cgJNdMj/g9MZTW J1qIi6uKOHwY5JEcL7uQ+2DhghwJESxMqvnPoHK0gIdxs+8/J9groo= 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=n+pLtyj428X/vJgP5f/XBKJIxJY=; b=fQNqg6Dn9ByKzg4OHSRG GJCojViOcAazvVtjJ4G0uEs9q55nO8bdUOrksNOtL+pyDnWOoQB0HqAanmmZgjmk CxaI8H8iVWK0IXVVPMmZBJdLQ5q1/5uQJvnyTIWVTWkNyWn7HWj+uU+Sc534vNAn XJXlETzU/pWdGHph/kqjrY0= Received: (qmail 114656 invoked by alias); 11 Apr 2017 11:35:17 -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 114131 invoked by uid 89); 11 Apr 2017 11:35:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=luo, Luo, figuring, H*RU:sk:mail.he X-HELO: mail.headstrong.de Received: from mail.headstrong.de (HELO mail.headstrong.de) (81.7.4.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Apr 2017 11:35:03 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.headstrong.de (Postfix) with ESMTP id 5A5A91C0061C; Tue, 11 Apr 2017 13:35:02 +0200 (CEST) Authentication-Results: mail.headstrong.de (amavisd-new); dkim=pass (1024-bit key) reason="pass (just generated, assumed good)" header.d=headstrong.de Received: from mail.headstrong.de ([127.0.0.1]) by localhost (mail.headstrong.de [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 2bRhUjpq8Er9; Tue, 11 Apr 2017 13:35:01 +0200 (CEST) Received: from infinity0 by pdeb1.fritz.box with local (Exim 4.88) (envelope-from ) id 1cxu4Y-00046e-4W; Tue, 11 Apr 2017 13:34:58 +0200 From: Ximin Luo To: GCC Patches Cc: Ximin Luo Subject: [PATCH 2/3] Use BUILD_PATH_PREFIX_MAP envvar to transform __FILE__ Date: Tue, 11 Apr 2017 13:34:45 +0200 Message-Id: <20170411113446.15683-3-infinity0@pwned.gg> In-Reply-To: <20170411113446.15683-1-infinity0@pwned.gg> References: <20170411113446.15683-1-infinity0@pwned.gg> Use the BUILD_PATH_PREFIX_MAP environment variable when expanding the __FILE__ macro, in the same way that debug-prefix-map works for debugging symbol paths. This patch follows similar lines to the earlier patch for SOURCE_DATE_EPOCH. Specifically, we read the environment variable not in libcpp but via a hook which has an implementation defined in gcc/c-family. However, to achieve this is more complex than the earlier patch: we need to share the prefix_map data structure and associated functions between libcpp and c-family. Therefore, we need to move these to libiberty. (For comparison, the SOURCE_DATE_EPOCH patch did not need this because time_t et. al. are in the standard C library.) Acknowledgements ---------------- Dhole who wrote the earlier patch for SOURCE_DATE_EPOCH which saved me a lot of time on figuring out what to edit. ChangeLogs ---------- gcc/c-family/ChangeLog: 2017-03-27 Ximin Luo * c-common.c (cb_get_build_path_prefix_map): Define new call target. * c-common.h (cb_get_build_path_prefix_map): Declare call target. * c-lex.c (init_c_lex): Set the get_build_path_prefix_map callback. libcpp/ChangeLog: 2017-03-27 Ximin Luo * include/cpplib.h (cpp_callbacks): Add get_build_path_prefix_map callback. * init.c (cpp_create_reader): Initialise build_path_prefix_map field. * internal.h (cpp_reader): Add new field build_path_prefix_map. * macro.c (_cpp_builtin_macro_text): Set the build_path_prefix_map field if unset and apply it when expanding __FILE__ macros. gcc/testsuite/ChangeLog: 2017-03-27 Ximin Luo * gcc.dg/cpp/build_path_prefix_map-1.c: New test. * gcc.dg/cpp/build_path_prefix_map-2.c: New test. Index: gcc-7-20170402/gcc/c-family/c-common.c =================================================================== --- gcc-7-20170402.orig/gcc/c-family/c-common.c +++ gcc-7-20170402/gcc/c-family/c-common.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. #include "config.h" #include "system.h" +#include "prefix-map.h" #include "coretypes.h" #include "target.h" #include "function.h" @@ -8012,6 +8013,25 @@ cb_get_source_date_epoch (cpp_reader *pf return (time_t) epoch; } +/* Read BUILD_PATH_PREFIX_MAP from environment to have deterministic relative + paths to replace embedded absolute paths to get reproducible results. + Returns NULL if BUILD_PATH_PREFIX_MAP is badly formed. */ + +prefix_map ** +cb_get_build_path_prefix_map (cpp_reader *pfile ATTRIBUTE_UNUSED) +{ + prefix_map **map = XCNEW (prefix_map *); + + const char *arg = getenv ("BUILD_PATH_PREFIX_MAP"); + if (!arg || prefix_map_parse (map, arg)) + return map; + + free (map); + error_at (input_location, "environment variable BUILD_PATH_PREFIX_MAP is " + "not well formed; see the GCC documentation for more details."); + return NULL; +} + /* Callback for libcpp for offering spelling suggestions for misspelled directives. GOAL is an unrecognized string; CANDIDATES is a NULL-terminated array of candidate strings. Return the closest Index: gcc-7-20170402/gcc/c-family/c-common.h =================================================================== --- gcc-7-20170402.orig/gcc/c-family/c-common.h +++ gcc-7-20170402/gcc/c-family/c-common.h @@ -1085,6 +1085,11 @@ extern time_t cb_get_source_date_epoch ( __TIME__ can store. */ #define MAX_SOURCE_DATE_EPOCH HOST_WIDE_INT_C (253402300799) +/* Read BUILD_PATH_PREFIX_MAP from environment to have deterministic relative + paths to replace embedded absolute paths to get reproducible results. + Returns NULL if BUILD_PATH_PREFIX_MAP is badly formed. */ +extern prefix_map **cb_get_build_path_prefix_map (cpp_reader *pfile); + /* Callback for libcpp for offering spelling suggestions for misspelled directives. */ extern const char *cb_get_suggestion (cpp_reader *, const char *, Index: gcc-7-20170402/gcc/c-family/c-lex.c =================================================================== --- gcc-7-20170402.orig/gcc/c-family/c-lex.c +++ gcc-7-20170402/gcc/c-family/c-lex.c @@ -81,6 +81,7 @@ init_c_lex (void) cb->read_pch = c_common_read_pch; cb->has_attribute = c_common_has_attribute; cb->get_source_date_epoch = cb_get_source_date_epoch; + cb->get_build_path_prefix_map = cb_get_build_path_prefix_map; cb->get_suggestion = cb_get_suggestion; /* Set the debug callbacks if we can use them. */ Index: gcc-7-20170402/libcpp/include/cpplib.h =================================================================== --- gcc-7-20170402.orig/libcpp/include/cpplib.h +++ gcc-7-20170402/libcpp/include/cpplib.h @@ -607,6 +607,9 @@ struct cpp_callbacks /* Callback to parse SOURCE_DATE_EPOCH from environment. */ time_t (*get_source_date_epoch) (cpp_reader *); + /* Callback to parse BUILD_PATH_PREFIX_MAP from environment. */ + struct prefix_map **(*get_build_path_prefix_map) (cpp_reader *); + /* Callback for providing suggestions for misspelled directives. */ const char *(*get_suggestion) (cpp_reader *, const char *, const char *const *); }; Index: gcc-7-20170402/libcpp/init.c =================================================================== --- gcc-7-20170402.orig/libcpp/init.c +++ gcc-7-20170402/libcpp/init.c @@ -261,6 +261,9 @@ cpp_create_reader (enum c_lang lang, cpp /* Initialize source_date_epoch to -2 (not yet set). */ pfile->source_date_epoch = (time_t) -2; + /* Initialize build_path_prefix_map to NULL (not yet set). */ + pfile->build_path_prefix_map = NULL; + /* The expression parser stack. */ _cpp_expand_op_stack (pfile); Index: gcc-7-20170402/libcpp/internal.h =================================================================== --- gcc-7-20170402.orig/libcpp/internal.h +++ gcc-7-20170402/libcpp/internal.h @@ -507,6 +507,11 @@ struct cpp_reader set to -1 to disable it or to a non-negative value to enable it. */ time_t source_date_epoch; + /* Externally set prefix-map to transform absolute paths, useful for + reproducibility. It should be initialized to NULL (not yet set or + disabled) or to a `struct prefix_map` double pointer to enable it. */ + struct prefix_map **build_path_prefix_map; + /* EOF token, and a token forcing paste avoidance. */ cpp_token avoid_paste; cpp_token eof; Index: gcc-7-20170402/libcpp/macro.c =================================================================== --- gcc-7-20170402.orig/libcpp/macro.c +++ gcc-7-20170402/libcpp/macro.c @@ -26,6 +26,7 @@ along with this program; see the file CO #include "system.h" #include "cpplib.h" #include "internal.h" +#include "prefix-map.h" typedef struct macro_arg macro_arg; /* This structure represents the tokens of a macro argument. These @@ -291,7 +292,17 @@ _cpp_builtin_macro_text (cpp_reader *pfi unsigned int len; const char *name; uchar *buf; + prefix_map **map = pfile->build_path_prefix_map; + /* Set a prefix-map for __FILE__ if BUILD_PATH_PREFIX_MAP is defined. */ + if (map == NULL && pfile->cb.get_build_path_prefix_map != NULL) + { + map = pfile->cb.get_build_path_prefix_map (pfile); + if (map == NULL) + abort (); + pfile->build_path_prefix_map = map; + } + if (node->value.builtin == BT_FILE) name = linemap_get_expansion_filename (pfile->line_table, pfile->line_table->highest_line); @@ -301,6 +312,11 @@ _cpp_builtin_macro_text (cpp_reader *pfi if (!name) abort (); } + + /* Apply the prefix-map for deterministic path output. */ + if (map != NULL) + name = prefix_map_remap_alloca (*map, name); + len = strlen (name); buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); result = buf; Index: gcc-7-20170402/gcc/testsuite/gcc.dg/cpp/build_path_prefix_map-1.c =================================================================== --- /dev/null +++ gcc-7-20170402/gcc/testsuite/gcc.dg/cpp/build_path_prefix_map-1.c @@ -0,0 +1,11 @@ +/* __FILE__ should strip BUILD_PATH_PREFIX_MAP if the latter is a prefix. */ +/* { dg-do run } */ +/* { dg-set-compiler-env-var BUILD_PATH_PREFIX_MAP "MACROTEST=$srcdir" } */ + +int +main () +{ + if (__builtin_strcmp (__FILE__, "MACROTEST/gcc.dg/cpp/build_path_prefix_map-1.c") != 0) + __builtin_abort (); + return 0; +} Index: gcc-7-20170402/gcc/testsuite/gcc.dg/cpp/build_path_prefix_map-2.c =================================================================== --- /dev/null +++ gcc-7-20170402/gcc/testsuite/gcc.dg/cpp/build_path_prefix_map-2.c @@ -0,0 +1,12 @@ +/* __FILE__ should not be relative if BUILD_PATH_PREFIX_MAP is not set, and gcc is + asked to compile an absolute filename as is the case with this test. */ +/* { dg-do run } */ +/* { dg-set-compiler-env-var BUILD_PATH_PREFIX_MAP } */ + +int +main () +{ + if (__builtin_strcmp (__FILE__, "./gcc.dg/cpp/build_path_prefix_map-2.c") == 0) + __builtin_abort (); + return 0; +}