This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Prevent LTO section collision for a symbol name starting with '*'.
- From: Martin Liška <mliska at suse dot cz>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: Richard Biener <richard dot guenther at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 18 Sep 2019 12:14:29 +0200
- Subject: Re: [PATCH] Prevent LTO section collision for a symbol name starting with '*'.
- References: <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> <bbc38fef-89ce-c433-209c-3dcd722d6ea5@suse.cz> <20190823150502.l4dnv3fxzsfhro4g@kam.mff.cuni.cz> <b00ee4a3-2246-b146-d489-09535203b557@suse.cz> <20190823223622.yq2upqnvpm574qws@kam.mff.cuni.cz> <68650f0d-1472-ba6a-0530-19ed3a011321@suse.cz> <289c7087-008d-1921-fe78-80a3e1abd986@suse.cz> <20190909143343.2tf2tc3mvnhwcqur@kam.mff.cuni.cz> <6e297b4b-3086-fa84-6fce-a5ced89694bb@suse.cz>
On 9/11/19 1:38 PM, Martin Liška wrote:
> The inline_clone manipulation happens in cgraph_node::find_replacement where
> we manipulate the clone_of.
I fixed that but there's a similar situation which goes other way around:
cgraph_node *
cgraph_node::get_create (tree decl)
{
cgraph_node *first_clone = cgraph_node::get (decl);
if (first_clone && !first_clone->global.inlined_to)
return first_clone;
cgraph_node *node = cgraph_node::create (decl);
if (first_clone)
{
first_clone->clone_of = node;
Here we come up with a new parent and this->clone_of is set to the parent.
We ought to come cgraph_node::order here, but I don't like.
Right now cgraph_node::order is a way how one can identify a node in IPA dumps.
The patch is breaking that. I'm not sure we want the patch right now.
Martin
>From 61603b9a995d6cab7938ad2b0e2a14fde3d02308 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 26 Aug 2019 11:59:23 +0200
Subject: [PATCH] Use symtab_node::order in LTO sections with body.
---
gcc/cgraph.c | 13 +++++++++----
gcc/cgraphclones.c | 5 +++++
gcc/ipa-fnsummary.c | 2 +-
gcc/ipa-hsa.c | 2 +-
gcc/ipa-icf.c | 2 +-
gcc/ipa-prop.c | 6 ++++--
gcc/lto-cgraph.c | 13 +++++--------
gcc/lto-opts.c | 2 +-
gcc/lto-section-in.c | 12 +++++++-----
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 | 13 +++++++------
gcc/testsuite/gcc.dg/lto/pr91393_0.c | 11 +++++++++++
gcc/varpool.c | 7 ++++---
17 files changed, 85 insertions(+), 49 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/lto/pr91393_0.c
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 843891e9e56..9f86c2bdd10 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -3602,12 +3602,17 @@ cgraph_node::get_untransformed_body (void)
struct lto_in_decl_state *decl_state
= lto_get_function_in_decl_state (file_data, decl);
+ cgraph_node *origin = this;
+ while (origin->clone_of)
+ origin = origin->clone_of;
+
+ int stream_order = origin->order - file_data->order_base;
data = lto_get_section_data (file_data, LTO_section_function_body,
- name, &len, decl_state->compressed);
+ name, stream_order, &len,
+ decl_state->compressed);
if (!data)
- fatal_error (input_location, "%s: section %s is missing",
- file_data->file_name,
- name);
+ fatal_error (input_location, "%s: section %s.%d is missing",
+ file_data->file_name, name, stream_order);
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index fa753697c78..f47c50fbb00 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -772,6 +772,11 @@ cgraph_node::find_replacement (void)
n->clone_of = next_inline_clone;
n = n->next_sibling_clone;
}
+
+ /* Update order in order to be able to find a LTO section
+ with function body. */
+ replacement->order = order;
+
return replacement;
}
else
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 1bf1806eaf8..b7e0571cdfc 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -3463,7 +3463,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 a23aa2590a0..9b36d96fd2a 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -4592,7 +4592,9 @@ 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);
@@ -4837,7 +4839,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<symtab_node *> 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<symtab_node *> 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 0e9f24e1189..99c6fe53923 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..792a3045957 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,8 @@ 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..af4dd266fae 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..0981dd219ff 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -2200,7 +2200,8 @@ 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 +2214,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 %<LTO_section_decls%> from %s",
@@ -2391,15 +2392,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..d4b83429c12 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -299,11 +299,12 @@ 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 - file_data->order_base,
+ &len, decl_state->compressed);
if (!data)
- fatal_error (input_location, "%s: section %s is missing",
+ fatal_error (input_location, "%s: section %s.%d is missing",
file_data->file_name,
- name);
+ name, order - file_data->order_base);
if (!quiet_flag)
fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
--
2.23.0