From 73ce4d1ed68a2f4e36c27be604ce35c242048f9d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 23 Jul 2010 05:33:51 +0000 Subject: re PR lto/44992 (ld -r breaks LTO) gcc: 2010-07-10 Andi Kleen 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 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 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. From-SVN: r162443 --- lto-plugin/ChangeLog | 17 +++++++ lto-plugin/lto-plugin.c | 128 +++++++++++++++++++++++++----------------------- 2 files changed, 83 insertions(+), 62 deletions(-) (limited to 'lto-plugin') diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index 04a091b..a8f7461 100644 --- a/lto-plugin/ChangeLog +++ b/lto-plugin/ChangeLog @@ -1,3 +1,20 @@ +2010-07-10 Andi Kleen + + 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 * 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 c82f50d..314759b 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 (<o_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, <o_file.symtab)) goto err; - symtab = get_symtab (elf); - if (!symtab) - goto err; - - translate (symtab, <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"); -- cgit v1.1