API extension for binutils (type of symbols).

* lto-section-in.c: Add ext_symtab.
	* lto-streamer-out.c (write_symbol_extension_info): New.
	(produce_symtab_extension): New.
	(produce_asm_for_decls): Stream also produce_symtab_extension.
	* lto-streamer.h (enum lto_section_type): New section.
	* lto-symtab.h (enum gcc_plugin_symbol_type): New.
	(enum gcc_plugin_symbol_section_kind): Likewise.
	* lto-plugin.c (LTO_SECTION_PREFIX): Rename to ...
	(LTO_SYMTAB_PREFIX): ... this.
	(LTO_SECTION_PREFIX_LEN): Rename to ...
	(LTO_SYMTAB_PREFIX_LEN): ... this.
	(LTO_SYMTAB_EXT_PREFIX): New.
	(LTO_SYMTAB_EXT_PREFIX_LEN): New.
	(LTO_LTO_PREFIX): New.
	(LTO_LTO_PREFIX_LEN): New.
	(parse_table_entry): Fill up unused to zero.
	(parse_table_entry_extension): New.
	(parse_symtab_extension): New.
	(finish_conflict_resolution): Change type
	for resolution.
	(process_symtab): Use new macro name.
	(process_symtab_extension): New.
	(claim_file_handler): Parse also process_symtab_extension.
	(onload): Call new add_symbols_v2.
This commit is contained in:
Martin Liska 2020-03-19 16:56:27 +01:00
parent f5389e17e4
commit c8429c2aba
No known key found for this signature in database
GPG Key ID: 4DC182DC0FA73785
8 changed files with 258 additions and 13 deletions

View File

@ -1,3 +1,11 @@
2020-03-19 Martin Liska <mliska@suse.cz>
* lto-section-in.c: Add ext_symtab.
* lto-streamer-out.c (write_symbol_extension_info): New.
(produce_symtab_extension): New.
(produce_asm_for_decls): Stream also produce_symtab_extension.
* lto-streamer.h (enum lto_section_type): New section.
2020-03-19 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94211

View File

@ -38,6 +38,7 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] =
"function_body",
"statics",
"symtab",
"ext_symtab",
"refs",
"asm",
"jmpfuncs",

View File

@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "print-tree.h"
#include "tree-dfa.h"
#include "file-prefix-map.h" /* remap_debug_filename() */
#include "output.h"
static void lto_write_tree (struct output_block*, tree, bool);
@ -2777,12 +2778,32 @@ write_symbol (struct streamer_tree_cache_d *cache,
lto_write_data (&slot_num, 4);
}
/* Write extension information for symbols (symbol type, section flags). */
static void
write_symbol_extension_info (tree t)
{
unsigned char c;
c = ((unsigned char) TREE_CODE (t) == VAR_DECL
? GCCST_VARIABLE : GCCST_FUNCTION);
lto_write_data (&c, 1);
unsigned char section_kind = 0;
if (TREE_CODE (t) == VAR_DECL)
{
section *s = get_variable_section (t, false);
if (s->common.flags & SECTION_BSS)
section_kind |= GCCSSK_BSS;
}
lto_write_data (&section_kind, 1);
}
/* Write an IL symbol table to OB.
SET and VSET are cgraph/varpool node sets we are outputting. */
static void
static unsigned int
produce_symtab (struct output_block *ob)
{
unsigned int streamed_symbols = 0;
struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, 0, NULL);
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
@ -2804,6 +2825,7 @@ produce_symtab (struct output_block *ob)
if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol (cache, node->decl, &seen, false);
++streamed_symbols;
}
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
@ -2813,9 +2835,62 @@ produce_symtab (struct output_block *ob)
if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol (cache, node->decl, &seen, false);
++streamed_symbols;
}
lto_end_section ();
return streamed_symbols;
}
/* Symtab extension version. */
#define LTO_SYMTAB_EXTENSION_VERSION 1
/* Write an IL symbol table extension to OB.
SET and VSET are cgraph/varpool node sets we are outputting. */
static void
produce_symtab_extension (struct output_block *ob,
unsigned int previous_streamed_symbols)
{
unsigned int streamed_symbols = 0;
char *section_name = lto_get_section_name (LTO_section_symtab_extension,
NULL, 0, NULL);
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
lto_symtab_encoder_iterator lsei;
lto_begin_section (section_name, false);
free (section_name);
unsigned char version = LTO_SYMTAB_EXTENSION_VERSION;
lto_write_data (&version, 1);
/* Write the symbol table.
First write everything defined and then all declarations.
This is necessary to handle cases where we have duplicated symbols. */
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
symtab_node *node = lsei_node (lsei);
if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol_extension_info (node->decl);
++streamed_symbols;
}
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
symtab_node *node = lsei_node (lsei);
if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
write_symbol_extension_info (node->decl);
++streamed_symbols;
}
gcc_assert (previous_streamed_symbols == streamed_symbols);
lto_end_section ();
}
@ -3001,7 +3076,10 @@ produce_asm_for_decls (void)
/* Write the symbol table. It is used by linker to determine dependencies
and thus we can skip it for WPA. */
if (!flag_wpa)
produce_symtab (ob);
{
unsigned int streamed_symbols = produce_symtab (ob);
produce_symtab_extension (ob, streamed_symbols);
}
/* Write command line opts. */
lto_write_options ();

