[gcc(refs/users/marxin/heads/lto-plugin-symbol-type-v5)] API extension for binutils (type of symbols).
Martin Liska
marxin@gcc.gnu.org
Wed Mar 11 14:12:17 GMT 2020
https://gcc.gnu.org/g:8a2e73edb53f26a1b6a543e2e2027b2661a48f94
commit 8a2e73edb53f26a1b6a543e2e2027b2661a48f94
Author: Martin Liska <mliska@suse.cz>
Date: Fri Mar 6 18:09:35 2020 +0100
API extension for binutils (type of symbols).
Diff:
---
gcc/lto-streamer-out.c | 12 ++++++
include/lto-symtab.h | 12 ++++++
include/plugin-api.h | 30 ++++++++++++++-
lto-plugin/lto-plugin.c | 99 ++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 142 insertions(+), 11 deletions(-)
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index cea5e71cffb..b212be35b3d 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -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);
@@ -2773,6 +2774,17 @@ write_symbol (struct streamer_tree_cache_d *cache,
lto_write_data (&c, 1);
c = (unsigned char) visibility;
lto_write_data (&c, 1);
+ c = ((unsigned char) TREE_CODE (t) == VAR_DECL
+ ? GCCST_VARIABLE : GCCST_FUNCTION);
+ lto_write_data (&c, 1);
+ unsigned char section_flags = 0;
+ if (TREE_CODE (t) == VAR_DECL)
+ {
+ section *s = get_variable_section (t, false);
+ if (s->common.flags & SECTION_BSS)
+ section_flags |= GCCSSS_BSS;
+ }
+ lto_write_data (§ion_flags, 1);
lto_write_data (&size, 8);
lto_write_data (&slot_num, 4);
}
diff --git a/include/lto-symtab.h b/include/lto-symtab.h
index 0ce0de10121..47f0ff27df8 100644
--- a/include/lto-symtab.h
+++ b/include/lto-symtab.h
@@ -38,4 +38,16 @@ enum gcc_plugin_symbol_visibility
GCCPV_HIDDEN
};
+enum gcc_plugin_symbol_type
+{
+ GCCST_UNKNOWN,
+ GCCST_FUNCTION,
+ GCCST_VARIABLE,
+};
+
+enum gcc_plugin_symbol_section_flags
+{
+ GCCSSS_BSS = 1
+};
+
#endif /* GCC_LTO_SYMTAB_H */
diff --git a/include/plugin-api.h b/include/plugin-api.h
index 09e1202df07..804684449cf 100644
--- a/include/plugin-api.h
+++ b/include/plugin-api.h
@@ -87,7 +87,17 @@ struct ld_plugin_symbol
{
char *name;
char *version;
- int def;
+#ifdef __BIG_ENDIAN__
+ char unused;
+ char section_flags;
+ char symbol_type;
+ char def;
+#else
+ char def;
+ char symbol_type;
+ char section_flags;
+ char unused;
+#endif
int visibility;
uint64_t size;
char *comdat_key;
@@ -123,6 +133,20 @@ enum ld_plugin_symbol_visibility
LDPV_HIDDEN
};
+/* The type of the symbol. */
+
+enum ld_plugin_symbol_type
+{
+ LDST_UNKNOWN,
+ LDST_FUNCTION,
+ LDST_VARIABLE,
+};
+
+enum ld_plugin_symbol_section_flags
+{
+ LDSSS_BSS = 1
+};
+
/* How a symbol is resolved. */
enum ld_plugin_symbol_resolution
@@ -431,7 +455,9 @@ enum ld_plugin_tag
LDPT_GET_INPUT_SECTION_ALIGNMENT = 29,
LDPT_GET_INPUT_SECTION_SIZE = 30,
LDPT_REGISTER_NEW_INPUT_HOOK = 31,
- LDPT_GET_WRAP_SYMBOLS = 32
+ LDPT_GET_WRAP_SYMBOLS = 32,
+ LDPT_ADD_SYMBOLS_V2 = 33,
+ LDPT_GET_SYMBOLS_V4 = 34,
};
/* The plugin transfer vector. */
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index c307fc871bf..bce9f183049 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -90,6 +90,8 @@ along with this program; see the file COPYING3. If not see
#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
#define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_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)
@@ -154,12 +156,12 @@ enum symbol_style
static char *arguments_file_name;
static ld_plugin_register_claim_file register_claim_file;
static ld_plugin_register_all_symbols_read register_all_symbols_read;
-static ld_plugin_get_symbols get_symbols, get_symbols_v2;
+static ld_plugin_get_symbols get_symbols, get_symbols_v2, get_symbols_v4;
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;
@@ -221,6 +223,20 @@ check_1 (int gate, enum ld_plugin_level level, const char *text)
}
}
+/* Structure that represents LTO ELF section with information
+ about the format. */
+
+struct lto_section
+ {
+ int16_t major_version;
+ int16_t minor_version;
+ unsigned char slim_object: 1;
+ unsigned char compression: 4;
+ int32_t reserved0: 27;
+};
+
+struct lto_section lto_header;
+
/* This little wrapper allows check to be called with a non-integer
first argument, such as a pointer that must be non-NULL. We can't
use c99 bool type to coerce it into range, so we explicitly test. */
@@ -252,6 +268,13 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
LDPV_HIDDEN
};
+ enum ld_plugin_symbol_type symbol_types[] =
+ {
+ LDST_UNKNOWN,
+ LDST_FUNCTION,
+ LDST_VARIABLE,
+ };
+
switch (sym_style)
{
case ss_win32:
@@ -296,6 +319,19 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
entry->visibility = translate_visibility[t];
p++;
+ /* Symbol type was added in GCC 10.1 (LTO version 9.0). */
+ if (lto_header.major_version >= 9)
+ {
+ t = *p;
+ check (t <= 3, LDPL_FATAL, "invalid symbol type found");
+ entry->symbol_type = symbol_types[t];
+ p++;
+ entry->section_flags = *p;
+ p++;
+ }
+
+ entry->unused = 0;
+
memcpy (&entry->size, p, sizeof (uint64_t));
p += 8;
@@ -431,7 +467,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;
@@ -473,6 +509,19 @@ free_symtab (struct plugin_symtab *symtab)
symtab->aux = NULL;
}
+/* Clear new flags symbol_type and section_flags
+ from symbol table entries. */
+
+static void
+clear_new_symtab_flags (struct plugin_symtab *out)
+{
+ for (unsigned i = 0; i < out->nsyms; i++)
+ {
+ out->syms[i].symbol_type = 0;
+ out->syms[i].section_flags = 0;
+ }
+}
+
/* Writes the relocations to disk. */
static void
@@ -495,10 +544,16 @@ write_resolution (void)
/* Version 2 of API supports IRONLY_EXP resolution that is
accepted by GCC-4.7 and newer. */
- if (get_symbols_v2)
- get_symbols_v2 (info->handle, symtab->nsyms, syms);
+ if (get_symbols_v4)
+ get_symbols_v4 (info->handle, symtab->nsyms, syms);
else
- get_symbols (info->handle, symtab->nsyms, syms);
+ {
+ clear_new_symtab_flags (symtab);
+ if (get_symbols_v2)
+ get_symbols_v2 (info->handle, symtab->nsyms, syms);
+ else
+ get_symbols (info->handle, symtab->nsyms, syms);
+ }
finish_conflict_resolution (symtab, &info->conflicts);
@@ -951,7 +1006,20 @@ process_symtab (void *data, const char *name, off_t offset, off_t length)
{
struct plugin_objfile *obj = (struct plugin_objfile *)data;
char *s;
- char *secdatastart, *secdata;
+ char *secdatastart = NULL, *secdata;
+
+ if (strncmp (name, LTO_LTO_PREFIX, LTO_LTO_PREFIX_LEN) == 0)
+ {
+ if (offset != lseek (obj->file->fd, offset, SEEK_SET))
+ goto err;
+
+ ssize_t got = read (obj->file->fd, <o_header,
+ sizeof (struct lto_section));
+ if (got != sizeof (struct lto_section))
+ goto err;
+
+ return 1;
+ }
if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0)
return 1;
@@ -1080,8 +1148,15 @@ 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
+ {
+ clear_new_symtab_flags (<o_file.symtab);
+ 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,12 +1317,18 @@ 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;
case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
register_all_symbols_read = p->tv_u.tv_register_all_symbols_read;
break;
+ case LDPT_GET_SYMBOLS_V4:
+ get_symbols_v4 = p->tv_u.tv_get_symbols;
+ break;
case LDPT_GET_SYMBOLS_V2:
get_symbols_v2 = p->tv_u.tv_get_symbols;
break;
More information about the Gcc-cvs
mailing list