diff options
author | ak <ak@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-23 05:33:51 +0000 |
---|---|---|
committer | ak <ak@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-23 05:33:51 +0000 |
commit | f18bad3324ef4d6e39219a4ec94b0a59cbcbb010 (patch) | |
tree | 50e055bbea281c232261eb1e07af42e60ab3a165 /lto-plugin | |
parent | aa5c56571d44e75a4ac0d2824131e011cd38a7c2 (diff) | |
download | gcc-f18bad3324ef4d6e39219a4ec94b0a59cbcbb010.tar.gz |
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/ChangeLog | 17 | ||||
-rw-r--r-- | lto-plugin/lto-plugin.c | 128 |
2 files changed, 83 insertions, 62 deletions
diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index 04a091b1021..a8f7461298c 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 c82f50d97f9..314759bc462 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"); |