From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 37689 invoked by alias); 26 Aug 2019 10:04:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 37680 invoked by uid 89); 26 Aug 2019 10:04:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.8 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 spammy=streaming, orders, aux X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Aug 2019 10:04:34 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 3A361B62E; Mon, 26 Aug 2019 10:04:32 +0000 (UTC) Subject: Re: [PATCH] Prevent LTO section collision for a symbol name starting with '*'. To: Jan Hubicka Cc: Richard Biener , GCC Patches References: <55b4acda-9673-557b-5819-50bff07fa095@suse.cz> <20190815143341.m4t76ewfi4zn3ayl@kam.mff.cuni.cz> <7c27efd6-e9dd-ac4f-ebaf-6626a226bb61@suse.cz> <1d1856dc-6e42-89ad-85ee-519b1a691afd@suse.cz> <20190823143728.favozczljnminl4d@kam.mff.cuni.cz> <20190823150502.l4dnv3fxzsfhro4g@kam.mff.cuni.cz> <20190823223622.yq2upqnvpm574qws@kam.mff.cuni.cz> From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: <68650f0d-1472-ba6a-0530-19ed3a011321@suse.cz> Date: Mon, 26 Aug 2019 11:54:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <20190823223622.yq2upqnvpm574qws@kam.mff.cuni.cz> Content-Type: multipart/mixed; boundary="------------2ECB3EA8B33CD8DF6521E4FC" X-IsSubscribed: yes X-SW-Source: 2019-08/txt/msg01734.txt.bz2 This is a multi-part message in MIME format. --------------2ECB3EA8B33CD8DF6521E4FC Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 1038 Ok. I have a semi-working patch that has issues for inline clones. When we call cgraph_node::get_untransformed_body for an inline clone, then one needs to use clone_of->order to find proper LTO stream. What's more problematic is that such clone can be expanded: f/12 (f) @0x7ffff769f708 Type: function definition analyzed Visibility: external public References: mumble.lto_priv.0/8 (write) Referring: Read from file: /tmp/cciAkXHp.ltrans1.o Function f/12 is inline copy in main/0 Availability: local Function flags: count:1073741824 (estimated locally) local nonfreeing_fn executed_once Called by: main/0 (inlined) (1073741824 (estimated locally),1.00 per call) Calls: and lost. So we end up with an orphan and we ICE with: /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/lto/20081112_0.c: In function ‘main’: /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/lto/20081112_0.c:10:3: fatal error: /tmp/cciAkXHp.ltrans1.o: section f is missing So usage of symtab_node::order seems awkward to me :/ Martin --------------2ECB3EA8B33CD8DF6521E4FC Content-Type: text/x-patch; name="0001-WIP-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-WIP-v2.patch" Content-length: 18205 >From d4607fe7ce11bc5e35583ee545979d000dec3233 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 26 Aug 2019 11:59:23 +0200 Subject: [PATCH] WIP v2. --- gcc/cgraph.c | 4 +++- gcc/ipa-fnsummary.c | 2 +- gcc/ipa-hsa.c | 2 +- gcc/ipa-icf.c | 2 +- gcc/ipa-prop.c | 4 ++-- gcc/lto-cgraph.c | 13 +++++-------- gcc/lto-opts.c | 2 +- gcc/lto-section-in.c | 11 ++++++----- gcc/lto-section-out.c | 2 +- gcc/lto-streamer-in.c | 4 ++-- gcc/lto-streamer-out.c | 21 ++++++++++++--------- gcc/lto-streamer.c | 9 +++++++-- gcc/lto-streamer.h | 10 +++++++--- gcc/lto/lto-common.c | 12 ++++++------ gcc/testsuite/gcc.dg/lto/pr91393_0.c | 11 +++++++++++ gcc/varpool.c | 2 +- 16 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr91393_0.c diff --git a/gcc/cgraph.c b/gcc/cgraph.c index ea8ab38d806..7de4b427a87 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -3602,8 +3602,10 @@ cgraph_node::get_untransformed_body (void) struct lto_in_decl_state *decl_state = lto_get_function_in_decl_state (file_data, decl); + int stream_order = clone_of != NULL ? clone_of->order : order; data = lto_get_section_data (file_data, LTO_section_function_body, - name, &len, decl_state->compressed); + name, stream_order - file_data->order_base, &len, + decl_state->compressed); if (!data) fatal_error (input_location, "%s: section %s is missing", file_data->file_name, diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 278bf606661..424aea73780 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -3354,7 +3354,7 @@ ipa_fn_summary_read (void) size_t len; const char *data = lto_get_section_data (file_data, LTO_section_ipa_fn_summary, - NULL, &len); + NULL, 0, &len); if (data) inline_read_section (file_data, data, len); else diff --git a/gcc/ipa-hsa.c b/gcc/ipa-hsa.c index 8af1d734d85..c9739fa6135 100644 --- a/gcc/ipa-hsa.c +++ b/gcc/ipa-hsa.c @@ -278,7 +278,7 @@ ipa_hsa_read_summary (void) { size_t len; const char *data = lto_get_section_data (file_data, LTO_section_ipa_hsa, - NULL, &len); + NULL, 0, &len); if (data) ipa_hsa_read_section (file_data, data, len); diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index c9c3cb4a331..41663821d36 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -2387,7 +2387,7 @@ sem_item_optimizer::read_summary (void) { size_t len; const char *data = lto_get_section_data (file_data, - LTO_section_ipa_icf, NULL, &len); + LTO_section_ipa_icf, NULL, 0, &len); if (data) read_section (file_data, data, len); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1a0e12e6c0c..3a4a48df5df 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -4600,7 +4600,7 @@ ipa_prop_read_jump_functions (void) while ((file_data = file_data_vec[j++])) { size_t len; - const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len); + const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, 0, &len); if (data) ipa_prop_read_section (file_data, data, len); @@ -4845,7 +4845,7 @@ ipcp_read_transformation_summaries (void) size_t len; const char *data = lto_get_section_data (file_data, LTO_section_ipcp_transform, - NULL, &len); + NULL, 0, &len); if (data) read_replacements_section (file_data, data, len); } diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index bc0f0107333..aeabed08f04 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -49,9 +49,6 @@ static void input_cgraph_opt_summary (vec nodes); /* Number of LDPR values known to GCC. */ #define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1) -/* All node orders are ofsetted by ORDER_BASE. */ -static int order_base; - /* Cgraph streaming is organized as set of record whose type is indicated by a tag. */ enum LTO_symtab_tags @@ -1218,7 +1215,7 @@ input_node (struct lto_file_decl_data *file_data, int i, count; tree group; const char *section; - order = streamer_read_hwi (ib) + order_base; + order = streamer_read_hwi (ib) + file_data->order_base; clone_ref = streamer_read_hwi (ib); decl_index = streamer_read_uhwi (ib); @@ -1337,7 +1334,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, tree group; const char *section; - order = streamer_read_hwi (ib) + order_base; + order = streamer_read_hwi (ib) + file_data->order_base; decl_index = streamer_read_uhwi (ib); var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); @@ -1504,7 +1501,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, unsigned i; tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag); - order_base = symtab->order; + file_data->order_base = symtab->order; while (tag) { if (tag == LTO_symtab_edge) @@ -1529,7 +1526,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag); } - lto_input_toplevel_asms (file_data, order_base); + lto_input_toplevel_asms (file_data, file_data->order_base); /* AUX pointers should be all non-zero for function nodes read from the stream. */ if (flag_checking) @@ -2010,7 +2007,7 @@ input_cgraph_opt_summary (vec nodes) size_t len; const char *data = lto_get_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, - &len); + 0, &len); if (data) input_cgraph_opt_section (file_data, data, len, nodes); diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c index 5e59e9327e7..14a1753e547 100644 --- a/gcc/lto-opts.c +++ b/gcc/lto-opts.c @@ -65,7 +65,7 @@ lto_write_options (void) char *args; bool first_p = true; - section_name = lto_get_section_name (LTO_section_opts, NULL, NULL); + section_name = lto_get_section_name (LTO_section_opts, NULL, 0, NULL); lto_begin_section (section_name, false); obstack_init (&temporary_obstack); diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 0bdcf62b1de..16b748a628b 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -130,10 +130,11 @@ struct lto_data_header const char * lto_get_section_data (struct lto_file_decl_data *file_data, enum lto_section_type section_type, - const char *name, + const char *name, int order, size_t *len, bool decompress) { - const char *data = (get_section_f) (file_data, section_type, name, len); + const char *data = (get_section_f) (file_data, section_type, name, order, + len); const size_t header_length = sizeof (struct lto_data_header); struct lto_data_header *header; struct lto_buffer buffer; @@ -176,10 +177,10 @@ lto_get_section_data (struct lto_file_decl_data *file_data, const char * lto_get_raw_section_data (struct lto_file_decl_data *file_data, enum lto_section_type section_type, - const char *name, + const char *name, int order, size_t *len) { - return (get_section_f) (file_data, section_type, name, len); + return (get_section_f) (file_data, section_type, name, order, len); } /* Free the data found from the above call. The first three @@ -234,7 +235,7 @@ lto_create_simple_input_block (struct lto_file_decl_data *file_data, enum lto_section_type section_type, const char **datar, size_t *len) { - const char *data = lto_get_section_data (file_data, section_type, NULL, len); + const char *data = lto_get_section_data (file_data, section_type, NULL, 0, len); const struct lto_simple_header * header = (const struct lto_simple_header *) data; diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c index 7ae102164ef..69fb8b7cffa 100644 --- a/gcc/lto-section-out.c +++ b/gcc/lto-section-out.c @@ -278,7 +278,7 @@ lto_destroy_simple_output_block (struct lto_simple_output_block *ob) char *section_name; struct lto_simple_header header; - section_name = lto_get_section_name (ob->section_type, NULL, NULL); + section_name = lto_get_section_name (ob->section_type, NULL, 0, NULL); lto_begin_section (section_name, !flag_wpa); free (section_name); diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 3158edd4c5f..486aade9cc0 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1568,7 +1568,7 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base) { size_t len; const char *data = lto_get_section_data (file_data, LTO_section_asm, - NULL, &len); + NULL, 0, &len); const struct lto_simple_header_with_strings *header = (const struct lto_simple_header_with_strings *) data; int string_offset; @@ -1607,7 +1607,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data) { size_t len; const char *data = lto_get_section_data (file_data, LTO_section_mode_table, - NULL, &len); + NULL, 0, &len); if (! data) { internal_error ("cannot read LTO mode table from %s", diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index d85b03a6c4a..cb232c1b013 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -1963,10 +1963,12 @@ produce_asm (struct output_block *ob, tree fn) if (section_type == LTO_section_function_body) { const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn)); - section_name = lto_get_section_name (section_type, name, NULL); + section_name = lto_get_section_name (section_type, name, + symtab_node::get(fn)->order, + NULL); } else - section_name = lto_get_section_name (section_type, NULL, NULL); + section_name = lto_get_section_name (section_type, NULL, 0, NULL); lto_begin_section (section_name, !flag_wpa); free (section_name); @@ -2259,7 +2261,7 @@ lto_output_toplevel_asms (void) streamer_write_string_cst (ob, ob->main_stream, NULL_TREE); - section_name = lto_get_section_name (LTO_section_asm, NULL, NULL); + section_name = lto_get_section_name (LTO_section_asm, NULL, 0, NULL); lto_begin_section (section_name, !flag_wpa); free (section_name); @@ -2292,7 +2294,7 @@ copy_function_or_variable (struct symtab_node *node) size_t len; const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)); char *section_name = - lto_get_section_name (LTO_section_function_body, name, NULL); + lto_get_section_name (LTO_section_function_body, name, node->order, NULL); size_t i, j; struct lto_in_decl_state *in_state; struct lto_out_decl_state *out_state = lto_get_out_decl_state (); @@ -2306,7 +2308,8 @@ copy_function_or_variable (struct symtab_node *node) name = lto_get_decl_name_mapping (file_data, name); data = lto_get_raw_section_data (file_data, LTO_section_function_body, - name, &len); + name, node->order - file_data->order_base, + &len); gcc_assert (data); /* Do a bit copy of the function body. */ @@ -2391,7 +2394,7 @@ produce_lto_section () /* Stream LTO meta section. */ output_block *ob = create_output_block (LTO_section_lto); - char * section_name = lto_get_section_name (LTO_section_lto, NULL, NULL); + char * section_name = lto_get_section_name (LTO_section_lto, NULL, 0, NULL); lto_begin_section (section_name, false); free (section_name); @@ -2735,7 +2738,7 @@ static void produce_symtab (struct output_block *ob) { struct streamer_tree_cache_d *cache = ob->writer_cache; - char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL); + char *section_name = lto_get_section_name (LTO_section_symtab, NULL, 0, NULL); lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder; lto_symtab_encoder_iterator lsei; @@ -2835,7 +2838,7 @@ lto_write_mode_table (void) streamer_write_bitpack (&bp); char *section_name - = lto_get_section_name (LTO_section_mode_table, NULL, NULL); + = lto_get_section_name (LTO_section_mode_table, NULL, 0, NULL); lto_begin_section (section_name, !flag_wpa); free (section_name); @@ -2879,7 +2882,7 @@ produce_asm_for_decls (void) memset (&header, 0, sizeof (struct lto_decl_header)); - section_name = lto_get_section_name (LTO_section_decls, NULL, NULL); + section_name = lto_get_section_name (LTO_section_decls, NULL, 0, NULL); lto_begin_section (section_name, !flag_wpa); free (section_name); diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index bd0126faebb..2ad979fdf34 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -114,7 +114,8 @@ lto_tag_name (enum LTO_tags tag) to free the returned name. */ char * -lto_get_section_name (int section_type, const char *name, struct lto_file_decl_data *f) +lto_get_section_name (int section_type, const char *name, + int node_order, struct lto_file_decl_data *f) { const char *add; char post[32]; @@ -125,7 +126,11 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d gcc_assert (name != NULL); if (name[0] == '*') name++; - add = name; + + char *buffer = (char *)xmalloc (strlen (name) + 32); + sprintf (buffer, "%s.%d", name, node_order); + + add = buffer; sep = ""; } else if (section_type < LTO_N_SECTION_TYPES) diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index bf755a64141..019b0670bf2 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -282,6 +282,7 @@ lto_file_decl_data_num_ ## name ## s (struct lto_file_decl_data *data) \ typedef const char* (lto_get_section_data_f) (struct lto_file_decl_data *, enum lto_section_type, const char *, + int, size_t *); /* Return the data found from the above call. The first three @@ -619,6 +620,8 @@ struct GTY(()) lto_file_decl_data /* Read LTO section. */ lto_section lto_section_header; + + int order_base; }; typedef struct lto_file_decl_data *lto_file_decl_data_ptr; @@ -785,11 +788,11 @@ extern void lto_set_in_hooks (struct lto_file_decl_data **, extern struct lto_file_decl_data **lto_get_file_decl_data (void); extern const char *lto_get_section_data (struct lto_file_decl_data *, enum lto_section_type, - const char *, size_t *, + const char *, int, size_t *, bool decompress = false); extern const char *lto_get_raw_section_data (struct lto_file_decl_data *, enum lto_section_type, - const char *, size_t *); + const char *, int, size_t *); extern void lto_free_section_data (struct lto_file_decl_data *, enum lto_section_type, const char *, const char *, size_t, @@ -853,7 +856,8 @@ extern void lto_append_block (struct lto_output_stream *); extern bool lto_stream_offload_p; extern const char *lto_tag_name (enum LTO_tags); -extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *); +extern char *lto_get_section_name (int, const char *, int, + struct lto_file_decl_data *); extern void print_lto_report (const char *); extern void lto_streamer_init (void); extern bool gate_lto_out (void); diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c index 9a17933d094..4a836d622af 100644 --- a/gcc/lto/lto-common.c +++ b/gcc/lto/lto-common.c @@ -2200,7 +2200,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) #endif /* Read and verify LTO section. */ - data = lto_get_section_data (file_data, LTO_section_lto, NULL, &len, false); + data = lto_get_section_data (file_data, LTO_section_lto, NULL, 0, &len, false); if (data == NULL) { fatal_error (input_location, "bytecode stream in file %qs generated " @@ -2213,7 +2213,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) file_data->lto_section_header.minor_version, file_data->file_name); - data = lto_get_section_data (file_data, LTO_section_decls, NULL, &len); + data = lto_get_section_data (file_data, LTO_section_decls, NULL, 0, &len); if (data == NULL) { internal_error ("cannot read % from %s", @@ -2391,15 +2391,15 @@ lto_read_section_data (struct lto_file_decl_data *file_data, static const char * get_section_data (struct lto_file_decl_data *file_data, - enum lto_section_type section_type, - const char *name, - size_t *len) + enum lto_section_type section_type, + const char *name, int order, + size_t *len) { htab_t section_hash_table = file_data->section_hash_table; struct lto_section_slot *f_slot; struct lto_section_slot s_slot; const char *section_name = lto_get_section_name (section_type, name, - file_data); + order, file_data); char *data = NULL; *len = 0; diff --git a/gcc/testsuite/gcc.dg/lto/pr91393_0.c b/gcc/testsuite/gcc.dg/lto/pr91393_0.c new file mode 100644 index 00000000000..43b2426c86b --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr91393_0.c @@ -0,0 +1,11 @@ +void __open_alias(int, ...) __asm__("open"); +void __open_alias(int flags, ...) {} +extern __inline __attribute__((__gnu_inline__)) int open() {} +struct { + void *func; +} a = {open}; + +int main() +{ + return 0; +} diff --git a/gcc/varpool.c b/gcc/varpool.c index 8e5a9372656..589c13888fe 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -299,7 +299,7 @@ varpool_node::get_constructor (void) = lto_get_function_in_decl_state (file_data, decl); data = lto_get_section_data (file_data, LTO_section_function_body, - name, &len, decl_state->compressed); + name, order, &len, decl_state->compressed); if (!data) fatal_error (input_location, "%s: section %s is missing", file_data->file_name, -- 2.22.1 --------------2ECB3EA8B33CD8DF6521E4FC--