View File

@ -219,6 +219,7 @@ enum lto_section_type
LTO_section_function_body,
LTO_section_static_initializer,
LTO_section_symtab,
LTO_section_symtab_extension,
LTO_section_refs,
LTO_section_asm,
LTO_section_jump_functions,

View File

@ -1,3 +1,8 @@
2020-03-19 Martin Liska <mliska@suse.cz>
* lto-symtab.h (enum gcc_plugin_symbol_type): New.
(enum gcc_plugin_symbol_section_kind): Likewise.
2020-03-19 Martin Liska <mliska@suse.cz>
* plugin-api.h (struct ld_plugin_symbol): Split

View File

@ -38,4 +38,17 @@ enum gcc_plugin_symbol_visibility
GCCPV_HIDDEN
};
enum gcc_plugin_symbol_type
{
GCCST_UNKNOWN,
GCCST_FUNCTION,
GCCST_VARIABLE,
};
enum gcc_plugin_symbol_section_kind
{
GCCSSK_DEFAULT,
GCCSSK_BSS
};
#endif /* GCC_LTO_SYMTAB_H */

View File

@ -1,3 +1,23 @@
2020-03-19 Martin Liska <mliska@suse.cz>
* lto-plugin.c (LTO_SECTION_PREFIX): Rename to ...
(LTO_SYMTAB_PREFIX): ... this.
(LTO_SECTION_PREFIX_LEN): Rename to ...
(LTO_SYMTAB_PREFIX_LEN): ... this.
(LTO_SYMTAB_EXT_PREFIX): New.
(LTO_SYMTAB_EXT_PREFIX_LEN): New.
(LTO_LTO_PREFIX): New.
(LTO_LTO_PREFIX_LEN): New.
(parse_table_entry): Fill up unused to zero.
(parse_table_entry_extension): New.
(parse_symtab_extension): New.
(finish_conflict_resolution): Change type
for resolution.
(process_symtab): Use new macro name.
(process_symtab_extension): New.
(claim_file_handler): Parse also process_symtab_extension.
(onload): Call new add_symbols_v2.
2020-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.

View File

