1cd0b7167e
ChangeLog: 2010-10-07 Dave Korn <dave.korn.cygwin@gmail.com> * configure.ac (build_lto_plugin): New shell variable. (--enable-lto): Turn on by default for all non-ELF platforms that have had LTO support added so far. Set build_lto_plugin appropriately for both ELF and non-ELF. (configdirs): Add lto-plugin or not based on build_lto_plugin. * configure: Regenerate. gcc/ChangeLog: 2010-10-07 Dave Korn <dave.korn.cygwin@gmail.com> * config.host (host_lto_plugin_soname): New shell variable. * configure.ac (LTOPLUGINSONAME): Add an AC_DEFINE for the above. * config.in: Regenerate. * configure: Regenerate. * gcc.c (main): Use LTOPLUGINSONAME instead of hard-coding name of LTO plugin shared library. lto-plugin/ChangeLog: 2010-10-07 Dave Korn <dave.korn.cygwin@gmail.com> * configure.ac: Source config.gcc to determine lto_binary_reader. (LTO_FORMAT): New AC_SUBST variable inferred from lto_binary_reader. * Makefile.am (LTO_FORMAT): Import. (liblto_plugin_la_SOURCES): Add object format dependent module defined by LTO_FORMAT. (liblto_plugin_la_LIBADD): Allow for both PIC and non-PIC libiberty, and work around libtool warning. * configure: Regenerate. * Makefile.in: Likewise. * lto-plugin.c (struct sym_aux): Move to new lto-plugin.h. (struct sym_aux): Likewise. (struct plugin_symtab): Likewise. (struct plugin_file_info): Likewise. (LTO_SECTION_PREFIX): Likewise. (add_symbols): Make non-static. (claimed_files): Likewise. (num_claimed_files): Likewise. (check): Likewise. (parse_table_entry): Likewise. (translate): Likewise. (resolve_conflicts): Likewise. (process_symtab): Move to new lto-plugin-elf.c object format dependent source file. (claim_file_handler): Likewise, and make non-static. (onload): Call new onload_format_checks function. * lto-plugin.h: New file. (LTO_SECTION_PREFIX): Move here. (struct sym_aux): Likewise. (struct plugin_symtab): Likewise. (struct plugin_file_info): Likewise. (claim_file_handler): Add new function prototype. (onload_format_checks): Likewise. (check): Declare extern. (translate): Likewise. (parse_table_entry): Likewise. (resolve_conflicts): Likewise. (add_symbols): Likewise. (claimed_files): Likewise. (num_claimed_files): Likewise. * lto-plugin-elf.c (process_symtab): Move here. (claim_file_handler): Likewise, and make non-static. (onload_format_checks): New function factored out from onload. * lto-plugin-coff.c (claim_file_handler): New function stub. (onload_format_checks): Likewise. From-SVN: r165133
158 lines
4.3 KiB
C
158 lines
4.3 KiB
C
/* LTO plugin for gold.
|
|
Copyright (C) 2009, 2010 Free Software Foundation, Inc.
|
|
Contributed by Rafael Avila de Espindola (espindola@google.com).
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <libiberty.h>
|
|
#include <stdlib.h>
|
|
#include <inttypes.h>
|
|
|
|
/* The presence of gelf.h is checked by the toplevel configure script. */
|
|
#include <gelf.h>
|
|
|
|
/* Common definitions that the object format dependent code needs. */
|
|
#include "lto-plugin.h"
|
|
|
|
/* Process all lto symtabs of file ELF. */
|
|
|
|
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 0;
|
|
assert (t == &header);
|
|
|
|
while ((section = elf_nextscn(elf, section)) != 0)
|
|
{
|
|
GElf_Shdr shdr;
|
|
GElf_Shdr *tshdr = gelf_getshdr (section, &shdr);
|
|
Elf_Data *symtab;
|
|
const char *t;
|
|
assert (tshdr == &shdr);
|
|
t = elf_strptr (elf, header.e_shstrndx, shdr.sh_name);
|
|
assert (t != NULL);
|
|
if (strncmp (t, LTO_SECTION_PREFIX, strlen (LTO_SECTION_PREFIX)) == 0)
|
|
{
|
|
char *s = strrchr (t, '.');
|
|
if (s)
|
|
sscanf (s, ".%x", &out->id);
|
|
symtab = elf_getdata (section, NULL);
|
|
translate (symtab->d_buf, symtab->d_buf + symtab->d_size, out);
|
|
found++;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
/* Callback used by gold to check if the plugin will claim FILE. Writes
|
|
the result in CLAIMED. */
|
|
|
|
enum ld_plugin_status
|
|
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;
|
|
int n;
|
|
|
|
memset (<o_file, 0, sizeof (struct plugin_file_info));
|
|
|
|
if (file->offset != 0)
|
|
{
|
|
char *objname;
|
|
Elf *archive;
|
|
off_t offset;
|
|
/* We pass the offset of the actual file, not the archive header. */
|
|
int t = asprintf (&objname, "%s@0x%" PRIx64, file->name,
|
|
(int64_t) file->offset);
|
|
check (t >= 0, LDPL_FATAL, "asprintf failed");
|
|
lto_file.name = objname;
|
|
|
|
archive = elf_begin (file->fd, ELF_C_READ, NULL);
|
|
check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
|
|
"Not an archive and offset not 0");
|
|
|
|
/* elf_rand expects the offset to point to the ar header, not the
|
|
object itself. Subtract the size of the ar header (60 bytes).
|
|
We don't uses sizeof (struct ar_hd) to avoid including ar.h */
|
|
|
|
offset = file->offset - 60;
|
|
check (offset == elf_rand (archive, offset), LDPL_FATAL,
|
|
"could not seek in archive");
|
|
elf = elf_begin (file->fd, ELF_C_READ, archive);
|
|
check (elf != NULL, LDPL_FATAL, "could not find archive member");
|
|
elf_end (archive);
|
|
}
|
|
else
|
|
{
|
|
lto_file.name = xstrdup (file->name);
|
|
elf = elf_begin (file->fd, ELF_C_READ, NULL);
|
|
}
|
|
lto_file.handle = file->handle;
|
|
|
|
*claimed = 0;
|
|
|
|
if (!elf)
|
|
goto err;
|
|
|
|
n = process_symtab (elf, <o_file.symtab);
|
|
if (n == 0)
|
|
goto err;
|
|
|
|
if (n > 1)
|
|
resolve_conflicts (<o_file.symtab, <o_file.conflicts);
|
|
|
|
status = add_symbols (file->handle, lto_file.symtab.nsyms,
|
|
lto_file.symtab.syms);
|
|
check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
|
|
|
|
*claimed = 1;
|
|
num_claimed_files++;
|
|
claimed_files =
|
|
xrealloc (claimed_files,
|
|
num_claimed_files * sizeof (struct plugin_file_info));
|
|
claimed_files[num_claimed_files - 1] = lto_file;
|
|
|
|
goto cleanup;
|
|
|
|
err:
|
|
free (lto_file.name);
|
|
|
|
cleanup:
|
|
if (elf)
|
|
elf_end (elf);
|
|
|
|
return LDPS_OK;
|
|
}
|
|
|
|
/* Method called first thing at onload time to perform sanity checks. */
|
|
|
|
enum ld_plugin_status
|
|
onload_format_checks (struct ld_plugin_tv *tv)
|
|
{
|
|
unsigned version = elf_version (EV_CURRENT);
|
|
check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
|
|
return LDPS_OK;
|
|
}
|
|
|