From 1cd0b7167ed9b43b189c39549d8165a020aee9b6 Mon Sep 17 00:00:00 2001 From: Dave Korn Date: Thu, 7 Oct 2010 20:28:59 +0000 Subject: configure.ac (build_lto_plugin): New shell variable. ChangeLog: 2010-10-07 Dave Korn * 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 * 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 * 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 --- ChangeLog | 9 +++ configure | 13 ++- configure.ac | 13 ++- gcc/ChangeLog | 9 +++ gcc/config.host | 9 +++ gcc/config.in | 16 +++- gcc/configure | 10 ++- gcc/configure.ac | 4 + gcc/gcc.c | 4 +- lto-plugin/ChangeLog | 47 +++++++++++ lto-plugin/Makefile.am | 10 ++- lto-plugin/Makefile.in | 24 ++++-- lto-plugin/configure | 13 ++- lto-plugin/configure.ac | 8 ++ lto-plugin/lto-plugin-coff.c | 38 +++++++++ lto-plugin/lto-plugin-elf.c | 157 ++++++++++++++++++++++++++++++++++++ lto-plugin/lto-plugin.c | 185 +++++-------------------------------------- lto-plugin/lto-plugin.h | 84 ++++++++++++++++++++ 18 files changed, 465 insertions(+), 188 deletions(-) create mode 100644 lto-plugin/lto-plugin-coff.c create mode 100644 lto-plugin/lto-plugin-elf.c create mode 100644 lto-plugin/lto-plugin.h diff --git a/ChangeLog b/ChangeLog index 57fb0e7..f9d37cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-10-07 Dave Korn + + * 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. + 2010-10-07 Ralf Wildenhues Sync from src: diff --git a/configure b/configure index 7762106..b1fbfaa 100755 --- a/configure +++ b/configure @@ -6676,11 +6676,13 @@ to specify its location." "$LINENO" 5 # Flags needed for libelf. + # ELF platforms build the lto-plugin when GOLD is in use. + build_lto_plugin=${ENABLE_GOLD} fi else if test x"$default_enable_lto" = x"yes" ; then case $target in - *-apple-darwin*) ;; + *-apple-darwin* | *-cygwin* | *-mingw*) ;; # On other non-ELF platforms, LTO must be explicitly enabled. *) enable_lto=no ;; esac @@ -6691,13 +6693,18 @@ else # 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*) ;; + *-cygwin* | *-mingw* | *-apple-darwin*) ;; *) if test x"$enable_lto" = x"yes"; then as_fn_error "LTO support is not enabled for this target." "$LINENO" 5 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 fi @@ -6778,7 +6785,7 @@ if test -d ${srcdir}/gcc; then *,lto,*) ;; *) enable_languages="${enable_languages},lto" ;; esac - if test "${ENABLE_GOLD}" = "yes" ; then + if test "${build_lto_plugin}" = "yes" ; then configdirs="$configdirs lto-plugin" extra_host_libiberty_configure_flags=--enable-shared fi diff --git a/configure.ac b/configure.ac index 6af4be1..bf5fe3a 100644 --- a/configure.ac +++ b/configure.ac @@ -1786,9 +1786,11 @@ to specify its location.]) # 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*) ;; + *-apple-darwin* | *-cygwin* | *-mingw*) ;; # On other non-ELF platforms, LTO must be explicitly enabled. *) enable_lto=no ;; esac @@ -1799,13 +1801,18 @@ fi],[if test x"$default_enable_lto" = x"yes" ; then # 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*) ;; + *-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]) @@ -1884,7 +1891,7 @@ if test -d ${srcdir}/gcc; then *,lto,*) ;; *) enable_languages="${enable_languages},lto" ;; esac - if test "${ENABLE_GOLD}" = "yes" ; then + if test "${build_lto_plugin}" = "yes" ; then configdirs="$configdirs lto-plugin" extra_host_libiberty_configure_flags=--enable-shared fi diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 744c579..6b50b65 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-10-07 Dave Korn + + * 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. + 2010-10-07 Richard Henderson * target.h (enum unwind_info_type): Move ... diff --git a/gcc/config.host b/gcc/config.host index 9738345..c035a50 100644 --- a/gcc/config.host +++ b/gcc/config.host @@ -51,10 +51,15 @@ # # host_can_use_collect2 Set to yes normally; to no if the host cannot # link or otherwise use collect2 +# # use_long_long_for_widest_fast_int Set this to 'yes' if 'long long' # (or '__int64') is wider than 'long' but still # efficeiently supported by the host hardware. # Only affects compile speed. Default is 'no'. +# +# host_lto_plugin_soname Set this to the name to which the LTO linker +# plugin gets compiled on this host, if it is +# different from the default "liblto_plugin.so". # When setting any of these variables, check to see if a corresponding # variable is present in config.build; if so, you will likely want to @@ -70,6 +75,7 @@ host_extra_gcc_objs= out_host_hook_obj=host-default.o host_can_use_collect2=yes use_long_long_for_widest_fast_int=no +host_lto_plugin_soname=liblto_plugin.so # Unsupported hosts list. Generally, only include hosts known to fail here, # since we allow hosts not listed to be supported generically. @@ -206,12 +212,14 @@ case ${host} in out_host_hook_obj=host-cygwin.o host_xmake_file="${host_xmake_file} i386/x-cygwin" host_exeext=.exe + host_lto_plugin_soname=cyglto_plugin-0.dll ;; i[34567]86-*-mingw32*) host_xm_file=i386/xm-mingw32.h host_xmake_file="${host_xmake_file} i386/x-mingw32" host_exeext=.exe out_host_hook_obj=host-mingw32.o + host_lto_plugin_soname=liblto_plugin-0.dll ;; x86_64-*-mingw*) use_long_long_for_widest_fast_int=yes @@ -219,6 +227,7 @@ case ${host} in host_xmake_file="${host_xmake_file} i386/x-mingw32" host_exeext=.exe out_host_hook_obj=host-mingw32.o + host_lto_plugin_soname=liblto_plugin-0.dll ;; i[34567]86-*-uwin*) echo "*** UWIN may not be used as a host platform because" diff --git a/gcc/config.in b/gcc/config.in index 3925a11..4576de07 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -959,9 +959,6 @@ /* Define if your assembler and linker support .hidden. */ #undef HAVE_GAS_HIDDEN -/* Define if your system supports gnu indirect functions. */ -#undef HAVE_GNU_INDIRECT_FUNCTION - /* Define if your assembler supports .lcomm with an alignment field. */ #ifndef USED_FOR_TARGET #undef HAVE_GAS_LCOMM_WITH_ALIGNMENT @@ -1062,6 +1059,12 @@ #endif +/* Define if your system supports gnu indirect functions. */ +#ifndef USED_FOR_TARGET +#undef HAVE_GNU_INDIRECT_FUNCTION +#endif + + /* Define if using GNU ld. */ #ifndef USED_FOR_TARGET #undef HAVE_GNU_LD @@ -1543,6 +1546,13 @@ #endif +/* Define to the name of the LTO plugin DSO that must be passed to the + linker's -plugin=LIB option. */ +#ifndef USED_FOR_TARGET +#undef LTOPLUGINSONAME +#endif + + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #ifndef USED_FOR_TARGET diff --git a/gcc/configure b/gcc/configure index 3b20cc9..68cb29e 100755 --- a/gcc/configure +++ b/gcc/configure @@ -11045,6 +11045,12 @@ case $use_collect2 in ;; esac + +cat >>confdefs.h <<_ACEOF +#define LTOPLUGINSONAME "${host_lto_plugin_soname}" +_ACEOF + + # --------------------------- # Assembler & linker features # --------------------------- @@ -17127,7 +17133,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17130 "configure" +#line 17136 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17233,7 +17239,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17236 "configure" +#line 17242 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/configure.ac b/gcc/configure.ac index 164d3f4..9dd9c5d 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1811,6 +1811,10 @@ case $use_collect2 in ;; esac +AC_DEFINE_UNQUOTED(LTOPLUGINSONAME,"${host_lto_plugin_soname}", +[Define to the name of the LTO plugin DSO that must be + passed to the linker's -plugin=LIB option.]) + # --------------------------- # Assembler & linker features # --------------------------- diff --git a/gcc/gcc.c b/gcc/gcc.c index f6e0b9e..7005c5c 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -6827,10 +6827,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" fuse_linker_plugin + strlen (fuse_linker_plugin), 0)) { linker_plugin_file_spec = find_a_file (&exec_prefixes, - "liblto_plugin.so", R_OK, + LTOPLUGINSONAME, R_OK, false); if (!linker_plugin_file_spec) - fatal_error ("-fuse-linker-plugin, but liblto_plugin.so not found"); + fatal_error ("-fuse-linker-plugin, but " LTOPLUGINSONAME " not found"); lto_libgcc_spec = find_a_file (&startfile_prefixes, "libgcc.a", R_OK, true); diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index 6f6c4e8..9caad6a 100644 --- a/lto-plugin/ChangeLog +++ b/lto-plugin/ChangeLog @@ -1,3 +1,50 @@ +2010-10-07 Dave Korn + + * 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 * lto-plugin.c: Include diff --git a/lto-plugin/Makefile.am b/lto-plugin/Makefile.am index da74e1c..52bf671 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 2f58f9b..c3f5260 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 234ff90..1e4041b 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 e89a982..c43b264 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 0000000..acaff59 --- /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 +. */ + +/* 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 0000000..afd79da --- /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 +. */ + +#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; +} + diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c index dc51b48..7e8443d 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 #include #include - -/* The presence of gelf.h is checked by the toplevel configure script. */ -#include - -#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 (<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; -} - /* 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 0000000..09eb850 --- /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 +. */ + +#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; + -- cgit v1.1