Index: configure.ac =================================================================== --- configure.ac (revision 166214) +++ configure.ac (working copy) @@ -1654,175 +1654,8 @@ AC_SUBST(clooginc) AC_ARG_ENABLE(lto, [ --enable-lto enable link time optimization support], enable_lto=$enableval, -enable_lto=yes; default_enable_lto=yes) +enable_lto=yes) - -ACX_ELF_TARGET_IFELSE([if test x"$enable_lto" = x"yes" ; then - # Make sure that libelf.h and gelf.h are available. - AC_ARG_WITH(libelf, [ --with-libelf=PATH Specify prefix directory for the installed libelf package - Equivalent to --with-libelf-include=PATH/include - plus --with-libelf-lib=PATH/lib]) - - AC_ARG_WITH(libelf_include, [ --with-libelf-include=PATH Specify directory for installed libelf include files]) - - AC_ARG_WITH(libelf_lib, [ --with-libelf-lib=PATH Specify the directory for the installed libelf library]) - - saved_CFLAGS="$CFLAGS" - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - - case $with_libelf in - "") - libelflibs="-lelf" - libelfinc="-I/usr/include/libelf" - ;; - *) - libelflibs="-L$with_libelf/lib -lelf" - libelfinc="-I$with_libelf/include -I$with_libelf/include/libelf" - LIBS="$libelflibs $LIBS" - ;; - esac - - if test "x$with_libelf_include" != x; then - libelfinc="-I$with_libelf_include" - fi - - if test "x$with_libelf_lib" != x; then - libelflibs="-L$with_libelf_lib -lelf" - LIBS="$libelflibs $LIBS" - fi - - if test "x$with_libelf$with_libelf_include$with_libelf_lib" = x \ - && test -d ${srcdir}/libelf; then - libelflibs='-L$$r/$(HOST_SUBDIR)/libelf/lib -lelf ' - libelfinc='-D__LIBELF_INTERNAL__ -I$$r/$(HOST_SUBDIR)/libelf/lib -I$$s/libelf/lib' - LIBS="$libelflibs $LIBS" - - else - - CFLAGS="$CFLAGS $libelfinc" - CPPFLAGS="$CPPFLAGS $libelfinc" - LIBS="$LIBS $libelflibs" - - AC_CHECK_HEADERS(libelf.h, [have_libelf_h=yes]) - AC_CHECK_HEADERS(gelf.h, [have_gelf_h=yes]) - - AC_CHECK_HEADERS(libelf/libelf.h, [have_libelf_libelf_h=yes]) - AC_CHECK_HEADERS(libelf/gelf.h, [have_libelf_gelf_h=yes]) - - # If we couldn't find libelf.h and the user forced it, emit an error. - if test x"$have_libelf_h" != x"yes" \ - && test x"$have_libelf_libelf_h" != x"yes" ; then - if test x"$default_enable_lto" != x"yes" ; then - AC_MSG_ERROR([LTO support requires libelf.h or libelf/libelf.h.]) - else - enable_lto=no - libelflibs= - libelfinc= - fi - fi - - # If we couldn't find gelf.h and the user forced it, emit an error. - if test x"$have_gelf_h" != x"yes" \ - && test x"$have_libelf_gelf_h" != x"yes" ; then - if test x"$default_enable_lto" != x"yes" ; then - AC_MSG_ERROR([LTO support requires gelf.h or libelf/gelf.h.]) - else - enable_lto=no - libelflibs= - libelfinc= - fi - fi - - # Check that the detected libelf has the functions we need. We cannot - # rely on just detecting the headers since they do not include - # versioning information. Add functions, if needed. - if test x"$enable_lto" = x"yes" ; then - AC_MSG_CHECKING([for the correct version of libelf]) - AC_TRY_LINK( - [#include ],[ - elf_errmsg (0); - elf_getscn (0, 0); - elf_nextscn (0, 0); - elf_strptr (0, 0, 0); - elf_getident (0, 0); - elf_begin (0, 0, 0); - elf_ndxscn (0); - elf_end (0); - ], - [AC_MSG_RESULT([yes]);], - [AC_MSG_RESULT([no]); enable_lto=no; libelflibs= ; libelfinc= ] - ) - - # Check for elf_getshdrstrndx or elf_getshstrndx. The latter's flavor - # is determined in gcc/configure.ac. - if test x"$enable_lto" = x"yes" ; then - AC_MSG_CHECKING([for elf_getshdrstrndx]) - AC_TRY_LINK( - [#include ],[ - elf_getshdrstrndx (0, 0); - ], - [AC_MSG_RESULT([yes]);], - [AC_MSG_RESULT([no]); - AC_MSG_CHECKING([for elf_getshstrndx]) - AC_TRY_LINK( - [#include ],[ - elf_getshstrndx (0, 0); - ], - [AC_MSG_RESULT([yes]);], - [AC_MSG_RESULT([no]); enable_lto=no; libelflibs= ; libelfinc= ] - )] - ) - fi - - # If we couldn't enable LTO and the user forced it, emit an error. - if test x"$enable_lto" = x"no" \ - && test x"$default_enable_lto" != x"yes" ; then - AC_MSG_ERROR([To enable LTO, GCC requires libelf v0.8.12+. -Try the --with-libelf, --with-libelf-include and --with-libelf-lib options -to specify its location.]) - fi - fi - - CFLAGS="$saved_CFLAGS" - CPPFLAGS="$saved_CPPFLAGS" - LIBS="$saved_LIBS" - - fi - - # Flags needed for libelf. - AC_SUBST(libelflibs) - AC_SUBST(libelfinc) - # ELF platforms build the lto-plugin when GOLD is in use. - build_lto_plugin=${ENABLE_GOLD} -fi],[if test x"$default_enable_lto" = x"yes" ; then - case $target in - *-apple-darwin* | *-cygwin* | *-mingw*) ;; - # On other non-ELF platforms, LTO must be explicitly enabled. - *) enable_lto=no ;; - esac - else - # Apart from ELF platforms, only Windows and Darwin support LTO so far. - # It would also be nice to check the binutils support, but we don't - # have gcc_GAS_CHECK_FEATURE available here. For now, we'll just - # warn during gcc/ subconfigure; unless you're bootstrapping with - # -flto it won't be needed until after installation anyway. - case $target in - *-cygwin* | *-mingw* | *-apple-darwin*) ;; - *) if test x"$enable_lto" = x"yes"; then - AC_MSG_ERROR([LTO support is not enabled for this target.]) - fi - ;; - esac - fi - # Among non-ELF, only Windows platforms support the lto-plugin so far. - case $target in - *-cygwin* | *-mingw*) build_lto_plugin=yes ;; - *) ;; - esac - default_enable_lto=no]) - - # By default, C is the only stage 1 language. stage1_languages=,c, Index: lto-plugin/lto-plugin-elf.c =================================================================== --- lto-plugin/lto-plugin-elf.c (revision 166214) +++ lto-plugin/lto-plugin-elf.c (working copy) @@ -1,157 +0,0 @@ -/* 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 -. */ - -#include -#include -#include -#include -#include -#include - -/* The presence of gelf.h is checked by the toplevel configure script. */ -#include - -/* 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; -} - Index: lto-plugin/lto-plugin.h =================================================================== --- lto-plugin/lto-plugin.h (revision 166214) +++ lto-plugin/lto-plugin.h (working copy) @@ -1,84 +0,0 @@ -/* 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 -. */ - -#include -#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; - Index: lto-plugin/configure.ac =================================================================== --- lto-plugin/configure.ac (revision 166214) +++ lto-plugin/configure.ac (working copy) @@ -6,18 +6,21 @@ AM_INIT_AUTOMAKE([foreign no-dist]) AM_MAINTAINER_MODE AC_PROG_CC AC_SYS_LARGEFILE -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.]) ;; +# Trying to get this information from gcc's config is tricky. +case $target in + x86_64*-mingw*) + AC_DEFINE([SYM_STYLE], [ss_none], [Default symbol style]) + ;; + *-cygwin* | i?86*-mingw* ) + AC_DEFINE([SYM_STYLE], [ss_win32], [Default symbol style]) + ;; + *) + AC_DEFINE([SYM_STYLE], [ss_none], [Default symbol style]) + ;; esac - -AC_SUBST(LTO_FORMAT) AC_TYPE_UINT64_T AC_CONFIG_FILES(Makefile) +AC_CONFIG_HEADERS(config.h) AC_OUTPUT Index: lto-plugin/lto-plugin-coff.c =================================================================== --- lto-plugin/lto-plugin-coff.c (revision 166214) +++ lto-plugin/lto-plugin-coff.c (working copy) @@ -1,38 +0,0 @@ -/* 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 -. */ - -/* 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; -} - Index: lto-plugin/Makefile.am =================================================================== --- lto-plugin/Makefile.am (revision 166214) +++ lto-plugin/Makefile.am (working copy) @@ -7,20 +7,13 @@ gcc_version := $(shell cat $(top_srcdir)/../gcc/BA target_noncanonical := @target_noncanonical@ libexecsubdir := $(libexecdir)/gcc/$(target_noncanonical)/$(gcc_version) -# How to find libelf -LIBELFLIBS = @LIBELFLIBS@ -LIBELFINC = @LIBELFINC@ - -# Which object format to parse. -LTO_FORMAT = @LTO_FORMAT@ - -AM_CPPFLAGS = -I$(top_srcdir)/../include $(LIBELFINC) +AM_CPPFLAGS = -I$(top_srcdir)/../include $(DEFS) AM_CFLAGS = -Wall -Werror libexecsub_LTLIBRARIES = liblto_plugin.la -liblto_plugin_la_SOURCES = lto-plugin.c lto-plugin-$(LTO_FORMAT).c -liblto_plugin_la_LIBADD = $(LIBELFLIBS) \ +liblto_plugin_la_SOURCES = lto-plugin.c +liblto_plugin_la_LIBADD = \ $(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) Index: lto-plugin/lto-plugin.c =================================================================== --- lto-plugin/lto-plugin.c (revision 166214) +++ lto-plugin/lto-plugin.c (working copy) @@ -32,6 +32,9 @@ along with this program; see the file COPYING3. I -nop: Instead of running lto-wrapper, pass the original to the plugin. This only works if the input files are hybrid. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include #include @@ -46,10 +49,73 @@ along with this program; see the file COPYING3. I #include #include #include "../gcc/lto/common.h" +#include "simple-object.h" +#include "plugin-api.h" -/* Common definitions for/from the object format dependent code. */ -#include "lto-plugin.h" +/* Handle opening elf files on hosts, such as Windows, that may use + text file handling that will break binary access. */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif +/* Segment name for LTO sections. This is only used for Mach-O. + FIXME: This needs to be kept in sync with darwin.c. */ + +#define LTO_SEGMENT_NAME "__GNU_LTO" + +/* LTO magic section name. */ + +#define LTO_SECTION_PREFIX ".gnu.lto_.symtab" +#define LTO_SECTION_PREFIX_LEN (sizeof (LTO_SECTION_PREFIX) - 1) + +/* 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; +}; + +/* Encapsulates object file data during symbol scan. */ +struct plugin_objfile +{ + int found; + simple_object_read *objfile; + struct plugin_symtab *out; + const struct ld_plugin_input_file *file; +}; + +/* 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; +}; + +/* Until ASM_OUTPUT_LABELREF can be hookized and decoupled from + stdio file streams, we do simple label translation here. */ + +enum symbol_style +{ + ss_none, /* No underscore prefix. */ + ss_win32, /* Underscore prefix any symbol not beginning with '@'. */ + ss_uscore, /* Underscore prefix all symbols. */ +}; + static char *arguments_file_name; static ld_plugin_register_claim_file register_claim_file; static ld_plugin_register_all_symbols_read register_all_symbols_read; @@ -58,14 +124,11 @@ static ld_plugin_register_cleanup register_cleanup static ld_plugin_add_input_file add_input_file; static ld_plugin_add_input_library add_input_library; static ld_plugin_message message; +static ld_plugin_add_symbols add_symbols; -/* 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; +static struct plugin_file_info *claimed_files = NULL; +static unsigned int num_claimed_files = 0; -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; @@ -79,7 +142,12 @@ static bool debug; static bool nop; static char *resolution_file = NULL; -void +/* Set by default from configure.ac, but can be overridden at runtime + by using -plugin-opt=-sym-style={none,win32,underscore|uscore} + (in fact, only first letter of style arg is checked.) */ +static enum symbol_style sym_style = SYM_STYLE; + +static void check (bool gate, enum ld_plugin_level level, const char *text) { if (gate) @@ -100,7 +168,7 @@ check (bool gate, enum ld_plugin_level level, cons by P and the result is written in ENTRY. The slot number is stored in SLOT. Returns the address of the next entry. */ -char * +static char * parse_table_entry (char *p, struct ld_plugin_symbol *entry, struct sym_aux *aux) { @@ -122,7 +190,24 @@ parse_table_entry (char *p, struct ld_plugin_symbo LDPV_HIDDEN }; - entry->name = xstrdup (p); + switch (sym_style) + { + case ss_win32: + if (p[0] == '@') + { + /* cf. Duff's device. */ + case ss_none: + entry->name = xstrdup (p); + break; + } + /* FALL-THROUGH. */ + case ss_uscore: + entry->name = concat ("_", p, NULL); + break; + default: + check (false, LDPL_FATAL, "invalid symbol style requested"); + break; + } while (*p) p++; p++; @@ -165,7 +250,7 @@ parse_table_entry (char *p, struct ld_plugin_symbo /* Translate the IL symbol table located between DATA and END. Append the slots and symbols to OUT. */ -void +static void translate (char *data, char *end, struct plugin_symtab *out) { struct sym_aux *aux; @@ -621,7 +706,7 @@ static int symbol_strength (struct ld_plugin_symbo XXX how to handle common? */ -void +static void resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts) { htab_t symtab = htab_create (t->nsyms, hash_sym, eq_sym, NULL); @@ -689,6 +774,120 @@ resolve_conflicts (struct plugin_symtab *t, struct htab_delete (symtab); } +/* Process one section of an object file. */ + +static int +process_symtab (void *data, const char *name, off_t offset, off_t length) +{ + struct plugin_objfile *obj = (struct plugin_objfile *)data; + char *s; + char *secdata; + + if (strncmp (name, LTO_SECTION_PREFIX, LTO_SECTION_PREFIX_LEN) != 0) + return 1; + + s = strrchr (name, '.'); + if (s) + sscanf (s, ".%x", &obj->out->id); + secdata = xmalloc (length); + offset += obj->file->offset; + if (offset != lseek (obj->file->fd, offset, SEEK_SET) + || length != read (obj->file->fd, secdata, length)) + { + if (message) + message (LDPL_FATAL, "%s: corrupt object file", obj->file->name); + /* Force claim_file_handler to abandon this file. */ + obj->found = 0; + free (secdata); + return 0; + } + + translate (secdata, secdata + length, obj->out); + obj->found++; + free (secdata); + return 1; +} + +/* 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; + struct plugin_objfile obj; + struct plugin_file_info lto_file; + int err; + const char *errmsg; + + memset (<o_file, 0, sizeof (struct plugin_file_info)); + + if (file->offset != 0) + { + char *objname; + /* 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; + } + else + { + lto_file.name = xstrdup (file->name); + } + lto_file.handle = file->handle; + + *claimed = 0; + obj.file = file; + obj.found = 0; + obj.out = <o_file.symtab; + errmsg = NULL; + obj.objfile = simple_object_start_read (file->fd, file->offset, LTO_SEGMENT_NAME, + &errmsg, &err); + if (obj.objfile) + errmsg = simple_object_find_sections (obj.objfile, process_symtab, &obj, &err); + + if (!obj.objfile || errmsg) + { + if (err && message) + message (LDPL_FATAL, "%s: %s: %s", file->name, errmsg, + xstrerror (err)); + else if (message) + message (LDPL_FATAL, "%s: %s", file->name, errmsg); + goto err; + } + + if (obj.found == 0) + goto err; + + if (obj.found > 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 (obj.objfile) + simple_object_release_read (obj.objfile); + if (file->fd >= 0) + close (file->fd); + + return LDPS_OK; +} + /* Parse the plugin options. */ static void @@ -706,6 +905,21 @@ process_option (const char *option) pass_through_items[num_pass_through_items - 1] = xstrdup (option + strlen ("-pass-through=")); } + else if (!strncmp (option, "-sym-style=", sizeof ("-sym-style=") - 1)) + { + switch (option[sizeof ("-sym-style=") - 1]) + { + case 'w': + sym_style = ss_win32; + break; + case 'u': + sym_style = ss_uscore; + break; + default: + sym_style = ss_none; + break; + } + } else { int size; @@ -727,10 +941,6 @@ onload (struct ld_plugin_tv *tv) struct ld_plugin_tv *p; enum ld_plugin_status status; - status = onload_format_checks (tv); - if (status != LDPS_OK) - return status; - p = tv; while (p->tv_tag) { Index: gcc/config.gcc =================================================================== --- gcc/config.gcc (revision 166214) +++ gcc/config.gcc (working copy) @@ -219,8 +219,6 @@ default_gnu_indirect_function=no target_gtfiles= need_64bit_hwint= need_64bit_isa= -# Selects the object file format reader/writer used by LTO. -lto_binary_reader=lto-elf # Don't carry these over build->host->target. Please. xm_file= @@ -1160,13 +1158,11 @@ i[34567]86-*-darwin*) # support. with_cpu=${with_cpu:-generic} tmake_file="${tmake_file} t-slibgcc-darwin i386/t-crtpc i386/t-crtfm" - lto_binary_reader=lto-macho ;; x86_64-*-darwin*) with_cpu=${with_cpu:-generic} tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm" tm_file="${tm_file} ${cpu_type}/darwin64.h" - lto_binary_reader=lto-macho ;; i[34567]86-*-elf*) tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h" @@ -1421,7 +1417,6 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*) thread_file='posix' fi use_gcc_stdint=wrap - lto_binary_reader=lto-coff ;; i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h" @@ -1494,7 +1489,6 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o" default_use_cxa_atexit=yes use_gcc_stdint=wrap - lto_binary_reader=lto-coff case ${enable_threads} in "" | yes | win32) thread_file='win32' tmake_file="${tmake_file} i386/t-gthr-win32" @@ -2006,7 +2000,6 @@ powerpc-*-darwin*) ;; esac tmake_file="${tmake_file} t-slibgcc-darwin" - lto_binary_reader=lto-macho extra_headers=altivec.h ;; powerpc64-*-darwin*) @@ -2014,7 +2007,6 @@ powerpc64-*-darwin*) extra_parts="crt2.o" tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc-darwin" tm_file="${tm_file} ${cpu_type}/darwin8.h ${cpu_type}/darwin64.h" - lto_binary_reader=lto-macho extra_headers=altivec.h ;; powerpc*-*-freebsd*) Index: gcc/doc/install.texi =================================================================== --- gcc/doc/install.texi (revision 166214) +++ gcc/doc/install.texi (working copy) @@ -355,17 +355,6 @@ not installed in your default library search path. Necessary to build libgcj, the GCJ runtime. -@item libelf version 0.8.12 (or later) - -Necessary to build link-time optimization (LTO) support. It can be -downloaded from @uref{http://www.mr511.de/software/libelf-0.8.12.tar.gz}, -though it is commonly available in several systems. The version in -IRIX 6.5 doesn't work since it lacks @file{gelf.h}. The version in -Solaris 2 does work. - -The @option{--with-libelf} configure option should be used if libelf is -not installed in your default library search patch. - @end table @heading Tools/packages necessary for modifying GCC @@ -1650,21 +1639,10 @@ default for a native toolchain with an assembler t GLIBC 2.11 or above, otherwise disabled. @item --enable-lto +@itemx --disable-lto Enable support for link-time optimization (LTO). This is enabled by -default if a working libelf implementation is found (see -@option{--with-libelf}). +default, and may be disabled using @option{--disable-lto}. -@item --with-libelf=@var{pathname} -@itemx --with-libelf-include=@var{pathname} -@itemx --with-libelf-lib=@var{pathname} -If you do not have libelf installed in a standard location and you -want to enable support for link-time optimization (LTO), you can -explicitly specify the directory where libelf is installed -(@samp{--with-libelf=@var{libelfinstalldir}}). The -@option{--with-libelf=@var{libelfinstalldir}} option is shorthand for -@option{--with-libelf-include=@var{libelfinstalldir}/include} -@option{--with-libelf-lib=@var{libelfinstalldir}/lib}. - @item --enable-gold Enable support for using @command{gold} as the linker. If gold support is enabled together with @option{--enable-lto}, an additional directory