summaryrefslogtreecommitdiff
path: root/lto-plugin
diff options
context:
space:
mode:
authorDave Korn <dave.korn.cygwin@gmail.com>2010-10-07 20:28:59 +0000
committerDave Korn <davek@gcc.gnu.org>2010-10-07 20:28:59 +0000
commit1cd0b7167ed9b43b189c39549d8165a020aee9b6 (patch)
tree946186568fee00058aace74937894e09bce8b4b8 /lto-plugin
parent6ba74c2d192958de47dc1d7b36125495441a4d50 (diff)
configure.ac (build_lto_plugin): New shell variable.
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
Diffstat (limited to 'lto-plugin')
-rw-r--r--lto-plugin/ChangeLog47
-rw-r--r--lto-plugin/Makefile.am10
-rw-r--r--lto-plugin/Makefile.in24
-rwxr-xr-xlto-plugin/configure13
-rw-r--r--lto-plugin/configure.ac8
-rw-r--r--lto-plugin/lto-plugin-coff.c38
-rw-r--r--lto-plugin/lto-plugin-elf.c157
-rw-r--r--lto-plugin/lto-plugin.c185
-rw-r--r--lto-plugin/lto-plugin.h84
9 files changed, 391 insertions, 175 deletions
diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog
index 6f6c4e8908c..9caad6aab54 100644
--- a/lto-plugin/ChangeLog
+++ b/lto-plugin/ChangeLog
@@ -1,3 +1,50 @@
+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.
+
2010-08-05 Andi Kleen <ak@linux.intel.com>
* lto-plugin.c: Include <hashtab.h>
diff --git a/lto-plugin/Makefile.am b/lto-plugin/Makefile.am
index da74e1c778c..52bf6719daa 100644
--- a/lto-plugin/Makefile.am
+++ b/lto-plugin/Makefile.am
@@ -11,13 +11,19 @@ libexecsubdir := $(libexecdir)/gcc/$(target_noncanonical)/$(gcc_version)
LIBELFLIBS = @LIBELFLIBS@
LIBELFINC = @LIBELFINC@
+# Which object format to parse.
+LTO_FORMAT = @LTO_FORMAT@
+
AM_CPPFLAGS = -I$(top_srcdir)/../include $(LIBELFINC)
AM_CFLAGS = -Wall -Werror
libexecsub_LTLIBRARIES = liblto_plugin.la
-liblto_plugin_la_SOURCES = lto-plugin.c
-liblto_plugin_la_LIBADD = $(LIBELFLIBS) ../libiberty/pic/libiberty.a
+liblto_plugin_la_SOURCES = lto-plugin.c lto-plugin-$(LTO_FORMAT).c
+liblto_plugin_la_LIBADD = $(LIBELFLIBS) \
+ $(if $(wildcard ../libiberty/pic/libiberty.a),../libiberty/pic/libiberty.a,)
+liblto_plugin_la_LDFLAGS = -no-undefined -bindir $(libexecsubdir) \
+ $(if $(wildcard ../libiberty/pic/libiberty.a),,-Wc,../libiberty/libiberty.a)
all: copy_lto_plugin
diff --git a/lto-plugin/Makefile.in b/lto-plugin/Makefile.in
index 2f58f9bbe36..c3f5260ed7d 100644
--- a/lto-plugin/Makefile.in
+++ b/lto-plugin/Makefile.in
@@ -79,10 +79,14 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(libexecsubdir)"
LTLIBRARIES = $(libexecsub_LTLIBRARIES)
am__DEPENDENCIES_1 =
-liblto_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
- ../libiberty/pic/libiberty.a
-am_liblto_plugin_la_OBJECTS = lto-plugin.lo
+liblto_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(if $(wildcard \
+ ../libiberty/pic/libiberty.a),../libiberty/pic/libiberty.a,)
+am_liblto_plugin_la_OBJECTS = lto-plugin.lo \
+ lto-plugin-$(LTO_FORMAT).lo
liblto_plugin_la_OBJECTS = $(am_liblto_plugin_la_OBJECTS)
+liblto_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(liblto_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp =
am__depfiles_maybe =
@@ -139,6 +143,9 @@ LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+
+# Which object format to parse.
+LTO_FORMAT = @LTO_FORMAT@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
@@ -225,8 +232,13 @@ libexecsubdir := $(libexecdir)/gcc/$(target_noncanonical)/$(gcc_version)
AM_CPPFLAGS = -I$(top_srcdir)/../include $(LIBELFINC)
AM_CFLAGS = -Wall -Werror
libexecsub_LTLIBRARIES = liblto_plugin.la
-liblto_plugin_la_SOURCES = lto-plugin.c
-liblto_plugin_la_LIBADD = $(LIBELFLIBS) ../libiberty/pic/libiberty.a
+liblto_plugin_la_SOURCES = lto-plugin.c lto-plugin-$(LTO_FORMAT).c
+liblto_plugin_la_LIBADD = $(LIBELFLIBS) \
+ $(if $(wildcard ../libiberty/pic/libiberty.a),../libiberty/pic/libiberty.a,)
+
+liblto_plugin_la_LDFLAGS = -no-undefined -bindir $(libexecsubdir) \
+ $(if $(wildcard ../libiberty/pic/libiberty.a),,-Wc,../libiberty/libiberty.a)
+
all: all-am
.SUFFIXES:
@@ -297,7 +309,7 @@ clean-libexecsubLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
liblto_plugin.la: $(liblto_plugin_la_OBJECTS) $(liblto_plugin_la_DEPENDENCIES)
- $(LINK) -rpath $(libexecsubdir) $(liblto_plugin_la_OBJECTS) $(liblto_plugin_la_LIBADD) $(LIBS)
+ $(liblto_plugin_la_LINK) -rpath $(libexecsubdir) $(liblto_plugin_la_OBJECTS) $(liblto_plugin_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
diff --git a/lto-plugin/configure b/lto-plugin/configure
index 234ff90a055..1e4041bc7e7 100755
--- a/lto-plugin/configure
+++ b/lto-plugin/configure
@@ -601,6 +601,7 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+LTO_FORMAT
target_noncanonical
CPP
OTOOL64
@@ -10397,7 +10398,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10400 "configure"
+#line 10401 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10503,7 +10504,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10506 "configure"
+#line 10507 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10741,6 +10742,14 @@ CC="$lt_save_CC"
+. ${srcdir}/../gcc/config.gcc
+case ${lto_binary_reader} in
+ *coff*) LTO_FORMAT=coff ;;
+ *elf*) LTO_FORMAT=elf ;;
+ *) as_fn_error "LTO plugin is not supported on this target." "$LINENO" 5 ;;
+esac
+
+
ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
case $ac_cv_c_uint64_t in #(
no|yes) ;; #(
diff --git a/lto-plugin/configure.ac b/lto-plugin/configure.ac
index e89a982b971..c43b26434e8 100644
--- a/lto-plugin/configure.ac
+++ b/lto-plugin/configure.ac
@@ -9,6 +9,14 @@ AC_ARG_VAR(LIBELFLIBS,[How to link libelf])
AC_ARG_VAR(LIBELFINC,[How to find libelf include files])
AM_PROG_LIBTOOL
AC_SUBST(target_noncanonical)
+. ${srcdir}/../gcc/config.gcc
+case ${lto_binary_reader} in
+ *coff*) LTO_FORMAT=coff ;;
+ *elf*) LTO_FORMAT=elf ;;
+ *) AC_MSG_ERROR([LTO plugin is not supported on this target.]) ;;
+esac
+
+AC_SUBST(LTO_FORMAT)
AC_TYPE_UINT64_T
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
diff --git a/lto-plugin/lto-plugin-coff.c b/lto-plugin/lto-plugin-coff.c
new file mode 100644
index 00000000000..acaff5979f2
--- /dev/null
+++ b/lto-plugin/lto-plugin-coff.c
@@ -0,0 +1,38 @@
+/* LTO plugin for gold.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+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/>. */
+
+/* Common definitions that the object format dependent code needs. */
+#include "lto-plugin.h"
+
+/* 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)
+{
+ /* To be implemented; for now, simply do nothing. */
+ 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)
+{
+ return LDPS_OK;
+}
+
diff --git a/lto-plugin/lto-plugin-elf.c b/lto-plugin/lto-plugin-elf.c
new file mode 100644
index 00000000000..afd79dac056
--- /dev/null
+++ b/lto-plugin/lto-plugin-elf.c
@@ -0,0 +1,157 @@
+/* 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 (&lto_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, &lto_file.symtab);
+ if (n == 0)
+ goto err;
+
+ if (n > 1)
+ resolve_conflicts (&lto_file.symtab, &lto_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;
+}
+
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index dc51b48bc5a..7e8443d021e 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -1,5 +1,5 @@
-/* LTO plugin for gold.
- Copyright (C) 2009 Free Software Foundation, Inc.
+/* LTO plugin for gold and/or GNU ld.
+ 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
@@ -45,46 +45,13 @@ along with this program; see the file COPYING3. If not see
#include <stdbool.h>
#include <libiberty.h>
#include <hashtab.h>
-
-/* The presence of gelf.h is checked by the toplevel configure script. */
-#include <gelf.h>
-
-#include "plugin-api.h"
#include "../gcc/lto/common.h"
-/* The part of the symbol table the plugin has to keep track of. Note that we
- 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;
- unsigned next_conflict;
-};
-
-struct plugin_symtab
-{
- int nsyms;
- struct sym_aux *aux;
- struct ld_plugin_symbol *syms;
- unsigned id;
-};
-
-/* All that we have to remember about a file. */
-
-struct plugin_file_info
-{
- char *name;
- void *handle;
- struct plugin_symtab symtab;
- struct plugin_symtab conflicts;
-};
-
+/* Common definitions for/from the object format dependent code. */
+#include "lto-plugin.h"
static char *arguments_file_name;
static ld_plugin_register_claim_file register_claim_file;
-static ld_plugin_add_symbols add_symbols;
static ld_plugin_register_all_symbols_read register_all_symbols_read;
static ld_plugin_get_symbols get_symbols;
static ld_plugin_register_cleanup register_cleanup;
@@ -92,8 +59,12 @@ static ld_plugin_add_input_file add_input_file;
static ld_plugin_add_input_library add_input_library;
static ld_plugin_message message;
-static struct plugin_file_info *claimed_files = NULL;
-static unsigned int num_claimed_files = 0;
+/* These are not static because the object format dependent
+ claim_file hooks in lto-plugin-{coff,elf}.c need them. */
+ld_plugin_add_symbols add_symbols;
+
+struct plugin_file_info *claimed_files = NULL;
+unsigned int num_claimed_files = 0;
static char **output_files = NULL;
static unsigned int num_output_files = 0;
@@ -108,7 +79,7 @@ static bool debug;
static bool nop;
static char *resolution_file = NULL;
-static void
+void
check (bool gate, enum ld_plugin_level level, const char *text)
{
if (gate)
@@ -129,7 +100,7 @@ check (bool gate, enum ld_plugin_level level, const char *text)
by P and the result is written in ENTRY. The slot number is stored in SLOT.
Returns the address of the next entry. */
-static char *
+char *
parse_table_entry (char *p, struct ld_plugin_symbol *entry,
struct sym_aux *aux)
{
@@ -191,16 +162,13 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
return p;
}
-#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
-
-/* Translate the IL symbol table SYMTAB. Append the slots and symbols to OUT. */
+/* Translate the IL symbol table located between DATA and END. Append the
+ slots and symbols to OUT. */
-static void
-translate (Elf_Data *symtab, struct plugin_symtab *out)
+void
+translate (char *data, char *end, 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;
@@ -224,39 +192,6 @@ translate (Elf_Data *symtab, struct plugin_symtab *out)
out->aux = aux;
}
-/* 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);
- 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);
- translate (elf_getdata (section, NULL), out);
- found++;
- }
- }
- return found;
-}
-
/* Free all memory that is no longer needed after writing the symbol
resolution. */
@@ -686,7 +621,7 @@ static int symbol_strength (struct ld_plugin_symbol *s)
XXX how to handle common? */
-static void
+void
resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
{
htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL);
@@ -754,87 +689,6 @@ resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
htab_delete (symtab);
}
-/* Callback used by gold to check if the plugin will claim FILE. Writes
- the result in CLAIMED. */
-
-static 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 (&lto_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, &lto_file.symtab);
- if (n == 0)
- goto err;
-
- if (n > 1)
- resolve_conflicts (&lto_file.symtab, &lto_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;
-}
-
/* Parse the plugin options. */
static void
@@ -873,8 +727,9 @@ onload (struct ld_plugin_tv *tv)
struct ld_plugin_tv *p;
enum ld_plugin_status status;
- unsigned version = elf_version (EV_CURRENT);
- check (version != EV_NONE, LDPL_FATAL, "invalid ELF version");
+ status = onload_format_checks (tv);
+ if (status != LDPS_OK)
+ return status;
p = tv;
while (p->tv_tag)
diff --git a/lto-plugin/lto-plugin.h b/lto-plugin/lto-plugin.h
new file mode 100644
index 00000000000..09eb85003a7
--- /dev/null
+++ b/lto-plugin/lto-plugin.h
@@ -0,0 +1,84 @@
+/* Common declarations for LTO plugin for gold and/or GNU ld.
+ 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 <stdbool.h>
+#include "plugin-api.h"
+
+/* LTO magic section name. */
+
+#define LTO_SECTION_PREFIX ".gnu.lto_.symtab"
+
+/* The part of the symbol table the plugin has to keep track of. Note that we
+ 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;
+ unsigned next_conflict;
+};
+
+struct plugin_symtab
+{
+ int nsyms;
+ struct sym_aux *aux;
+ struct ld_plugin_symbol *syms;
+ unsigned id;
+};
+
+/* All that we have to remember about a file. */
+
+struct plugin_file_info
+{
+ char *name;
+ void *handle;
+ struct plugin_symtab symtab;
+ struct plugin_symtab conflicts;
+};
+
+/* These are the methods supplied by one of the object format
+ dependent files lto-plugin-elf.c or lto-plugin-coff.c */
+
+extern enum ld_plugin_status claim_file_handler
+ (const struct ld_plugin_input_file *file, int *claimed);
+
+extern enum ld_plugin_status onload_format_checks (struct ld_plugin_tv *tv);
+
+/* These methods are made available to the object format
+ dependent files. */
+
+extern void check (bool gate, enum ld_plugin_level level, const char *text);
+
+extern void translate (char *data, char *end, struct plugin_symtab *out);
+
+extern char *parse_table_entry (char *p, struct ld_plugin_symbol *entry,
+ struct sym_aux *aux);
+
+extern void resolve_conflicts (struct plugin_symtab *t,
+ struct plugin_symtab *conflicts);
+
+/* And this callback function is exposed. */
+
+extern ld_plugin_add_symbols add_symbols;
+
+/* Along with these two variables. */
+
+extern struct plugin_file_info *claimed_files;
+extern unsigned int num_claimed_files;
+