summaryrefslogtreecommitdiff
path: root/lto-plugin
diff options
context:
space:
mode:
authorak <ak@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-23 05:33:51 +0000
committerak <ak@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-23 05:33:51 +0000
commitf18bad3324ef4d6e39219a4ec94b0a59cbcbb010 (patch)
tree50e055bbea281c232261eb1e07af42e60ab3a165 /lto-plugin
parentaa5c56571d44e75a4ac0d2824131e011cd38a7c2 (diff)
gcc:
2010-07-10 Andi Kleen <ak@linux.intel.com> PR lto/44992 * lto-opts.c (lto_write_options): Add NULL file_data argument to lto_get_section_name. * lto-section-out.c (lto_destroy_simple_output_block): Likewise. * lto-streamer-out.c (produce_asm): Likewise. (copy_function): Likewise. (produce_symtab): Likewise. (produce_asm_for_decls): Likewise. * lto-streamer.c (lto_get_section_name): Add file_data argument. Rewrite to add random postfix to LTO sections. * lto-streamer.h (lto_file_decl_data): Add next, id, resolutions. (lto_get_section_name): Add file_data argument to prototype. lto: 2010-07-10 Andi Kleen <ak@linux.intel.com> PR lto/44992 * lto.c: Include splay-tree.h (lto_resolution_read): Change to walk file_ids tree and parse extra file_id in resolution file. (lto_section_with_id): Add. (create_subid_section_table): Add. (lwstate): Add. (lto_create_files_from_ids): Add. (lto_file_read): Change to handle sub file ids and create list of file_datas. Add output argument for count. (get_section_data): Pass file_data to lto_get_section_name. (lto_flatten_file): Add. (read_cgraph_and_symbols): Handle linked lists of file_datas. lto-plugin: 2010-07-10 Andi Kleen <ak@linux.intel.com> PR lto/44992 * lto-plugin.c (sym_aux): Add. (plugin_symtab): Remove slots. Add aux and id. (parse_table_entry): Change to use aux instead of slots. (LTO_SECTION_PREFIX): Add. (translate): Improve buffer allocation. Change to append symbols to existing out buffer. (get_section): Remove. (process_symtab): Add. (free_2): Free symtab->aux. (write_resolution): Handle aux instead of slots. Print sub id to resolution file. (claim_file_handler): Clear lto_file. Replace get_symtab/translate calls with call to process_symtab. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162443 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'lto-plugin')
-rw-r--r--lto-plugin/ChangeLog17
-rw-r--r--lto-plugin/lto-plugin.c128
2 files changed, 83 insertions, 62 deletions
diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog
index 04a091b1021d..a8f7461298c2 100644
--- a/lto-plugin/ChangeLog
+++ b/lto-plugin/ChangeLog
@@ -1,3 +1,20 @@
+2010-07-10 Andi Kleen <ak@linux.intel.com>
+
+ PR lto/44992
+ * lto-plugin.c (sym_aux): Add.
+ (plugin_symtab): Remove slots. Add aux and id.
+ (parse_table_entry): Change to use aux instead of slots.
+ (LTO_SECTION_PREFIX): Add.
+ (translate): Improve buffer allocation. Change to append
+ symbols to existing out buffer.
+ (get_section): Remove.
+ (process_symtab): Add.
+ (free_2): Free symtab->aux.
+ (write_resolution): Handle aux instead of slots.
+ Print sub id to resolution file.
+ (claim_file_handler): Clear lto_file. Replace get_symtab/translate
+ calls with call to process_symtab.
+
2010-07-22 Richard Guenther <rguenther@suse.de>
* Makefile.am: New copy_lto_plugin rule to install the plugin
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index c82f50d97f98..314759bc4621 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -55,11 +55,18 @@ along with this program; see the file COPYING3. If not see
must keep SYMS until all_symbols_read is called to give the linker time to
copy the symbol information. */
+struct sym_aux
+{
+ uint32_t slot;
+ unsigned id;
+};
+
struct plugin_symtab
{
int nsyms;
- uint32_t *slots;
+ struct sym_aux *aux;
struct ld_plugin_symbol *syms;
+ unsigned id;
};
/* All that we have to remember about a file. */
@@ -120,7 +127,8 @@ check (bool gate, enum ld_plugin_level level, const char *text)
Returns the address of the next entry. */
static char *
-parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
+parse_table_entry (char *p, struct ld_plugin_symbol *entry,
+ struct sym_aux *aux)
{
unsigned char t;
enum ld_plugin_symbol_kind translate_kind[] =
@@ -170,7 +178,7 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
entry->size = *(uint64_t *) p;
p += 8;
- *slot = *(uint32_t *) p;
+ aux->slot = *(uint32_t *) p;
p += 4;
entry->resolution = LDPR_UNKNOWN;
@@ -178,16 +186,51 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry, uint32_t *slot)
return p;
}
-/* Return the section in ELF that is named NAME. */
+#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
+
+/* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
+
+static void
+translate (Elf_Data *symtab, struct plugin_symtab *out)
+{
+ struct sym_aux *aux;
+ char *data = symtab->d_buf;
+ char *end = data + symtab->d_size;
+ struct ld_plugin_symbol *syms = NULL;
+ int n, len;
+
+ /* This overestimates the output buffer sizes, but at least
+ the algorithm is O(1) now. */
+
+ len = (end - data)/8 + out->nsyms + 1;
+ syms = xrealloc (out->syms, len * sizeof (struct ld_plugin_symbol));
+ aux = xrealloc (out->aux, len * sizeof (struct sym_aux));
+
+ for (n = out->nsyms; data < end; n++)
+ {
+ aux[n].id = out->id;
+ data = parse_table_entry (data, &syms[n], &aux[n]);
+ }
+
+ fprintf (stderr, "n = %d len = %d end-data=%lu\n", n, len, end-data);
+ assert(n < len);
+
+ out->nsyms = n;
+ out->syms = syms;
+ out->aux = aux;
+}
+
+/* Process all lto symtabs of file ELF. */
-static Elf_Scn *
-get_section (Elf *elf, const char *name)
+static int
+process_symtab (Elf *elf, struct plugin_symtab *out)
{
+ int found = 0;
Elf_Scn *section = 0;
GElf_Ehdr header;
GElf_Ehdr *t = gelf_getehdr (elf, &header);
if (t == NULL)
- return NULL;
+ return 0;
assert (t == &header);
while ((section = elf_nextscn(elf, section)) != 0)
@@ -198,51 +241,16 @@ get_section (Elf *elf, const char *name)
assert (tshdr == &shdr);
t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
assert (t != NULL);
- if (strcmp (t, name) == 0)
- return section;
- }
- return NULL;
-}
-
-/* Returns the IL symbol table of file ELF. */
-
-static Elf_Data *
-get_symtab (Elf *elf)
-{
- Elf_Data *data = 0;
- Elf_Scn *section = get_section (elf, ".gnu.lto_.symtab");
- if (!section)
- return NULL;
-
- data = elf_getdata (section, data);
- assert (data);
- return data;
-}
-
-/* Translate the IL symbol table SYMTAB. Write the slots and symbols in OUT. */
-
-static void
-translate (Elf_Data *symtab, struct plugin_symtab *out)
-{
- uint32_t *slots = NULL;
- char *data = symtab->d_buf;
- char *end = data + symtab->d_size;
- struct ld_plugin_symbol *syms = NULL;
- int n = 0;
-
- while (data < end)
- {
- n++;
- syms = xrealloc (syms, n * sizeof (struct ld_plugin_symbol));
- check (syms, LDPL_FATAL, "could not allocate memory");
- slots = xrealloc (slots, n * sizeof (uint32_t));
- check (slots, LDPL_FATAL, "could not allocate memory");
- data = parse_table_entry (data, &syms[n - 1], &slots[n - 1]);
+ if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0)
+ {
+ char *s = strrchr (t, '.');
+ if (s)
+ sscanf (s, ".%x", &out->id);
+ translate (elf_getdata (section, NULL), out);
+ found = 1;
+ }
}
-
- out->nsyms = n;
- out->syms = syms;
- out->slots = slots;
+ return found;
}
/* Free all memory that is no longer needed after writing the symbol
@@ -279,7 +287,7 @@ free_2 (void)
{
struct plugin_file_info *info = &claimed_files[i];
struct plugin_symtab *symtab = &info->symtab;
- free (symtab->slots);
+ free (symtab->aux);
free (info->name);
}
@@ -323,9 +331,10 @@ write_resolution (void)
for (j = 0; j < info->symtab.nsyms; j++)
{
- uint32_t slot = symtab->slots[j];
+ uint32_t slot = symtab->aux[j].slot;
unsigned int resolution = syms[j].resolution;
- fprintf (f, "%d %s %s\n", slot, lto_resolution_str[resolution], syms[j].name);
+ fprintf (f, "%d %x %s %s\n", slot, symtab->aux[j].id,
+ lto_resolution_str[resolution], syms[j].name);
}
}
fclose (f);
@@ -551,7 +560,8 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
enum ld_plugin_status status;
Elf *elf;
struct plugin_file_info lto_file;
- Elf_Data *symtab;
+
+ memset (&lto_file, 0, sizeof (struct plugin_file_info));
if (file->offset != 0)
{
@@ -588,15 +598,9 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
*claimed = 0;
- if (!elf)
+ if (!elf || !process_symtab (elf, &lto_file.symtab))
goto err;
- symtab = get_symtab (elf);
- if (!symtab)
- goto err;
-
- translate (symtab, &lto_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");