@ -88,10 +88,14 @@ along with this program; see the file COPYING3. If not see
/* LTO magic section name. */
#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
#define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1)
#define OFFLOAD_SECTION ".gnu.offload_lto_.opts"
#define OFFLOAD_SECTION_LEN (sizeof (OFFLOAD_SECTION) - 1)
#define LTO_SYMTAB_PREFIX ".gnu.lto_.symtab"
#define LTO_SYMTAB_PREFIX_LEN (sizeof (LTO_SYMTAB_PREFIX) - 1)
#define LTO_SYMTAB_EXT_PREFIX ".gnu.lto_.ext_symtab"
#define LTO_SYMTAB_EXT_PREFIX_LEN (sizeof (LTO_SYMTAB_EXT_PREFIX) - 1)
#define LTO_LTO_PREFIX ".gnu.lto_.lto"
#define LTO_LTO_PREFIX_LEN (sizeof (LTO_LTO_PREFIX) - 1)
#define OFFLOAD_SECTION ".gnu.offload_lto_.opts"
#define OFFLOAD_SECTION_LEN (sizeof (OFFLOAD_SECTION) - 1)
/* The part of the symbol table the plugin has to keep track of. Note that we
must keep SYMS until all_symbols_read is called to give the linker time to
@ -159,7 +163,7 @@ static ld_plugin_register_cleanup register_cleanup;
static ld_plugin_add_input_file add_input_file;
static ld_plugin_add_input_library add_input_library;
static ld_plugin_message message;
static ld_plugin_add_symbols add_symbols;
static ld_plugin_add_symbols add_symbols, add_symbols_v2;
static struct plugin_file_info *claimed_files = NULL;
static unsigned int num_claimed_files = 0;
@ -286,6 +290,8 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
else
entry->comdat_key = xstrdup (entry->comdat_key);
entry->unused = entry->section_kind = entry->symbol_type = 0;
t = *p;
check (t <= 4, LDPL_FATAL, "invalid symbol kind found");
entry->def = translate_kind[t];
@ -309,6 +315,32 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
return p;
}
/* Parse an entry of the IL symbol table. The data to be parsed is pointed
by P and the result is written in ENTRY. The slot number is stored in SLOT.
Returns the address of the next entry. */
static char *
parse_table_entry_extension (char *p, struct ld_plugin_symbol *entry)
{
unsigned char t;
enum ld_plugin_symbol_type symbol_types[] =
{
LDST_UNKNOWN,
LDST_FUNCTION,
LDST_VARIABLE,
};
t = *p;
check (t <= 2, LDPL_FATAL, "invalid symbol type found");
entry->symbol_type = symbol_types[t];
p++;
entry->section_kind = *p;
p++;
return p;
}
/* Translate the IL symbol table located between DATA and END. Append the
slots and symbols to OUT. */
@ -339,6 +371,24 @@ translate (char *data, char *end, struct plugin_symtab *out)
out->aux = aux;
}
static void
parse_symtab_extension (char *data, char *end, struct plugin_symtab *out)
{
unsigned i;
unsigned char version = *data;
data++;
/* Version 1 contains the following data per entry:
- symbol_type
- section_kind
. */
if (version == 1)
for (i = 0; i < out->nsyms; i++)
data = parse_table_entry_extension (data, &out->syms[i]);
}
/* Free all memory that is no longer needed after writing the symbol
resolution. */
@ -431,7 +481,7 @@ finish_conflict_resolution (struct plugin_symtab *symtab,
for (i = 0; i < symtab->nsyms; i++)
{
int resolution = LDPR_UNKNOWN;
char resolution = LDPR_UNKNOWN;
if (symtab->aux[i].next_conflict == -1)
continue;
@ -953,7 +1003,7 @@ process_symtab (void *data, const char *name, off_t offset, off_t length)
char *s;
char *secdatastart, *secdata;
if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
if (strncmp (name, LTO_SYMTAB_PREFIX, LTO_SYMTAB_PREFIX_LEN) != 0)
return 1;
s = strrchr (name, '.');
@ -995,6 +1045,59 @@ err:
return 0;
}
/* Process one section of an object file. */
static int
process_symtab_extension (void *data, const char *name, off_t offset,
off_t length)
{
struct plugin_objfile *obj = (struct plugin_objfile *)data;
char *s;
char *secdatastart, *secdata;
if (strncmp (name, LTO_SYMTAB_EXT_PREFIX, LTO_SYMTAB_EXT_PREFIX_LEN) != 0)
return 1;
s = strrchr (name, '.');
if (s)
sscanf (s, ".%" PRI_LL "x", &obj->out->id);
secdata = secdatastart = xmalloc (length);
offset += obj->file->offset;
if (offset != lseek (obj->file->fd, offset, SEEK_SET))
goto err;
do
{
ssize_t got = read (obj->file->fd, secdata, length);
if (got == 0)
break;
else if (got > 0)
{
secdata += got;
length -= got;
}
else if (errno != EINTR)
goto err;
}
while (length > 0);
if (length > 0)
goto err;
parse_symtab_extension (secdatastart, secdata, obj->out);
obj->found++;
free (secdatastart);
return 1;
err:
if (message)
message (LDPL_FATAL, "%s: corrupt object file", obj->file->name);
/* Force claim_file_handler to abandon this file. */
obj->found = 0;
free (secdatastart);
return 0;
}
/* Find an offload section of an object file. */
static int
@ -1055,8 +1158,17 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
if (!obj.objfile && !err)
goto err;
if (obj.objfile)
errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err);
if (obj.objfile)
{
errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj,
&err);
/* Parsing symtab extension should be done only for add_symbols_v2 and
later versions. */
if (!errmsg && add_symbols_v2 != NULL)
errmsg = simple_object_find_sections (obj.objfile,
process_symtab_extension,
&obj, &err);
}
if (!obj.objfile || errmsg)
{
@ -1080,8 +1192,12 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
if (obj.found > 0)
{
status = add_symbols (file->handle, lto_file.symtab.nsyms,
lto_file.symtab.syms);
if (add_symbols_v2)
status = add_symbols_v2 (file->handle, lto_file.symtab.nsyms,
lto_file.symtab.syms);
else
status = add_symbols (file->handle, lto_file.symtab.nsyms,
lto_file.symtab.syms);
check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
num_claimed_files++;
@ -1242,6 +1358,9 @@ onload (struct ld_plugin_tv *tv)
case LDPT_REGISTER_CLAIM_FILE_HOOK:
register_claim_file = p->tv_u.tv_register_claim_file;
break;
case LDPT_ADD_SYMBOLS_V2:
add_symbols_v2 = p->tv_u.tv_add_symbols;
break;
case LDPT_ADD_SYMBOLS:
add_symbols = p->tv_u.tv_add_symbols;
break;