From 0a654319f9a1d0ebaacb5572139f72c7f236b100 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Sun, 7 May 2017 15:12:08 -0700 Subject: First stab at gen-versions.sh Signed-off-by: Alexey Neyman diff --git a/.gitignore b/.gitignore index d12732a..138b741 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ paths.* !paths.in config/configure.in config/gen/ +config/versions/ .config # Temporaries diff --git a/bootstrap b/bootstrap index ab493dd..44f77a7 100755 --- a/bootstrap +++ b/bootstrap @@ -4,7 +4,10 @@ set -e printf "Running autoconf...\n" autoconf -Wall --force -printf "Generating kconfig files...\n" +printf "Generating kconfig component lists...\n" ./maintainer/gen-kconfig.sh +printf "Generating kconfig component versions...\n" +./maintainer/gen-versions.sh + printf "Done. You may now run:\n ./configure\n" diff --git a/config/binutils/binutils.in b/config/binutils/binutils.in index c83cbb1..b97f178 100644 --- a/config/binutils/binutils.in +++ b/config/binutils/binutils.in @@ -2,167 +2,14 @@ comment "GNU binutils" -config BINUTILS_CUSTOM - bool - prompt "Custom binutils" - depends on EXPERIMENTAL - select BINUTILS_2_26_or_later - help - The choosen binutils version shall be not downloaded. Instead use - a custom location to get the source. - -if BINUTILS_CUSTOM - -config BINUTILS_CUSTOM_LOCATION - string - prompt "Full path to custom binutils source" - help - Enter the path to the directory or tarball of your source for binutils. - - If the path is a tarball, it should extract to: -/ - where the name is this component, binutils, and the version is set - below in the custom version string. - -config BINUTILS_CUSTOM_VERSION - string - prompt "Binutils Custom Version number" - help - Enter the version number for your custom binutils. - -config BINUTILS_VERSION - string - default BINUTILS_CUSTOM_VERSION - -endif # BINUTILS_CUSTOM - -if ! BINUTILS_CUSTOM - -config BINUTILS_SHOW_LINARO - bool - prompt "Show Linaro versions" - help - Linaro is maintaining some advanced/more stable/experimental versions - of binutils, especially for the ARM architecture. - - Those versions have not been blessed by the binutils comunity (nor have they - been cursed either!), but they look to be pretty much stable, and even - more stable than the upstream versions. YMMV... - - If you do not know what this Linaro stuff is, then simply say 'n' here, - and rest in peace. OTOH, if you know what you are doing, you will be - able to use and enjoy :-) the Linaro versions by saying 'y' here. - - Linaro: http://www.linaro.org/ - -choice - bool - prompt "binutils version" -# Don't remove next line -# CT_INSERT_VERSION_BELOW - -config BINUTILS_V_2_28 - bool - prompt "2.28" - select BINUTILS_2_27_or_later - -config BINUTILS_V_2_27 - bool - prompt "2.27" - select BINUTILS_2_27_or_later - -config BINUTILS_V_2_26 - bool - prompt "2.26" - select BINUTILS_2_26_or_later - -config BINUTILS_V_2_25_1 - bool - prompt "2.25.1 (OBSOLETE)" - select BINUTILS_2_25_1_or_later - depends on OBSOLETE - -config BINUTILS_LINARO_V_2_25 - bool - prompt "linaro-2.25.0-2015.01-2 (OBSOLETE)" - select BINUTILS_2_25_or_later - depends on BINUTILS_SHOW_LINARO - depends on OBSOLETE - -config BINUTILS_LINARO_V_2_24 - bool - prompt "linaro-2.24.0-2014.11-2 (OBSOLETE)" - select BINUTILS_2_24_or_later - depends on BINUTILS_SHOW_LINARO - depends on OBSOLETE - -config BINUTILS_V_2_24 - bool - prompt "2.24 (OBSOLETE)" - select BINUTILS_2_24_or_later - depends on OBSOLETE - -config BINUTILS_LINARO_V_2_23_2 - bool - prompt "linaro-2.23.2-2013.10-4 (OBSOLETE)" - select BINUTILS_2_23_2_or_later - depends on BINUTILS_SHOW_LINARO - depends on OBSOLETE - -config BINUTILS_V_2_23_2 - bool - prompt "2.23.2 (OBSOLETE)" - select BINUTILS_2_23_2_or_later - depends on OBSOLETE - -endchoice - -config BINUTILS_VERSION - string -# Don't remove next line -# CT_INSERT_VERSION_STRING_BELOW - default "2.28" if BINUTILS_V_2_28 - default "2.27" if BINUTILS_V_2_27 - default "2.26" if BINUTILS_V_2_26 - default "2.25.1" if BINUTILS_V_2_25_1 - default "linaro-2.25.0-2015.01-2" if BINUTILS_LINARO_V_2_25 - default "linaro-2.24.0-2014.11-2" if BINUTILS_LINARO_V_2_24 - default "2.24" if BINUTILS_V_2_24 - default "linaro-2.23.2-2013.10-4" if BINUTILS_LINARO_V_2_23_2 - default "2.23.2" if BINUTILS_V_2_23_2 - -endif # ! BINUTILS_CUSTOM - -config BINUTILS_2_27_or_later - bool - select BINUTILS_2_26_or_later - -config BINUTILS_2_26_or_later - bool - select BINUTILS_2_25_1_or_later - -config BINUTILS_2_25_1_or_later - bool - select BINUTILS_2_25_or_later - -config BINUTILS_2_25_or_later - bool - select BINUTILS_2_24_or_later - -config BINUTILS_2_24_or_later - bool - select BINUTILS_2_23_2_or_later - -config BINUTILS_2_23_2_or_later - bool - select BINUTILS_HAS_GOLD - select BINUTILS_HAS_HASH_STYLE - select BINUTILS_HAS_PKGVERSION_BUGURL - select BINUTILS_HAS_PLUGINS +source "config/versions/binutils.in" config BINUTILS_HAS_HASH_STYLE + default y if BINUTILS_V_2_23_2_or_later bool config BINUTILS_HAS_GOLD + default y if BINUTILS_V_2_23_2_or_later bool # gold only suports the listed architectures @@ -179,9 +26,11 @@ config BINUTILS_GOLD_SUPPORT depends on ! STATIC_TOOLCHAIN config BINUTILS_HAS_PLUGINS + default y if BINUTILS_V_2_23_2_or_later bool config BINUTILS_HAS_PKGVERSION_BUGURL + default y if BINUTILS_V_2_23_2_or_later bool # Force using the BFD linker if needed. There are two options: diff --git a/maintainer/gen-versions.sh b/maintainer/gen-versions.sh new file mode 100755 index 0000000..1d5cb76 --- /dev/null +++ b/maintainer/gen-versions.sh @@ -0,0 +1,253 @@ +#!/bin/bash + +# Where the version configs are generated +config_dir=config/versions +defaults=packages/default.desc + +declare -A forks + +debug() +{ + if [ -n "${DEBUG}" ]; then + echo ":: $@" >&2 + fi +} + +read_files() +{ + local f l + + for f in ${defaults} "$@"; do + [ -r "${f}" ] || continue + while read l; do + case "${l}" in + "#*") continue;; + *) echo "[${l%%=*}]=${l#*=}";; + esac + done < "${f}" + done +} + +derived_package() +{ + info[name]=${p} + info[forks]=${forks[${p}]} + info[master]=${info[master]:-${p}} + # Various kconfig-ized prefixes + tmp=${p^^} + info[pfx]=${tmp//[^0-9A-Z_]/_} + tmp=${info[origin]^^} + info[originpfx]=${tmp//[^0-9A-Z_/_} + tmp=${info[master]^^} + info[masterpfx]=${tmp//[^0-9A-Z_/_} +} + +read_package_desc() +{ + read_files "packages/${1}/package.desc" +} + +read_version_desc() +{ + read_files "packages/${1}/package.desc" "packages/${1}/${2}/version.desc" +} + +for_each_package() +{ + local list="${1}" + local -A info + local p tmp + + debug "Entering: for_each_package $@" + + shift + for p in ${list}; do + eval "info=( `read_package_desc ${p}` )" + derived_package ${p} + debug "Evaluate for ${p}: $@" + eval "$@" + done +} + +for_each_version() +{ + local pkg="${1}" + local -A info prev + local -a versions + local v tmp + + debug "Entering: for_each_version $@" + + shift + versions=( `cd packages/${pkg} && ls */version.desc 2>/dev/null | sed 's,/version.desc$,,' | sort -rV` ) + tmp= + for v in "${versions[@]}"; do + if [ -n "${tmp}" ]; then + prev["${tmp}"]=${v} + fi + tmp="${v}" + done + + if [ -n "${tmp}" ]; then + prev["${tmp}"]= + fi + + for v in "${versions[@]}"; do + eval "info=( `read_version_desc "${pkg}" "${v}"` )" + debug "INFO [[ `read_version_desc "${pkg}" "${v}"` ]]" + derived_package ${pkg} + info[ver]="${v}" + info[kcfg]="${v//[^0-9A-Za-z_]/_}" + info[prev]="${prev[${v}]//[^0-9A-Za-z_]/_}" + debug "Evaluate for ${pkg}/${v}: $@" + eval "$@" + done +} + +# Setup: find master-fork relationships between packages +find_forks() +{ + [ "${info[master]}" != "${info[name]}" ] && forks[${info[master]}]+=" ${info[name]}" +} + +gen_versions() +{ + local cond=$1 + + debug "Entering: gen_versions $@" + + if [ -n "${cond}" ]; then + cat <"${config_dir}/${info[name]}.in" + cat </dev/null | sed 's,/package.desc$,,' | xargs echo` +debug "Generating package version descriptions" +debug "Packages: ${all_packages}" +for_each_package "${all_packages}" find_forks +for_each_package "${all_packages}" gen_one_component +debug "Done!" diff --git a/packages/GNU.help b/packages/GNU.help new file mode 100644 index 0000000..ae6ba14 --- /dev/null +++ b/packages/GNU.help @@ -0,0 +1,6 @@ +GNU (which is a recursive acronym for "GNU's Not Unix") provides GNU binutils, +GNU C Compiler (gcc), GNU debugger (gdb) and many other utilities. GNU is +considered the master source for these packages. + +You should select "GNU" here unless you definitely know that you need some version +from another source. diff --git a/packages/Linaro.help b/packages/Linaro.help new file mode 100644 index 0000000..f752543 --- /dev/null +++ b/packages/Linaro.help @@ -0,0 +1,4 @@ +Linaro is maintaining some advanced/more stable/experimental versions +of binutils, gcc, glibc and gdb, especially for the ARM architecture. +These versions contain some changes that are not (yet?) merged into +their respective upstream repositories. diff --git a/packages/binutils-linaro/2.23.2-2013.10-4/version.desc b/packages/binutils-linaro/2.23.2-2013.10-4/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils-linaro/2.23.2-2013.10-4/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils-linaro/2.24.0-2014.11-2/version.desc b/packages/binutils-linaro/2.24.0-2014.11-2/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils-linaro/2.24.0-2014.11-2/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils-linaro/2.25.0-2015.01-2/version.desc b/packages/binutils-linaro/2.25.0-2015.01-2/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils-linaro/2.25.0-2015.01-2/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils-linaro/package.desc b/packages/binutils-linaro/package.desc new file mode 100644 index 0000000..4daff32 --- /dev/null +++ b/packages/binutils-linaro/package.desc @@ -0,0 +1,6 @@ +vcs="git" +repository="https://git.linaro.org/toolchain/binutils-gdb.git" +download="https://ftp.gnu.org/gnu/binutils/" +master="binutils" +origin="Linaro" +experimental="yes" diff --git a/packages/binutils/2.23.2/120-sh-conf.patch b/packages/binutils/2.23.2/120-sh-conf.patch new file mode 100644 index 0000000..ea3d1b6 --- /dev/null +++ b/packages/binutils/2.23.2/120-sh-conf.patch @@ -0,0 +1,29 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +--- a/configure ++++ b/configure +@@ -1495,7 +1495,7 @@ + mips*-*-*) + noconfigdirs="$noconfigdirs gprof" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +--- a/configure.ac ++++ b/configure.ac +@@ -712,7 +712,7 @@ + mips*-*-*) + noconfigdirs="$noconfigdirs gprof" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.23.2/300-001_ld_makefile_patch.patch b/packages/binutils/2.23.2/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..5cb0f61 --- /dev/null +++ b/packages/binutils/2.23.2/300-001_ld_makefile_patch.patch @@ -0,0 +1,24 @@ +diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.am binutils-2.17.50.0.17/ld/Makefile.am +--- binutils-2.17.50.0.17.oorig/ld/Makefile.am 2007-06-18 19:29:29.000000000 +0200 ++++ binutils-2.17.50.0.17/ld/Makefile.am 2007-06-25 10:00:36.000000000 +0200 +@@ -18,7 +18,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.in binutils-2.17.50.0.17/ld/Makefile.in +--- binutils-2.17.50.0.17.oorig/ld/Makefile.in 2007-06-18 19:29:29.000000000 +0200 ++++ binutils-2.17.50.0.17/ld/Makefile.in 2007-06-25 10:00:36.000000000 +0200 +@@ -287,7 +287,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.23.2/300-012_check_ldrunpath_length.patch b/packages/binutils/2.23.2/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..df78310 --- /dev/null +++ b/packages/binutils/2.23.2/300-012_check_ldrunpath_length.patch @@ -0,0 +1,21 @@ +diff -Nura binutils-2.21.orig/ld/emultempl/elf32.em binutils-2.21/ld/emultempl/elf32.em +--- binutils-2.21.orig/ld/emultempl/elf32.em 2010-10-29 09:10:36.000000000 -0300 ++++ binutils-2.21/ld/emultempl/elf32.em 2010-12-10 09:26:56.746102724 -0300 +@@ -1270,6 +1270,8 @@ + && command_line.rpath == NULL) + { + lib_path = (const char *) getenv ("LD_RUN_PATH"); ++ if ((lib_path) && (strlen (lib_path) == 0)) ++ lib_path = NULL; + if (gld${EMULATION_NAME}_search_needed (lib_path, &n, + force)) + break; +@@ -1497,6 +1499,8 @@ + rpath = command_line.rpath; + if (rpath == NULL) + rpath = (const char *) getenv ("LD_RUN_PATH"); ++ if ((rpath) && (strlen (rpath) == 0)) ++ rpath = NULL; + + for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.23.2/310-fix-gold-pthreads-typo.patch b/packages/binutils/2.23.2/310-fix-gold-pthreads-typo.patch new file mode 100644 index 0000000..f2e6ff2 --- /dev/null +++ b/packages/binutils/2.23.2/310-fix-gold-pthreads-typo.patch @@ -0,0 +1,14 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 +@@ -102,9 +102,9 @@ + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); + #ifdef PTHREAD_MUTEX_ADAPTIVE_NP +- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); ++ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) +- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); ++ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); + #endif + + err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/packages/binutils/2.23.2/500-sysroot.patch b/packages/binutils/2.23.2/500-sysroot.patch new file mode 100644 index 0000000..e49c795 --- /dev/null +++ b/packages/binutils/2.23.2/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -308,18 +308,25 @@ + directory first. */ + if (! entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.23.2/600-poison-system-directories.patch b/packages/binutils/2.23.2/600-poison-system-directories.patch new file mode 100644 index 0000000..780e48e --- /dev/null +++ b/packages/binutils/2.23.2/600-poison-system-directories.patch @@ -0,0 +1,279 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +Signed-off-by: Thomas Petazzoni + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.in (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +Index: b/ld/config.in +=================================================================== +--- a/ld/config.in ++++ b/ld/config.in +@@ -11,6 +11,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +Index: b/ld/configure +=================================================================== +--- a/ld/configure ++++ b/ld/configure +@@ -773,6 +773,7 @@ + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_werror +@@ -1428,6 +1429,8 @@ + (and sometimes confusing) to the casual installer + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -4338,7 +4341,18 @@ + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +Index: b/ld/configure.in +=================================================================== +--- a/ld/configure.in ++++ b/ld/configure.in +@@ -70,6 +70,16 @@ + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +Index: b/ld/ldfile.c +=================================================================== +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -116,6 +116,23 @@ + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +Index: b/ld/ld.h +=================================================================== +--- a/ld/ld.h ++++ b/ld/ld.h +@@ -203,6 +203,14 @@ + /* If TRUE we'll just print the default output on stdout. */ + bfd_boolean print_output_format; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +Index: b/ld/ldmain.c +=================================================================== +--- a/ld/ldmain.c ++++ b/ld/ldmain.c +@@ -265,6 +265,8 @@ + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; + command_line.disable_target_specific_optimizations = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +Index: b/ld/ld.texinfo +=================================================================== +--- a/ld/ld.texinfo ++++ b/ld/ld.texinfo +@@ -2154,6 +2154,18 @@ + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +Index: b/ld/lexsup.c +=================================================================== +--- a/ld/lexsup.c ++++ b/ld/lexsup.c +@@ -498,6 +498,14 @@ + TWO_DASHES }, + { {"wrap", required_argument, NULL, OPTION_WRAP}, + '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -510,6 +518,7 @@ + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1427,9 +1436,21 @@ + einfo (_("%P%X: --hash-size needs a numeric argument\n")); + } + break; ++ ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; + } + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); +Index: b/ld/ldlex.h +=================================================================== +--- a/ld/ldlex.h ++++ b/ld/ldlex.h +@@ -136,6 +136,8 @@ + #endif /* ENABLE_PLUGINS */ + OPTION_DEFAULT_SCRIPT, + OPTION_PRINT_OUTPUT_FORMAT, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ diff --git a/packages/binutils/2.23.2/900-xtensa-trampolines.patch b/packages/binutils/2.23.2/900-xtensa-trampolines.patch new file mode 100644 index 0000000..b5b934f --- /dev/null +++ b/packages/binutils/2.23.2/900-xtensa-trampolines.patch @@ -0,0 +1,846 @@ +From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001 +From: David Weatherford +Date: Fri, 21 Mar 2014 11:53:42 +0000 +Subject: [PATCH] Add support to the Xtensa target for creating trampolines for + out-of-range branches. + + * tc-xtensa.c (xtensa_check_frag_count, xtensa_create_trampoline_frag) + (xtensa_maybe_create_trampoline_frag, init_trampoline_frag) + (find_trampoline_seg, search_trampolines, get_best_trampoline) + (check_and_update_trampolines, add_jump_to_trampoline) + (dump_trampolines): New function. + (md_parse_option): Add cases for --[no-]trampolines options. + (md_assemble, finish_vinsn, xtensa_end): Add call to + xtensa_check_frag_count. + (xg_assemble_vliw_tokens): Add call to + xtensa_maybe_create_trampoline_frag. + (xtensa_relax_frag): Relax fragments with RELAX_TRAMPOLINE state. + (relax_frag_immed): Relax jump instructions that cannot reach its + target. + * tc-xtensa.h (xtensa_relax_statesE::RELAX_TRAMPOLINE): New relax + state. + + * as.texinfo: Document --[no-]trampolines command-line options. + * c-xtensa.texi: Document trampolines relaxation and command line + options. + + * frags.c (get_frag_count, clear_frag_count): New function. + (frag_alloc): Increment totalfrags counter. + * frags.h (get_frag_count, clear_frag_count): New function. + + * all.exp: Add test for trampoline relaxation. + * trampoline.d: Trampoline relaxation expected dump. + * trampoline.s: Trampoline relaxation test source. +--- +Backported from: a82c7d9030b67a6a76a5403d0e1641f9e42141ac +Changes to Changelog files are dropped. + + gas/config/tc-xtensa.c | 558 +++++++++++++++++++++++++++++++++- + gas/config/tc-xtensa.h | 5 + + gas/frags.c | 15 + + gas/frags.h | 3 + + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/trampoline.d | 26 ++ + gas/testsuite/gas/xtensa/trampoline.s | 21 ++ + 11 files changed, 753 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/trampoline.d + create mode 100644 gas/testsuite/gas/xtensa/trampoline.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index fe8ec0f..ea23c96 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -468,6 +468,12 @@ static void xtensa_set_frag_assembly_state (fragS *); + static void finish_vinsn (vliw_insn *); + static bfd_boolean emit_single_op (TInsn *); + static int total_frag_text_expansion (fragS *); ++static bfd_boolean use_trampolines = TRUE; ++static void xtensa_check_frag_count (void); ++static void xtensa_create_trampoline_frag (bfd_boolean); ++static void xtensa_maybe_create_trampoline_frag (void); ++struct trampoline_frag; ++static int init_trampoline_frag (struct trampoline_frag *); + + /* Alignment Functions. */ + +@@ -520,6 +526,7 @@ static void tinsn_from_chars (TInsn *, char *, int); + static void tinsn_immed_from_frag (TInsn *, fragS *, int); + static int get_num_stack_text_bytes (IStack *); + static int get_num_stack_literal_bytes (IStack *); ++static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf); + + /* vliw_insn functions. */ + +@@ -687,7 +694,10 @@ enum + option_prefer_l32r, + option_prefer_const16, + +- option_target_hardware ++ option_target_hardware, ++ ++ option_trampolines, ++ option_no_trampolines, + }; + + const char *md_shortopts = ""; +@@ -760,6 +770,9 @@ struct option md_longopts[] = + + { "target-hardware", required_argument, NULL, option_target_hardware }, + ++ { "trampolines", no_argument, NULL, option_trampolines }, ++ { "no-trampolines", no_argument, NULL, option_no_trampolines }, ++ + { NULL, no_argument, NULL, 0 } + }; + +@@ -940,6 +953,14 @@ md_parse_option (int c, char *arg) + directive_state[directive_transform] = FALSE; + return 1; + ++ case option_trampolines: ++ use_trampolines = TRUE; ++ return 1; ++ ++ case option_no_trampolines: ++ use_trampolines = FALSE; ++ return 1; ++ + default: + return 0; + } +@@ -963,7 +984,9 @@ Xtensa options:\n\ + flix bundles\n\ + --no-allow-flix neither allow hand-written nor generate\n\ + flix bundles\n\ +- --rename-section old=new Rename section 'old' to 'new'\n", stream); ++ --rename-section old=new Rename section 'old' to 'new'\n\ ++ --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ ++ when jumps do not reach their targets\n", stream); + } + + +@@ -5568,6 +5591,8 @@ md_assemble (char *str) + + /* We've just emitted a new instruction so clear the list of labels. */ + xtensa_clear_insn_labels (); ++ ++ xtensa_check_frag_count (); + } + + +@@ -6372,6 +6397,8 @@ finish_vinsn (vliw_insn *vinsn) + xg_assemble_vliw_tokens (vinsn); + + xg_clear_vinsn (vinsn); ++ ++ xtensa_check_frag_count (); + } + + +@@ -7140,6 +7167,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + RELAX_UNREACHABLE, + frag_now->fr_symbol, frag_now->fr_offset, NULL); + xtensa_set_frag_assembly_state (frag_now); ++ xtensa_maybe_create_trampoline_frag (); + } + else if (is_branch && do_align_targets ()) + { +@@ -7222,9 +7250,164 @@ xtensa_end (void) + xtensa_sanity_check (); + + xtensa_add_config_info (); ++ ++ xtensa_check_frag_count (); ++} ++ ++ ++struct trampoline_frag ++{ ++ struct trampoline_frag *next; ++ bfd_boolean needs_jump_around; ++ fragS *fragP; ++ fixS *fixP; ++}; ++ ++struct trampoline_seg ++{ ++ struct trampoline_seg *next; ++ asection *seg; ++ struct trampoline_frag trampoline_list; ++}; ++ ++static struct trampoline_seg trampoline_seg_list; ++#define J_RANGE (128 * 1024) ++ ++static int unreachable_count = 0; ++ ++ ++static void ++xtensa_maybe_create_trampoline_frag (void) ++{ ++ if (!use_trampolines) ++ return; ++ ++ /* We create an area for possible trampolines every 10 unreachable frags. ++ These are preferred over the ones not preceded by an unreachable frag, ++ because we don't have to jump around them. This function is called after ++ each RELAX_UNREACHABLE frag is created. */ ++ ++ if (++unreachable_count > 10) ++ { ++ xtensa_create_trampoline_frag (FALSE); ++ clear_frag_count (); ++ unreachable_count = 0; ++ } ++} ++ ++static void ++xtensa_check_frag_count (void) ++{ ++ if (!use_trampolines || frag_now->tc_frag_data.is_no_transform) ++ return; ++ ++ /* We create an area for possible trampolines every 8000 frags or so. This ++ is an estimate based on the max range of a "j" insn (+/-128K) divided ++ by a typical frag byte count (16), minus a few for safety. This function ++ is called after each source line is processed. */ ++ ++ if (get_frag_count () > 8000) ++ { ++ xtensa_create_trampoline_frag (TRUE); ++ clear_frag_count (); ++ unreachable_count = 0; ++ } ++} ++ ++static xtensa_insnbuf trampoline_buf = NULL; ++static xtensa_insnbuf trampoline_slotbuf = NULL; ++ ++#define TRAMPOLINE_FRAG_SIZE 3000 ++ ++static void ++xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) ++{ ++ /* Emit a frag where we can place intermediate jump instructions, ++ in case we need to jump farther than 128K bytes. ++ Each jump instruction takes three bytes. ++ We allocate enough for 1000 trampolines in each frag. ++ If that's not enough, oh well. */ ++ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ struct trampoline_frag *tf; ++ char *varP; ++ fragS *fragP; ++ int size = TRAMPOLINE_FRAG_SIZE; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ if (ts->seg == now_seg) ++ break; ++ } ++ ++ if (ts == NULL) ++ { ++ ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1); ++ ts->next = trampoline_seg_list.next; ++ trampoline_seg_list.next = ts; ++ ts->seg = now_seg; ++ } ++ ++ frag_wane (frag_now); ++ frag_new (0); ++ xtensa_set_frag_assembly_state (frag_now); ++ varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL); ++ fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG); ++ if (trampoline_buf == NULL) ++ { ++ trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa); ++ trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa); ++ } ++ tf = (struct trampoline_frag *)xmalloc(sizeof (struct trampoline_frag)); ++ tf->next = ts->trampoline_list.next; ++ ts->trampoline_list.next = tf; ++ tf->needs_jump_around = needs_jump_around; ++ tf->fragP = fragP; ++ tf->fixP = NULL; ++} ++ ++ ++static struct trampoline_seg * ++find_trampoline_seg (asection *seg) ++{ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ if (ts->seg == seg) ++ return ts; ++ } ++ ++ return NULL; + } + + ++void dump_trampolines (void); ++ ++void ++dump_trampolines (void) ++{ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ asection *seg = ts->seg; ++ ++ if (seg == NULL) ++ continue; ++ fprintf(stderr, "SECTION %s\n", seg->name); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ for ( ; tf; tf = tf->next) ++ { ++ if (tf->fragP == NULL) ++ continue; ++ fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n", ++ (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix, ++ tf->needs_jump_around ? "T" : "F"); ++ } ++ } ++} ++ + static void + xtensa_cleanup_align_frags (void) + { +@@ -8708,6 +8891,149 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + new_stretch += relax_frag_for_align (fragP, stretch); + break; + ++ case RELAX_TRAMPOLINE: ++ if (fragP->tc_frag_data.relax_seen) ++ { ++ segment_info_type *seginfo = seg_info (now_seg); ++ fragS *fP; /* The out-of-range jump. */ ++ fixS *fixP; ++ ++ /* Scan for jumps that will not reach. */ ++ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ { ++ symbolS *s = fixP->fx_addsy; ++ xtensa_opcode opcode; ++ int target; ++ int addr; ++ int delta; ++ ++ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || ++ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) ++ continue; ++ xtensa_insnbuf_from_chars (isa, trampoline_buf, ++ (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, ++ 0); ++ fmt = xtensa_format_decode (isa, trampoline_buf); ++ gas_assert (fmt != XTENSA_UNDEFINED); ++ slot = fixP->tc_fix_data.slot; ++ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); ++ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); ++ if (opcode != xtensa_j_opcode) ++ continue; ++ target = S_GET_VALUE (s); ++ addr = fixP->fx_frag->fr_address; ++ delta = target - addr + stretch; ++ if (delta > J_RANGE || delta < -1 * J_RANGE) ++ { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ struct trampoline_frag *prev = &ts->trampoline_list; ++ int lower = (target < addr) ? target : addr; ++ int upper = (target > addr) ? target : addr; ++ int midpoint = lower + (upper - lower) / 2; ++ ++ if ((upper - lower) > 2 * J_RANGE) ++ { ++ /* One trampoline won't suffice; we need multiple jumps. ++ Jump to the trampoline that's farthest, but still in ++ range relative to the original "j" instruction. */ ++ for ( ; tf; prev = tf, tf = tf->next ) ++ { ++ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ; ++ ++ if (addr == lower) ++ { ++ /* Forward jump. */ ++ if (this_addr - addr < J_RANGE) ++ break; ++ } ++ else ++ { ++ /* Backward jump. */ ++ if (next_addr == 0 || addr - next_addr > J_RANGE) ++ break; ++ } ++ } ++ } ++ else ++ { ++ struct trampoline_frag *best_tf = NULL; ++ int best_delta = 0; ++ ++ for ( ; tf; prev = tf, tf = tf->next ) ++ { ++ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ int this_delta = abs (this_addr - midpoint); ++ ++ if (!best_tf || this_delta < best_delta) ++ { ++ best_tf = tf; ++ best_delta = this_delta; ++ } ++ } ++ tf = best_tf; ++ } ++ if (tf->fragP == fragP) ++ { ++ int trampaddr = fragP->fr_address + fragP->fr_fix; ++ ++ if (abs (addr - trampaddr) < J_RANGE) ++ { /* The trampoline is in range of original; fix it! */ ++ fixS *newfixP; ++ int offset; ++ TInsn insn; ++ symbolS *lsym; ++ ++ new_stretch += init_trampoline_frag (tf); ++ offset = fragP->fr_fix; /* Where to assemble the j insn. */ ++ lsym = fragP->fr_symbol; ++ fP = fixP->fx_frag; ++ /* Assemble a jump to the target label here. */ ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], lsym, offset); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3); ++ fragP->fr_fix += 3; ++ fragP->fr_var -= 3; ++ /* Add a fix-up for the original j insn. */ ++ newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type); ++ newfixP->fx_no_overflow = 1; ++ newfixP->tc_fix_data.X_add_symbol = lsym; ++ newfixP->tc_fix_data.X_add_number = offset; ++ newfixP->tc_fix_data.slot = slot; ++ /* Move the fix-up from the original j insn to this one. */ ++ fixP->fx_frag = fragP; ++ fixP->fx_where = fragP->fr_fix - 3; ++ fixP->tc_fix_data.slot = 0; ++ /* Adjust the jump around this trampoline (if present). */ ++ if (tf->fixP != NULL) ++ { ++ tf->fixP->fx_offset += 3; ++ } ++ new_stretch += 3; ++ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ ++ /* Do we have room for more? */ ++ if (fragP->fr_var < 3) ++ { /* No, convert to fill. */ ++ frag_wane (fragP); ++ fragP->fr_subtype = 0; ++ /* Remove from the trampoline_list. */ ++ prev->next = tf->next; ++ break; ++ } ++ } ++ } ++ } ++ } ++ } ++ break; ++ + default: + as_bad (_("bad relaxation state")); + } +@@ -9146,6 +9472,200 @@ bytes_to_stretch (fragS *this_frag, + } + + ++static struct trampoline_frag * ++search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) ++{ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL; ++ struct trampoline_frag *best_tf = NULL; ++ int best_delta = 0; ++ int best_addr = 0; ++ symbolS *sym = tinsn->tok[0].X_add_symbol; ++ offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; ++ offsetT addr = fragP->fr_address; ++ offsetT lower = (addr < target) ? addr : target; ++ offsetT upper = (addr > target) ? addr : target; ++ int delta = upper - lower; ++ offsetT midpoint = lower + delta / 2; ++ int this_delta = -1; ++ int this_addr = -1; ++ ++ if (delta > 2 * J_RANGE) ++ { ++ /* One trampoline won't do; we need multiple. ++ Choose the farthest trampoline that's still in range of the original ++ and let a later pass finish the job. */ ++ for ( ; tf; tf = tf->next) ++ { ++ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0; ++ ++ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ if (lower == addr) ++ { ++ /* Forward jump. */ ++ if (this_addr - addr < J_RANGE) ++ break; ++ } ++ else ++ { ++ /* Backward jump. */ ++ if (next_addr == 0 || addr - next_addr > J_RANGE) ++ break; ++ } ++ if (abs (addr - this_addr) < J_RANGE) ++ return tf; ++ ++ return NULL; ++ } ++ } ++ for ( ; tf; tf = tf->next) ++ { ++ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ this_delta = abs (this_addr - midpoint); ++ if (unreachable_only && tf->needs_jump_around) ++ continue; ++ if (!best_tf || this_delta < best_delta) ++ { ++ best_tf = tf; ++ best_delta = this_delta; ++ best_addr = this_addr; ++ } ++ } ++ ++ if (best_tf && ++ best_delta < J_RANGE && ++ abs(best_addr - lower) < J_RANGE && ++ abs(best_addr - upper) < J_RANGE) ++ return best_tf; ++ ++ return NULL; /* No suitable trampoline found. */ ++} ++ ++ ++static struct trampoline_frag * ++get_best_trampoline (TInsn *tinsn, fragS *fragP) ++{ ++ struct trampoline_frag *tf = NULL; ++ ++ tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ ++ ++ if (tf == NULL) ++ tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */ ++ ++ return tf; ++} ++ ++ ++static void ++check_and_update_trampolines (void) ++{ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ struct trampoline_frag *prev = &ts->trampoline_list; ++ ++ for ( ; tf; prev = tf, tf = tf->next) ++ { ++ if (tf->fragP->fr_var < 3) ++ { ++ frag_wane (tf->fragP); ++ prev->next = tf->next; ++ tf->fragP = NULL; ++ } ++ } ++} ++ ++ ++static int ++init_trampoline_frag (struct trampoline_frag *trampP) ++{ ++ fragS *fp = trampP->fragP; ++ int growth = 0; ++ ++ if (fp->fr_fix == 0) ++ { ++ symbolS *lsym; ++ char label[10 + 2 * sizeof(fp)]; ++ sprintf (label, ".L0_TR_%p", fp); ++ ++ lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); ++ fp->fr_symbol = lsym; ++ if (trampP->needs_jump_around) ++ { ++ /* Add a jump around this block of jumps, in case ++ control flows into this block. */ ++ fixS *fixP; ++ TInsn insn; ++ xtensa_format fmt; ++ xtensa_isa isa = xtensa_default_isa; ++ ++ fp->tc_frag_data.is_insn = 1; ++ /* Assemble a jump insn. */ ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], lsym, 3); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3); ++ fp->fr_fix += 3; ++ fp->fr_var -= 3; ++ growth = 3; ++ fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); ++ trampP->fixP = fixP; ++ } ++ } ++ return growth; ++} ++ ++ ++static int ++add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) ++{ ++ fragS *tramp = trampP->fragP; ++ fixS *fixP; ++ int offset = tramp->fr_fix; /* Where to assemble the j insn. */ ++ TInsn insn; ++ symbolS *lsym; ++ symbolS *tsym; ++ int toffset; ++ xtensa_format fmt; ++ xtensa_isa isa = xtensa_default_isa; ++ int growth = 0; ++ ++ lsym = tramp->fr_symbol; ++ /* Assemble a jump to the target label in the trampoline frag. */ ++ tsym = origfrag->tc_frag_data.slot_symbols[0]; ++ toffset = origfrag-> tc_frag_data.slot_offsets[0]; ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], tsym, toffset); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3); ++ tramp->fr_fix += 3; ++ tramp->fr_var -= 3; ++ growth = 3; ++ /* add a fix-up for the trampoline jump. */ ++ fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); ++ /* Modify the jump at the start of this trampoline to point past the newly-added jump. */ ++ fixP = trampP->fixP; ++ if (fixP) ++ fixP->fx_offset += 3; ++ /* Modify the original j to point here. */ ++ origfrag->tc_frag_data.slot_symbols[0] = lsym; ++ origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3; ++ /* If trampoline is full, remove it from the list. */ ++ check_and_update_trampolines (); ++ ++ return growth; ++} ++ ++ + static long + relax_frag_immed (segT segP, + fragS *fragP, +@@ -9284,6 +9804,37 @@ relax_frag_immed (segT segP, + if (negatable_branch && istack.ninsn > 1) + update_next_frag_state (fragP); + ++ /* If last insn is a jump, and it cannot reach its target, try to find a trampoline. */ ++ if (istack.ninsn > 2 && ++ istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL && ++ istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN && ++ istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode) ++ { ++ TInsn *jinsn = &istack.insn[istack.ninsn - 2]; ++ ++ if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) ++ { ++ struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP); ++ ++ if (tf) ++ { ++ this_text_diff += init_trampoline_frag (tf); ++ this_text_diff += add_jump_to_trampoline (tf, fragP); ++ } ++ else ++ { ++ /* If target symbol is undefined, assume it will reach once linked. */ ++ expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0]; ++ ++ if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol)) ++ { ++ as_bad_where (fragP->fr_file, fragP->fr_line, ++ _("jump target out of range; no usable trampoline found")); ++ } ++ } ++ } ++ } ++ + return this_text_diff; + } + +@@ -9404,6 +9955,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp) + else + as_bad (_("invalid relaxation fragment result")); + break; ++ ++ case RELAX_TRAMPOLINE: ++ break; + } + + fragp->fr_var = 0; +diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h +index 0bf1240..4672bc6 100644 +--- a/gas/config/tc-xtensa.h ++++ b/gas/config/tc-xtensa.h +@@ -180,6 +180,11 @@ enum xtensa_relax_statesE + prevent the linker from changing the size of any frag between the + section start and the org frag. */ + ++ RELAX_TRAMPOLINE, ++ /* Every few thousand frags, we insert one of these, just in case we may ++ need some space for a trampoline (jump to a jump) because the function ++ has gotten too big. If not needed, it disappears. */ ++ + RELAX_NONE + }; + +diff --git a/gas/frags.c b/gas/frags.c +index 5f68480..e14099d 100644 +--- a/gas/frags.c ++++ b/gas/frags.c +@@ -24,6 +24,20 @@ + + extern fragS zero_address_frag; + extern fragS predefined_address_frag; ++ ++static int totalfrags; ++ ++int ++get_frag_count (void) ++{ ++ return totalfrags; ++} ++ ++void ++clear_frag_count (void) ++{ ++ totalfrags = 0; ++} + + /* Initialization for frag routines. */ + +@@ -70,6 +84,7 @@ frag_alloc (struct obstack *ob) + ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG); + obstack_alignment_mask (ob) = oalign; + memset (ptr, 0, SIZEOF_STRUCT_FRAG); ++ totalfrags++; + return ptr; + } + +diff --git a/gas/frags.h b/gas/frags.h +index 319898f..2f9e1b5 100644 +--- a/gas/frags.h ++++ b/gas/frags.h +@@ -155,4 +155,7 @@ char *frag_var (relax_stateT type, + + bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); + ++int get_frag_count (void); ++void clear_frag_count (void); ++ + #endif /* FRAGS_H */ +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 2b2c294..3683b78 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -98,6 +98,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "pcrel" + run_dump_test "weak-call" + run_dump_test "jlong" ++ run_dump_test "trampoline" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d +new file mode 100644 +index 0000000..b4f65dc +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/trampoline.d +@@ -0,0 +1,26 @@ ++#as: ++#objdump: -d ++#name: trampolines relaxation ++ ++.*: +file format .*xtensa.* ++#... ++.*0:.*j.0x1194c ++.*3:.*j.0x1194f ++.*6:.*j.0x11952 ++.*9:.*j.0x1d4e4 ++#... ++.*11949:.*j.0x11955 ++.*1194c:.*j.0x24a0e ++.*1194f:.*j.0x24a0e ++.*11952:.*j.0x24a11 ++#... ++.*1d4e1:.*j.0x1d4e7 ++.*1d4e4:.*j.0x33462 ++#... ++.*24a0e:.*j.0x24a0e ++.*24a11:.*j.0x24a11 ++#... ++.*3345f:.*ret ++.*33462:.*j.0x49407 ++#... ++.*49407:.*j.0x49407 +diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s +new file mode 100644 +index 0000000..259a3bb +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/trampoline.s +@@ -0,0 +1,21 @@ ++ .text ++ j 1f ++ j 1f ++ j 2f ++ j 3f ++ .rep 25000 ++99: ++ and a2, a2, a3 ++ bne a2, a3, 99b ++ .endr ++1: ++ j 1b ++2: ++ j 2b ++ ++ .rep 25000 ++ and a2, a2, a3 ++ _ret ++ .endr ++3: ++ j 3b +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch b/packages/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch new file mode 100644 index 0000000..e1c2d85 --- /dev/null +++ b/packages/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch @@ -0,0 +1,51 @@ +From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 15 Apr 2014 19:12:46 +0400 +Subject: [PATCH] Fix alignment for the first section frag on xtensa + +Linking object files produced by partial linking with link-time +relaxation enabled sometimes fails with the following error message: + +dangerous relocation: call8: misaligned call target: (.text.unlikely+0x63) + +This happens because no basic block with an XTENSA_PROP_ALIGN flag in the +property table is generated for the first basic block, even if the +.align directive is present. +It was believed that the first frag alignment could be derived from the +section alignment, but this was not implemented for the partial linking +case: after partial linking first frag of a section may become not +first, but no additional alignment frag is inserted before it. +Basic block for such frag may be merged with previous basic block into +extended basic block during relaxation pass losing its alignment +restrictions. + +Fix this by always recording alignment for the first section frag. + +2014-04-22 Max Filippov + +gas/ + * config/tc-xtensa.c (xtensa_handle_align): record alignment for the + first section frag. + +--- +Backported from: a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 +Changes to Changelog files and tests are dropped. + + gas/config/tc-xtensa.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index ea23c96..58ace38 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5609,7 +5609,6 @@ xtensa_handle_align (fragS *fragP) + && ! fragP->tc_frag_data.is_literal + && (fragP->fr_type == rs_align + || fragP->fr_type == rs_align_code) +- && fragP->fr_address + fragP->fr_fix > 0 + && fragP->fr_offset > 0 + && now_seg != bss_section) + { +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch b/packages/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch new file mode 100644 index 0000000..ba24f4e --- /dev/null +++ b/packages/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch @@ -0,0 +1,133 @@ +From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001 +From: Volodymyr Arbatov +Date: Mon, 6 May 2013 09:43:21 -0800 +Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets. + +R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such. +Add testcase that examines ld behaviour on R_XTENSA_DIFF relocation +changing sign during relaxation. + +2014-05-02 Volodymyr Arbatov + David Weatherford + Max Filippov + +bfd/ + * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as + signed. + +gas/ + * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF* + fixups as signed. +--- +Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6 +Changes to Changelog files and tests are dropped. + + bfd/elf32-xtensa.c | 32 ++++++++++++----------- + gas/config/tc-xtensa.c | 3 +++ + 2 files changed, 20 insertions(+), 15 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index edb04b4..8818d67 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] = + FALSE, 0, 0, FALSE), + + /* Relocations for supporting difference of symbols. */ +- HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE), +- HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE), +- HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE), + + /* General immediate operand relocations. */ +@@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + || r_type == R_XTENSA_DIFF16 + || r_type == R_XTENSA_DIFF32) + { +- bfd_vma diff_value = 0, new_end_offset, diff_mask = 0; ++ bfd_signed_vma diff_value = 0; ++ bfd_vma new_end_offset, diff_mask = 0; + + if (bfd_get_section_limit (abfd, sec) < old_source_offset) + { +@@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + { + case R_XTENSA_DIFF8: + diff_value = +- bfd_get_8 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_8 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: + diff_value = +- bfd_get_16 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_16 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: + diff_value = +- bfd_get_32 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_32 (abfd, &contents[old_source_offset]); + break; + } + +@@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + switch (r_type) + { + case R_XTENSA_DIFF8: +- diff_mask = 0xff; +- bfd_put_8 (abfd, diff_value, ++ diff_mask = 0x7f; ++ bfd_put_signed_8 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: +- diff_mask = 0xffff; +- bfd_put_16 (abfd, diff_value, ++ diff_mask = 0x7fff; ++ bfd_put_signed_16 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: +- diff_mask = 0xffffffff; +- bfd_put_32 (abfd, diff_value, ++ diff_mask = 0x7fffffff; ++ bfd_put_signed_32 (abfd, diff_value, + &contents[old_source_offset]); + break; + } + +- /* Check for overflow. */ +- if ((diff_value & ~diff_mask) != 0) ++ /* Check for overflow. Sign bits must be all zeroes or all ones */ ++ if ((diff_value & ~diff_mask) != 0 && ++ (diff_value & ~diff_mask) != (-1 & ~diff_mask)) + { + (*link_info->callbacks->reloc_dangerous) + (link_info, _("overflow after relaxation"), +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 58ace38..7547c0a0 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; ++ fixP->fx_signed = 1; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; ++ fixP->fx_signed = 1; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; ++ fixP->fx_signed = 1; + break; + default: + break; +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch b/packages/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch new file mode 100644 index 0000000..6a0846e --- /dev/null +++ b/packages/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch @@ -0,0 +1,47 @@ +From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 10 Jul 2014 01:47:33 +0400 +Subject: [PATCH] Fix xtensa ld segfault when linking linux modules + +is_inconsistent_linkonce_section makes an assumption that section name +that starts with ".gnu.linkonce.prop." has one more dot in its suffix. +However gas generates such section name by insertion of "prop." right +after ".gnu.linkonce." part of the name of the original section. So, for +section named ".gnu.linkonce.this_module" corresponding property section +name does not satisfy the assumption. Such section names are common in +linux modules. This bug was exposed by the patch "a35d5e8 Fix alignment +for the first section frag on xtensa", that makes gas produce property +section for each section that has ".align" directive in it. + +Use suffix that immediately follows ".gnu.linkonce.prop." when there are +no more dots following it. + +2014-07-10 Max Filippov + +ld/ + * emultempl/xtensaelf.em (is_inconsistent_linkonce_section): + correctly handle missing dot in section name after + ".gnu.linkonce.prop.". +--- +Backported from: e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 +Changes to ld/ChangeLog file are dropped. + + ld/emultempl/xtensaelf.em | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em +index 151eea4..948d18d 100644 +--- a/ld/emultempl/xtensaelf.em ++++ b/ld/emultempl/xtensaelf.em +@@ -1310,7 +1310,7 @@ is_inconsistent_linkonce_section (asection *sec) + for Tensilica's XCC compiler. */ + name = sec_name + linkonce_len; + if (CONST_STRNEQ (name, "prop.")) +- name = strchr (name + 5, '.') + 1; ++ name = strchr (name + 5, '.') ? strchr (name + 5, '.') + 1 : name + 5; + else if (name[1] == '.' + && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h')) + name += 2; +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/packages/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch new file mode 100644 index 0000000..dba7620 --- /dev/null +++ b/packages/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch @@ -0,0 +1,79 @@ +From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 +From: Sterling Augustine +Date: Tue, 25 Jan 2011 13:59:13 -0800 +Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation + bug + +During link-time relaxation distance between cross-section call site and +its target may grow, producing 'call target out of range' error for +relaxed calls. Be more conservative when calculating whether or not a +callx can be converted to a straight call. + +2014-09-23 Sterling Augustine + +bfd/ + * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section + call relaxation use furthermost addresses where call source and + destination can be to check whether it's in the range of a direct + call. + +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 09862e3..e32496a 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, + || is_reloc_sym_weak (abfd, irel))) + return FALSE; + +- self_address = (sec->output_section->vma +- + sec->output_offset + irel->r_offset + 3); +- dest_address = (target_sec->output_section->vma +- + target_sec->output_offset + target_offset); ++ if (target_sec->output_section != sec->output_section) ++ { ++ /* If the two sections are sufficiently far away that relaxation ++ might take the call out of range, we can't simplify. For ++ example, a positive displacement call into another memory ++ could get moved to a lower address due to literal removal, ++ but the destination won't move, and so the displacment might ++ get larger. ++ ++ If the displacement is negative, assume the destination could ++ move as far back as the start of the output section. The ++ self_address will be at least as far into the output section ++ as it is prior to relaxation. ++ ++ If the displacement is postive, assume the destination will be in ++ it's pre-relaxed location (because relaxation only makes sections ++ smaller). The self_address could go all the way to the beginning ++ of the output section. */ ++ ++ dest_address = target_sec->output_section->vma; ++ self_address = sec->output_section->vma; ++ ++ if (sec->output_section->vma > target_sec->output_section->vma) ++ self_address += sec->output_offset + irel->r_offset + 3; ++ else ++ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); ++ /* Call targets should be four-byte aligned. */ ++ dest_address = (dest_address + 3) & ~3; ++ } ++ else ++ { ++ ++ self_address = (sec->output_section->vma ++ + sec->output_offset + irel->r_offset + 3); ++ dest_address = (target_sec->output_section->vma ++ + target_sec->output_offset + target_offset); ++ } + + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch b/packages/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch new file mode 100644 index 0000000..8aeb064 --- /dev/null +++ b/packages/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch @@ -0,0 +1,90 @@ +From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 25 Nov 2014 21:33:21 +0300 +Subject: [PATCH] Fix trampolines search code for conditional branches + +For conditional branches that need more than one trampoline to reach its +target assembler couldn't always find suitable trampoline because +post-loop condition check was placed inside the loop, resulting in +premature loop termination. Move check outside the loop. + +This fixes the following build errors seen when assembling huge files +produced by gcc: + Error: jump target out of range; no usable trampoline found + Error: operand 1 of 'j' has out of range value '307307' + +2014-11-25 Max Filippov + +gas/ + * config/tc-xtensa.c (search_trampolines): Move post-loop + condition check outside the search loop. + +gas/testsuite/ + * gas/xtensa/trampoline.d: Add expected output for branches. + * gas/xtensa/trampoline.s: Add test case for branches. + +Signed-off-by: Max Filippov +--- +Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 +Changes to ChangeLogs are dropped. + + gas/config/tc-xtensa.c | 8 ++++---- + gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ + gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index d11b0c7..f23ccf8 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) + if (next_addr == 0 || addr - next_addr > J_RANGE) + break; + } +- if (abs (addr - this_addr) < J_RANGE) +- return tf; +- +- return NULL; + } ++ if (abs (addr - this_addr) < J_RANGE) ++ return tf; ++ ++ return NULL; + } + for ( ; tf; tf = tf->next) + { +diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d +index b4f65dc..5ae32a6 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.d ++++ b/gas/testsuite/gas/xtensa/trampoline.d +@@ -24,3 +24,12 @@ + .*33462:.*j.0x49407 + #... + .*49407:.*j.0x49407 ++.*4940a:.*beqz.n.a2,.0x4940f ++.*4940c:.*j.0x693d1 ++#... ++.*693d1:.*j.0x7ddd4 ++#... ++.*7ddd4:.*j.0x927f5 ++#... ++.*927f5:.*j.0x927f5 ++#... +diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s +index 259a3bb..4465786 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.s ++++ b/gas/testsuite/gas/xtensa/trampoline.s +@@ -19,3 +19,10 @@ + .endr + 3: + j 3b ++ bnez a2, 4f ++ .rep 50000 ++ and a2, a2, a3 ++ _ret ++ .endr ++4: ++ j 4b +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/packages/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch new file mode 100644 index 0000000..9ad6b3b --- /dev/null +++ b/packages/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch @@ -0,0 +1,57 @@ +From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 14 May 2015 05:22:55 +0300 +Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections + +elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were +made local, that results in link failure with the following message: + + BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line + 3372 in elf_xtensa_finish_dynamic_sections + +elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by +relocation type. Relocation types are not changed when symbol becomes +local, but its PLT references are added to GOT references and +plt.refcount is set to 0. Such symbol cannot be unreferences in the +elf_xtensa_gc_sweep_hook and its extra references make calculated GOT +relocations section size not match number of GOT relocations. + +Fix it by treating PLT reference as GOT reference when plt.refcount is +not positive. + +2015-05-14 Max Filippov +bfd/ + * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference + as GOT reference when plt.refcount is not positive. + +Signed-off-by: Max Filippov +--- +Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 +Changes to ChangeLog are dropped. + + bfd/elf32-xtensa.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 53af1c6..2523670 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, + { + if (is_plt) + { ++ /* If the symbol has been localized its plt.refcount got moved ++ to got.refcount. Handle it as GOT. */ + if (h->plt.refcount > 0) + h->plt.refcount--; ++ else ++ is_got = TRUE; + } +- else if (is_got) ++ if (is_got) + { + if (h->got.refcount > 0) + h->got.refcount--; +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/packages/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch new file mode 100644 index 0000000..4a3de2c --- /dev/null +++ b/packages/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch @@ -0,0 +1,56 @@ +From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 17 May 2015 06:46:15 +0300 +Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals + +When --text-section-literals is used and code in the .init or .fini +emits literal in the absence of .literal_position, xtensa_move_literals +segfaults. + +Check that search_frag is non-NULL in the xtensa_move_literals and +report error otherwise. + +2015-05-26 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Check that + search_frag is non-NULL. Report error if literal frag is not + found. + +Signed-off-by: Max Filippov +--- +Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 +Changes to ChangeLog are dropped. + + gas/config/tc-xtensa.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 31c0b6b..18307c1 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) + frchain_to = NULL; + frag_splice = &(frchain_from->frch_root); + +- while (!search_frag->tc_frag_data.literal_frag) ++ while (search_frag && !search_frag->tc_frag_data.literal_frag) + { + gas_assert (search_frag->fr_fix == 0 + || search_frag->fr_type == rs_align); + search_frag = search_frag->fr_next; + } + ++ if (!search_frag) ++ { ++ search_frag = frchain_from->frch_root; ++ as_bad_where (search_frag->fr_file, search_frag->fr_line, ++ _("literal pool location required for text-section-literals; specify with .literal_position")); ++ continue; ++ } ++ + gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype + == RELAX_LITERAL_POOL_BEGIN); + xtensa_switch_section_emit_state (&state, segment->seg, 0); +-- +1.8.1.4 + diff --git a/packages/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch b/packages/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch new file mode 100644 index 0000000..2955e11 --- /dev/null +++ b/packages/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch @@ -0,0 +1,47 @@ +From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 2 Feb 2016 17:11:38 +0300 +Subject: [PATCH] xtensa: fix signedness of gas relocations + +Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation +offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations +substituted for BFD_RELOC_*. This made it impossible to encode arbitrary +8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc +directive. Revert this part and add test. + +gas/ +2016-02-03 Max Filippov + * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* + substitutions for BFD_RELOC_* as unsigned. + +Signed-off-by: Max Filippov +--- + gas/config/tc-xtensa.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index a119871..36a06cc 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + default: + break; +-- +2.1.4 + diff --git a/packages/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch b/packages/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..62bc4b5 --- /dev/null +++ b/packages/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,70 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] xtensa: fix .init/.fini literals moving + +Despite the documentation and the comment in xtensa_move_literals, in +the presence of --text-section-literals and --auto-litpools literals are +moved from the separate literal sections into .init and .fini, because +the check in the xtensa_move_literals is incorrect. + +This moving was broken with introduction of auto litpools: some literals +now may be lost. This happens because literal frags emitted from .init +and .fini are not closed when new .literal_position marks new literal +pool. Then frag_align(2, 0, 0) changes type of the last literal frag to +rs_align. rs_align frags are skipped in the xtensa_move_literals. As a +result fixups against such literals are not moved out of .init.literal/ +.fini.literal sections producing the following assembler error: + + test.S: Warning: fixes not all moved from .init.literal + test.S: Internal error! + +Fix check for .init.literal/.fini.literal in the xtensa_move_literals +and don't let it move literals from there in the presence of +--text-section-literals or --auto-litpools. + +2016-02-17 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 36a06cc..5773634 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -10625,5 +10625,9 @@ xtensa_move_literals (void) + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; ++ const char *init_name = INIT_SECTION_NAME; ++ const char *fini_name = FINI_SECTION_NAME; ++ int init_name_len = strlen(init_name); ++ int fini_name_len = strlen(fini_name); + + mark_literal_frags (literal_head->next); + +@@ -10632,9 +10636,13 @@ xtensa_move_literals (void) + + for (segment = literal_head->next; segment; segment = segment->next) + { ++ const char *seg_name = segment_name (segment->seg); ++ + /* Keep the literals for .init and .fini in separate sections. */ +- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) +- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) ++ if ((!memcmp (seg_name, init_name, init_name_len) && ++ !strcmp (seg_name + init_name_len, ".literal")) || ++ (!memcmp (seg_name, fini_name, fini_name_len) && ++ !strcmp (seg_name + fini_name_len, ".literal"))) + continue; + + frchain_from = seg_info (segment->seg)->frchainP; +-- +2.1.4 + diff --git a/packages/binutils/2.23.2/version.desc b/packages/binutils/2.23.2/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils/2.23.2/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils/2.24/001-fix-enable-install-libiberty-flag.patch b/packages/binutils/2.24/001-fix-enable-install-libiberty-flag.patch new file mode 100644 index 0000000..e408401 --- /dev/null +++ b/packages/binutils/2.24/001-fix-enable-install-libiberty-flag.patch @@ -0,0 +1,46 @@ +From 369be6981b26787b2685e3b8c6da779dae8ce35f Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Mon, 6 Jan 2014 18:15:31 +0000 +Subject: [PATCH] libiberty: fix --enable-install-libiberty flag [PR 56780] + +Commit 199570 fixed the --disable-install-libiberty behavior, but it also +added a bug where the enable path never works because the initial clear +of target_header_dir wasn't deleted. So we end up initializing properly +at the top only to reset it at the end all the time. + +[Arnout: adapt to match 2.24 tarball] +Signed-off-by: Arnout Vandecappelle (Essensium/Mind) + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206367 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + libiberty/configure | 1 - + libiberty/configure.ac | 1 - + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libiberty/configure b/libiberty/configure +index 8ea54da..7bde9b3 100755 +--- a/libiberty/configure ++++ b/libiberty/configure +@@ -5507,7 +5507,6 @@ fi + + setobjs= + CHECK= +-target_header_dir= + if test -n "${with_target_subdir}"; then + + # We are being configured as a target library. AC_REPLACE_FUNCS +diff --git a/libiberty/configure.ac b/libiberty/configure.ac +index 4ad88a9..d6180bc 100644 +--- a/libiberty/configure.ac ++++ b/libiberty/configure.ac +@@ -405,7 +405,6 @@ fi + + setobjs= + CHECK= +-target_header_dir= + if test -n "${with_target_subdir}"; then + + # We are being configured as a target library. AC_REPLACE_FUNCS +-- +1.7.1 + diff --git a/packages/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch b/packages/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch new file mode 100644 index 0000000..7881646 --- /dev/null +++ b/packages/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch @@ -0,0 +1,66 @@ +From: Alan Modra +Date: Fri, 20 Dec 2013 13:27:52 +0000 (+1030) +Subject: Don't segv on cie.initial_instructions[] overflow. +X-Git-Tag: gdb-7.7-release~148 +X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff_plain;h=99d190fac4d2aab238cfc798dc5c28ab41456882 + +Don't segv on cie.initial_instructions[] overflow. + +Don't attempt to merge CIEs with a larger number of insns than will +fit in the buffer. + + * elf-eh-frame.c (cie_eq): Return false when initial_insn_length + is too large. + (cie_compute_hash): Don't exceed bounds of initial_instructions. + (_bfd_elf_parse_eh_frame): Always set initial_insn_length, and + save as much of insns to initial_instructions[] as will fit. +--- + +diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c +index 832a991..4b6e8ea 100644 +--- a/bfd/elf-eh-frame.c ++++ b/bfd/elf-eh-frame.c +@@ -235,6 +235,7 @@ cie_eq (const void *e1, const void *e2) + && c1->lsda_encoding == c2->lsda_encoding + && c1->fde_encoding == c2->fde_encoding + && c1->initial_insn_length == c2->initial_insn_length ++ && c1->initial_insn_length <= sizeof (c1->initial_instructions) + && memcmp (c1->initial_instructions, + c2->initial_instructions, + c1->initial_insn_length) == 0) +@@ -254,6 +255,7 @@ static hashval_t + cie_compute_hash (struct cie *c) + { + hashval_t h = 0; ++ size_t len; + h = iterative_hash_object (c->length, h); + h = iterative_hash_object (c->version, h); + h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h); +@@ -267,7 +269,10 @@ cie_compute_hash (struct cie *c) + h = iterative_hash_object (c->lsda_encoding, h); + h = iterative_hash_object (c->fde_encoding, h); + h = iterative_hash_object (c->initial_insn_length, h); +- h = iterative_hash (c->initial_instructions, c->initial_insn_length, h); ++ len = c->initial_insn_length; ++ if (len > sizeof (c->initial_instructions)) ++ len = sizeof (c->initial_instructions); ++ h = iterative_hash (c->initial_instructions, len, h); + c->hash = h; + return h; + } +@@ -762,11 +767,10 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, + cie->fde_encoding = DW_EH_PE_absptr; + + initial_insn_length = end - buf; +- if (initial_insn_length <= sizeof (cie->initial_instructions)) +- { +- cie->initial_insn_length = initial_insn_length; +- memcpy (cie->initial_instructions, buf, initial_insn_length); +- } ++ cie->initial_insn_length = initial_insn_length; ++ memcpy (cie->initial_instructions, buf, ++ initial_insn_length <= sizeof (cie->initial_instructions) ++ ? initial_insn_length : sizeof (cie->initial_instructions)); + insns = buf; + buf += initial_insn_length; + ENSURE_NO_RELOCS (buf); diff --git a/packages/binutils/2.24/120-sh-conf.patch b/packages/binutils/2.24/120-sh-conf.patch new file mode 100644 index 0000000..d5913e8 --- /dev/null +++ b/packages/binutils/2.24/120-sh-conf.patch @@ -0,0 +1,31 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +diff -durN binutils-2.22.orig/configure binutils-2.22/configure +--- binutils-2.22.orig/configure 2011-08-14 14:28:15.000000000 +0200 ++++ binutils-2.22/configure 2011-12-14 19:49:40.284777434 +0100 +@@ -3570,7 +3570,7 @@ + mips*-*-*) + noconfigdirs="$noconfigdirs gprof" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +diff -durN binutils-2.22.orig/configure.ac binutils-2.22/configure.ac +--- binutils-2.22.orig/configure.ac 2011-11-21 12:58:27.000000000 +0100 ++++ binutils-2.22/configure.ac 2011-12-14 19:49:40.316777436 +0100 +@@ -1006,7 +1006,7 @@ + mips*-*-*) + noconfigdirs="$noconfigdirs gprof" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.24/300-001_ld_makefile_patch.patch b/packages/binutils/2.24/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..4b5888a --- /dev/null +++ b/packages/binutils/2.24/300-001_ld_makefile_patch.patch @@ -0,0 +1,24 @@ +diff -durN binutils-2.22.orig/ld/Makefile.am binutils-2.22/ld/Makefile.am +--- binutils-2.22.orig/ld/Makefile.am 2011-07-22 22:22:37.000000000 +0200 ++++ binutils-2.22/ld/Makefile.am 2011-12-14 19:50:25.760779164 +0100 +@@ -37,7 +37,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff -durN binutils-2.22.orig/ld/Makefile.in binutils-2.22/ld/Makefile.in +--- binutils-2.22.orig/ld/Makefile.in 2011-07-22 22:22:37.000000000 +0200 ++++ binutils-2.22/ld/Makefile.in 2011-12-14 19:50:25.784779163 +0100 +@@ -366,7 +366,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.24/300-012_check_ldrunpath_length.patch b/packages/binutils/2.24/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..b49cc04 --- /dev/null +++ b/packages/binutils/2.24/300-012_check_ldrunpath_length.patch @@ -0,0 +1,21 @@ +diff -durN binutils-2.22.orig/ld/emultempl/elf32.em binutils-2.22/ld/emultempl/elf32.em +--- binutils-2.22.orig/ld/emultempl/elf32.em 2011-11-21 10:29:39.000000000 +0100 ++++ binutils-2.22/ld/emultempl/elf32.em 2011-12-14 19:52:12.880783238 +0100 +@@ -1273,6 +1273,8 @@ + && command_line.rpath == NULL) + { + lib_path = (const char *) getenv ("LD_RUN_PATH"); ++ if ((lib_path) && (strlen (lib_path) == 0)) ++ lib_path = NULL; + if (gld${EMULATION_NAME}_search_needed (lib_path, &n, + force)) + break; +@@ -1500,6 +1502,8 @@ + rpath = command_line.rpath; + if (rpath == NULL) + rpath = (const char *) getenv ("LD_RUN_PATH"); ++ if ((rpath) && (strlen (rpath) == 0)) ++ rpath = NULL; + + for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.24/310-fix-gold-pthreads-typo.patch b/packages/binutils/2.24/310-fix-gold-pthreads-typo.patch new file mode 100644 index 0000000..f2e6ff2 --- /dev/null +++ b/packages/binutils/2.24/310-fix-gold-pthreads-typo.patch @@ -0,0 +1,14 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 +@@ -102,9 +102,9 @@ + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); + #ifdef PTHREAD_MUTEX_ADAPTIVE_NP +- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); ++ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) +- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); ++ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); + #endif + + err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/packages/binutils/2.24/500-sysroot.patch b/packages/binutils/2.24/500-sysroot.patch new file mode 100644 index 0000000..e49c795 --- /dev/null +++ b/packages/binutils/2.24/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -308,18 +308,25 @@ + directory first. */ + if (! entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.24/600-poison-system-directories.patch b/packages/binutils/2.24/600-poison-system-directories.patch new file mode 100644 index 0000000..6a3bf6b --- /dev/null +++ b/packages/binutils/2.24/600-poison-system-directories.patch @@ -0,0 +1,279 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +Signed-off-by: Thomas Petazzoni + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.in (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +Index: b/ld/config.in +=================================================================== +--- a/ld/config.in ++++ b/ld/config.in +@@ -11,6 +11,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +Index: b/ld/configure +=================================================================== +--- a/ld/configure ++++ b/ld/configure +@@ -774,6 +774,7 @@ + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_werror +@@ -1429,6 +1430,8 @@ + (and sometimes confusing) to the casual installer + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -4339,7 +4342,18 @@ + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +Index: b/ld/configure.in +=================================================================== +--- a/ld/configure.in ++++ b/ld/configure.in +@@ -87,6 +87,16 @@ + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +Index: b/ld/ldfile.c +=================================================================== +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -116,6 +116,23 @@ + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +Index: b/ld/ld.h +=================================================================== +--- a/ld/ld.h ++++ b/ld/ld.h +@@ -180,6 +180,14 @@ + /* If TRUE we'll just print the default output on stdout. */ + bfd_boolean print_output_format; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +Index: b/ld/ldmain.c +=================================================================== +--- a/ld/ldmain.c ++++ b/ld/ldmain.c +@@ -266,6 +266,8 @@ + command_line.warn_mismatch = TRUE; + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +Index: b/ld/ld.texinfo +=================================================================== +--- a/ld/ld.texinfo ++++ b/ld/ld.texinfo +@@ -2175,6 +2175,18 @@ + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +Index: b/ld/lexsup.c +=================================================================== +--- a/ld/lexsup.c ++++ b/ld/lexsup.c +@@ -507,6 +507,14 @@ + OPTION_IGNORE_UNRESOLVED_SYMBOL}, + '\0', N_("SYMBOL"), + N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -519,6 +527,7 @@ + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1442,9 +1451,21 @@ + einfo (_("%P%X: --hash-size needs a numeric argument\n")); + } + break; ++ ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; + } + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); +Index: b/ld/ldlex.h +=================================================================== +--- a/ld/ldlex.h ++++ b/ld/ldlex.h +@@ -138,6 +138,8 @@ + OPTION_DEFAULT_SCRIPT, + OPTION_PRINT_OUTPUT_FORMAT, + OPTION_IGNORE_UNRESOLVED_SYMBOL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ diff --git a/packages/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch b/packages/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch new file mode 100644 index 0000000..cea92f3 --- /dev/null +++ b/packages/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch @@ -0,0 +1,42 @@ +From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 +From: Alexey Neyman +Date: Sat, 11 Mar 2017 17:27:09 -0800 +Subject: [PATCH] Fix library paths on PowerPC + +First, need to match against just the CPU name, not the whole triplet. +Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin +triplet. + +Second, it should be testing for $target, not $host. Host may be +little endian by default, and the sysroot directory layout shouldn't +depend on whether it is built on LE or BE machine. + +Signed-off-by: Alexey Neyman +--- + ld/emulparams/elf32ppccommon.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh +index 1f54ef8..d00cf68 100644 +--- a/ld/emulparams/elf32ppccommon.sh ++++ b/ld/emulparams/elf32ppccommon.sh +@@ -44,11 +44,11 @@ fi + + # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. + # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. +-case "$host":"$EMULATION_NAME" in +- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; +- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; +- *le-*:*64*) LIBPATH_SUFFIX=64be ;; +- *le-*:*32*) LIBPATH_SUFFIX=32be ;; ++case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in ++ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; ++ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; ++ *le:*64*) LIBPATH_SUFFIX=64be ;; ++ *le:*32*) LIBPATH_SUFFIX=32be ;; + *:*64lppc*) LIBPATH_SUFFIX=64le ;; + *:*32lppc*) LIBPATH_SUFFIX=32le ;; + *:*64*) LIBPATH_SUFFIX=64 ;; +-- +2.9.3 + diff --git a/packages/binutils/2.24/900-xtensa-trampolines.patch b/packages/binutils/2.24/900-xtensa-trampolines.patch new file mode 100644 index 0000000..b5b934f --- /dev/null +++ b/packages/binutils/2.24/900-xtensa-trampolines.patch @@ -0,0 +1,846 @@ +From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001 +From: David Weatherford +Date: Fri, 21 Mar 2014 11:53:42 +0000 +Subject: [PATCH] Add support to the Xtensa target for creating trampolines for + out-of-range branches. + + * tc-xtensa.c (xtensa_check_frag_count, xtensa_create_trampoline_frag) + (xtensa_maybe_create_trampoline_frag, init_trampoline_frag) + (find_trampoline_seg, search_trampolines, get_best_trampoline) + (check_and_update_trampolines, add_jump_to_trampoline) + (dump_trampolines): New function. + (md_parse_option): Add cases for --[no-]trampolines options. + (md_assemble, finish_vinsn, xtensa_end): Add call to + xtensa_check_frag_count. + (xg_assemble_vliw_tokens): Add call to + xtensa_maybe_create_trampoline_frag. + (xtensa_relax_frag): Relax fragments with RELAX_TRAMPOLINE state. + (relax_frag_immed): Relax jump instructions that cannot reach its + target. + * tc-xtensa.h (xtensa_relax_statesE::RELAX_TRAMPOLINE): New relax + state. + + * as.texinfo: Document --[no-]trampolines command-line options. + * c-xtensa.texi: Document trampolines relaxation and command line + options. + + * frags.c (get_frag_count, clear_frag_count): New function. + (frag_alloc): Increment totalfrags counter. + * frags.h (get_frag_count, clear_frag_count): New function. + + * all.exp: Add test for trampoline relaxation. + * trampoline.d: Trampoline relaxation expected dump. + * trampoline.s: Trampoline relaxation test source. +--- +Backported from: a82c7d9030b67a6a76a5403d0e1641f9e42141ac +Changes to Changelog files are dropped. + + gas/config/tc-xtensa.c | 558 +++++++++++++++++++++++++++++++++- + gas/config/tc-xtensa.h | 5 + + gas/frags.c | 15 + + gas/frags.h | 3 + + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/trampoline.d | 26 ++ + gas/testsuite/gas/xtensa/trampoline.s | 21 ++ + 11 files changed, 753 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/trampoline.d + create mode 100644 gas/testsuite/gas/xtensa/trampoline.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index fe8ec0f..ea23c96 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -468,6 +468,12 @@ static void xtensa_set_frag_assembly_state (fragS *); + static void finish_vinsn (vliw_insn *); + static bfd_boolean emit_single_op (TInsn *); + static int total_frag_text_expansion (fragS *); ++static bfd_boolean use_trampolines = TRUE; ++static void xtensa_check_frag_count (void); ++static void xtensa_create_trampoline_frag (bfd_boolean); ++static void xtensa_maybe_create_trampoline_frag (void); ++struct trampoline_frag; ++static int init_trampoline_frag (struct trampoline_frag *); + + /* Alignment Functions. */ + +@@ -520,6 +526,7 @@ static void tinsn_from_chars (TInsn *, char *, int); + static void tinsn_immed_from_frag (TInsn *, fragS *, int); + static int get_num_stack_text_bytes (IStack *); + static int get_num_stack_literal_bytes (IStack *); ++static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf); + + /* vliw_insn functions. */ + +@@ -687,7 +694,10 @@ enum + option_prefer_l32r, + option_prefer_const16, + +- option_target_hardware ++ option_target_hardware, ++ ++ option_trampolines, ++ option_no_trampolines, + }; + + const char *md_shortopts = ""; +@@ -760,6 +770,9 @@ struct option md_longopts[] = + + { "target-hardware", required_argument, NULL, option_target_hardware }, + ++ { "trampolines", no_argument, NULL, option_trampolines }, ++ { "no-trampolines", no_argument, NULL, option_no_trampolines }, ++ + { NULL, no_argument, NULL, 0 } + }; + +@@ -940,6 +953,14 @@ md_parse_option (int c, char *arg) + directive_state[directive_transform] = FALSE; + return 1; + ++ case option_trampolines: ++ use_trampolines = TRUE; ++ return 1; ++ ++ case option_no_trampolines: ++ use_trampolines = FALSE; ++ return 1; ++ + default: + return 0; + } +@@ -963,7 +984,9 @@ Xtensa options:\n\ + flix bundles\n\ + --no-allow-flix neither allow hand-written nor generate\n\ + flix bundles\n\ +- --rename-section old=new Rename section 'old' to 'new'\n", stream); ++ --rename-section old=new Rename section 'old' to 'new'\n\ ++ --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ ++ when jumps do not reach their targets\n", stream); + } + + +@@ -5568,6 +5591,8 @@ md_assemble (char *str) + + /* We've just emitted a new instruction so clear the list of labels. */ + xtensa_clear_insn_labels (); ++ ++ xtensa_check_frag_count (); + } + + +@@ -6372,6 +6397,8 @@ finish_vinsn (vliw_insn *vinsn) + xg_assemble_vliw_tokens (vinsn); + + xg_clear_vinsn (vinsn); ++ ++ xtensa_check_frag_count (); + } + + +@@ -7140,6 +7167,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + RELAX_UNREACHABLE, + frag_now->fr_symbol, frag_now->fr_offset, NULL); + xtensa_set_frag_assembly_state (frag_now); ++ xtensa_maybe_create_trampoline_frag (); + } + else if (is_branch && do_align_targets ()) + { +@@ -7222,9 +7250,164 @@ xtensa_end (void) + xtensa_sanity_check (); + + xtensa_add_config_info (); ++ ++ xtensa_check_frag_count (); ++} ++ ++ ++struct trampoline_frag ++{ ++ struct trampoline_frag *next; ++ bfd_boolean needs_jump_around; ++ fragS *fragP; ++ fixS *fixP; ++}; ++ ++struct trampoline_seg ++{ ++ struct trampoline_seg *next; ++ asection *seg; ++ struct trampoline_frag trampoline_list; ++}; ++ ++static struct trampoline_seg trampoline_seg_list; ++#define J_RANGE (128 * 1024) ++ ++static int unreachable_count = 0; ++ ++ ++static void ++xtensa_maybe_create_trampoline_frag (void) ++{ ++ if (!use_trampolines) ++ return; ++ ++ /* We create an area for possible trampolines every 10 unreachable frags. ++ These are preferred over the ones not preceded by an unreachable frag, ++ because we don't have to jump around them. This function is called after ++ each RELAX_UNREACHABLE frag is created. */ ++ ++ if (++unreachable_count > 10) ++ { ++ xtensa_create_trampoline_frag (FALSE); ++ clear_frag_count (); ++ unreachable_count = 0; ++ } ++} ++ ++static void ++xtensa_check_frag_count (void) ++{ ++ if (!use_trampolines || frag_now->tc_frag_data.is_no_transform) ++ return; ++ ++ /* We create an area for possible trampolines every 8000 frags or so. This ++ is an estimate based on the max range of a "j" insn (+/-128K) divided ++ by a typical frag byte count (16), minus a few for safety. This function ++ is called after each source line is processed. */ ++ ++ if (get_frag_count () > 8000) ++ { ++ xtensa_create_trampoline_frag (TRUE); ++ clear_frag_count (); ++ unreachable_count = 0; ++ } ++} ++ ++static xtensa_insnbuf trampoline_buf = NULL; ++static xtensa_insnbuf trampoline_slotbuf = NULL; ++ ++#define TRAMPOLINE_FRAG_SIZE 3000 ++ ++static void ++xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) ++{ ++ /* Emit a frag where we can place intermediate jump instructions, ++ in case we need to jump farther than 128K bytes. ++ Each jump instruction takes three bytes. ++ We allocate enough for 1000 trampolines in each frag. ++ If that's not enough, oh well. */ ++ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ struct trampoline_frag *tf; ++ char *varP; ++ fragS *fragP; ++ int size = TRAMPOLINE_FRAG_SIZE; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ if (ts->seg == now_seg) ++ break; ++ } ++ ++ if (ts == NULL) ++ { ++ ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1); ++ ts->next = trampoline_seg_list.next; ++ trampoline_seg_list.next = ts; ++ ts->seg = now_seg; ++ } ++ ++ frag_wane (frag_now); ++ frag_new (0); ++ xtensa_set_frag_assembly_state (frag_now); ++ varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL); ++ fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG); ++ if (trampoline_buf == NULL) ++ { ++ trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa); ++ trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa); ++ } ++ tf = (struct trampoline_frag *)xmalloc(sizeof (struct trampoline_frag)); ++ tf->next = ts->trampoline_list.next; ++ ts->trampoline_list.next = tf; ++ tf->needs_jump_around = needs_jump_around; ++ tf->fragP = fragP; ++ tf->fixP = NULL; ++} ++ ++ ++static struct trampoline_seg * ++find_trampoline_seg (asection *seg) ++{ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ if (ts->seg == seg) ++ return ts; ++ } ++ ++ return NULL; + } + + ++void dump_trampolines (void); ++ ++void ++dump_trampolines (void) ++{ ++ struct trampoline_seg *ts = trampoline_seg_list.next; ++ ++ for ( ; ts; ts = ts->next) ++ { ++ asection *seg = ts->seg; ++ ++ if (seg == NULL) ++ continue; ++ fprintf(stderr, "SECTION %s\n", seg->name); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ for ( ; tf; tf = tf->next) ++ { ++ if (tf->fragP == NULL) ++ continue; ++ fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n", ++ (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix, ++ tf->needs_jump_around ? "T" : "F"); ++ } ++ } ++} ++ + static void + xtensa_cleanup_align_frags (void) + { +@@ -8708,6 +8891,149 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + new_stretch += relax_frag_for_align (fragP, stretch); + break; + ++ case RELAX_TRAMPOLINE: ++ if (fragP->tc_frag_data.relax_seen) ++ { ++ segment_info_type *seginfo = seg_info (now_seg); ++ fragS *fP; /* The out-of-range jump. */ ++ fixS *fixP; ++ ++ /* Scan for jumps that will not reach. */ ++ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ { ++ symbolS *s = fixP->fx_addsy; ++ xtensa_opcode opcode; ++ int target; ++ int addr; ++ int delta; ++ ++ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || ++ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) ++ continue; ++ xtensa_insnbuf_from_chars (isa, trampoline_buf, ++ (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, ++ 0); ++ fmt = xtensa_format_decode (isa, trampoline_buf); ++ gas_assert (fmt != XTENSA_UNDEFINED); ++ slot = fixP->tc_fix_data.slot; ++ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); ++ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); ++ if (opcode != xtensa_j_opcode) ++ continue; ++ target = S_GET_VALUE (s); ++ addr = fixP->fx_frag->fr_address; ++ delta = target - addr + stretch; ++ if (delta > J_RANGE || delta < -1 * J_RANGE) ++ { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ struct trampoline_frag *prev = &ts->trampoline_list; ++ int lower = (target < addr) ? target : addr; ++ int upper = (target > addr) ? target : addr; ++ int midpoint = lower + (upper - lower) / 2; ++ ++ if ((upper - lower) > 2 * J_RANGE) ++ { ++ /* One trampoline won't suffice; we need multiple jumps. ++ Jump to the trampoline that's farthest, but still in ++ range relative to the original "j" instruction. */ ++ for ( ; tf; prev = tf, tf = tf->next ) ++ { ++ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ; ++ ++ if (addr == lower) ++ { ++ /* Forward jump. */ ++ if (this_addr - addr < J_RANGE) ++ break; ++ } ++ else ++ { ++ /* Backward jump. */ ++ if (next_addr == 0 || addr - next_addr > J_RANGE) ++ break; ++ } ++ } ++ } ++ else ++ { ++ struct trampoline_frag *best_tf = NULL; ++ int best_delta = 0; ++ ++ for ( ; tf; prev = tf, tf = tf->next ) ++ { ++ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ int this_delta = abs (this_addr - midpoint); ++ ++ if (!best_tf || this_delta < best_delta) ++ { ++ best_tf = tf; ++ best_delta = this_delta; ++ } ++ } ++ tf = best_tf; ++ } ++ if (tf->fragP == fragP) ++ { ++ int trampaddr = fragP->fr_address + fragP->fr_fix; ++ ++ if (abs (addr - trampaddr) < J_RANGE) ++ { /* The trampoline is in range of original; fix it! */ ++ fixS *newfixP; ++ int offset; ++ TInsn insn; ++ symbolS *lsym; ++ ++ new_stretch += init_trampoline_frag (tf); ++ offset = fragP->fr_fix; /* Where to assemble the j insn. */ ++ lsym = fragP->fr_symbol; ++ fP = fixP->fx_frag; ++ /* Assemble a jump to the target label here. */ ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], lsym, offset); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3); ++ fragP->fr_fix += 3; ++ fragP->fr_var -= 3; ++ /* Add a fix-up for the original j insn. */ ++ newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type); ++ newfixP->fx_no_overflow = 1; ++ newfixP->tc_fix_data.X_add_symbol = lsym; ++ newfixP->tc_fix_data.X_add_number = offset; ++ newfixP->tc_fix_data.slot = slot; ++ /* Move the fix-up from the original j insn to this one. */ ++ fixP->fx_frag = fragP; ++ fixP->fx_where = fragP->fr_fix - 3; ++ fixP->tc_fix_data.slot = 0; ++ /* Adjust the jump around this trampoline (if present). */ ++ if (tf->fixP != NULL) ++ { ++ tf->fixP->fx_offset += 3; ++ } ++ new_stretch += 3; ++ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ ++ /* Do we have room for more? */ ++ if (fragP->fr_var < 3) ++ { /* No, convert to fill. */ ++ frag_wane (fragP); ++ fragP->fr_subtype = 0; ++ /* Remove from the trampoline_list. */ ++ prev->next = tf->next; ++ break; ++ } ++ } ++ } ++ } ++ } ++ } ++ break; ++ + default: + as_bad (_("bad relaxation state")); + } +@@ -9146,6 +9472,200 @@ bytes_to_stretch (fragS *this_frag, + } + + ++static struct trampoline_frag * ++search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) ++{ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL; ++ struct trampoline_frag *best_tf = NULL; ++ int best_delta = 0; ++ int best_addr = 0; ++ symbolS *sym = tinsn->tok[0].X_add_symbol; ++ offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; ++ offsetT addr = fragP->fr_address; ++ offsetT lower = (addr < target) ? addr : target; ++ offsetT upper = (addr > target) ? addr : target; ++ int delta = upper - lower; ++ offsetT midpoint = lower + delta / 2; ++ int this_delta = -1; ++ int this_addr = -1; ++ ++ if (delta > 2 * J_RANGE) ++ { ++ /* One trampoline won't do; we need multiple. ++ Choose the farthest trampoline that's still in range of the original ++ and let a later pass finish the job. */ ++ for ( ; tf; tf = tf->next) ++ { ++ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0; ++ ++ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ if (lower == addr) ++ { ++ /* Forward jump. */ ++ if (this_addr - addr < J_RANGE) ++ break; ++ } ++ else ++ { ++ /* Backward jump. */ ++ if (next_addr == 0 || addr - next_addr > J_RANGE) ++ break; ++ } ++ if (abs (addr - this_addr) < J_RANGE) ++ return tf; ++ ++ return NULL; ++ } ++ } ++ for ( ; tf; tf = tf->next) ++ { ++ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; ++ this_delta = abs (this_addr - midpoint); ++ if (unreachable_only && tf->needs_jump_around) ++ continue; ++ if (!best_tf || this_delta < best_delta) ++ { ++ best_tf = tf; ++ best_delta = this_delta; ++ best_addr = this_addr; ++ } ++ } ++ ++ if (best_tf && ++ best_delta < J_RANGE && ++ abs(best_addr - lower) < J_RANGE && ++ abs(best_addr - upper) < J_RANGE) ++ return best_tf; ++ ++ return NULL; /* No suitable trampoline found. */ ++} ++ ++ ++static struct trampoline_frag * ++get_best_trampoline (TInsn *tinsn, fragS *fragP) ++{ ++ struct trampoline_frag *tf = NULL; ++ ++ tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ ++ ++ if (tf == NULL) ++ tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */ ++ ++ return tf; ++} ++ ++ ++static void ++check_and_update_trampolines (void) ++{ ++ struct trampoline_seg *ts = find_trampoline_seg (now_seg); ++ struct trampoline_frag *tf = ts->trampoline_list.next; ++ struct trampoline_frag *prev = &ts->trampoline_list; ++ ++ for ( ; tf; prev = tf, tf = tf->next) ++ { ++ if (tf->fragP->fr_var < 3) ++ { ++ frag_wane (tf->fragP); ++ prev->next = tf->next; ++ tf->fragP = NULL; ++ } ++ } ++} ++ ++ ++static int ++init_trampoline_frag (struct trampoline_frag *trampP) ++{ ++ fragS *fp = trampP->fragP; ++ int growth = 0; ++ ++ if (fp->fr_fix == 0) ++ { ++ symbolS *lsym; ++ char label[10 + 2 * sizeof(fp)]; ++ sprintf (label, ".L0_TR_%p", fp); ++ ++ lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); ++ fp->fr_symbol = lsym; ++ if (trampP->needs_jump_around) ++ { ++ /* Add a jump around this block of jumps, in case ++ control flows into this block. */ ++ fixS *fixP; ++ TInsn insn; ++ xtensa_format fmt; ++ xtensa_isa isa = xtensa_default_isa; ++ ++ fp->tc_frag_data.is_insn = 1; ++ /* Assemble a jump insn. */ ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], lsym, 3); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3); ++ fp->fr_fix += 3; ++ fp->fr_var -= 3; ++ growth = 3; ++ fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); ++ trampP->fixP = fixP; ++ } ++ } ++ return growth; ++} ++ ++ ++static int ++add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) ++{ ++ fragS *tramp = trampP->fragP; ++ fixS *fixP; ++ int offset = tramp->fr_fix; /* Where to assemble the j insn. */ ++ TInsn insn; ++ symbolS *lsym; ++ symbolS *tsym; ++ int toffset; ++ xtensa_format fmt; ++ xtensa_isa isa = xtensa_default_isa; ++ int growth = 0; ++ ++ lsym = tramp->fr_symbol; ++ /* Assemble a jump to the target label in the trampoline frag. */ ++ tsym = origfrag->tc_frag_data.slot_symbols[0]; ++ toffset = origfrag-> tc_frag_data.slot_offsets[0]; ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], tsym, toffset); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); ++ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3); ++ tramp->fr_fix += 3; ++ tramp->fr_var -= 3; ++ growth = 3; ++ /* add a fix-up for the trampoline jump. */ ++ fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); ++ /* Modify the jump at the start of this trampoline to point past the newly-added jump. */ ++ fixP = trampP->fixP; ++ if (fixP) ++ fixP->fx_offset += 3; ++ /* Modify the original j to point here. */ ++ origfrag->tc_frag_data.slot_symbols[0] = lsym; ++ origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3; ++ /* If trampoline is full, remove it from the list. */ ++ check_and_update_trampolines (); ++ ++ return growth; ++} ++ ++ + static long + relax_frag_immed (segT segP, + fragS *fragP, +@@ -9284,6 +9804,37 @@ relax_frag_immed (segT segP, + if (negatable_branch && istack.ninsn > 1) + update_next_frag_state (fragP); + ++ /* If last insn is a jump, and it cannot reach its target, try to find a trampoline. */ ++ if (istack.ninsn > 2 && ++ istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL && ++ istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN && ++ istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode) ++ { ++ TInsn *jinsn = &istack.insn[istack.ninsn - 2]; ++ ++ if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) ++ { ++ struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP); ++ ++ if (tf) ++ { ++ this_text_diff += init_trampoline_frag (tf); ++ this_text_diff += add_jump_to_trampoline (tf, fragP); ++ } ++ else ++ { ++ /* If target symbol is undefined, assume it will reach once linked. */ ++ expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0]; ++ ++ if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol)) ++ { ++ as_bad_where (fragP->fr_file, fragP->fr_line, ++ _("jump target out of range; no usable trampoline found")); ++ } ++ } ++ } ++ } ++ + return this_text_diff; + } + +@@ -9404,6 +9955,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp) + else + as_bad (_("invalid relaxation fragment result")); + break; ++ ++ case RELAX_TRAMPOLINE: ++ break; + } + + fragp->fr_var = 0; +diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h +index 0bf1240..4672bc6 100644 +--- a/gas/config/tc-xtensa.h ++++ b/gas/config/tc-xtensa.h +@@ -180,6 +180,11 @@ enum xtensa_relax_statesE + prevent the linker from changing the size of any frag between the + section start and the org frag. */ + ++ RELAX_TRAMPOLINE, ++ /* Every few thousand frags, we insert one of these, just in case we may ++ need some space for a trampoline (jump to a jump) because the function ++ has gotten too big. If not needed, it disappears. */ ++ + RELAX_NONE + }; + +diff --git a/gas/frags.c b/gas/frags.c +index 5f68480..e14099d 100644 +--- a/gas/frags.c ++++ b/gas/frags.c +@@ -24,6 +24,20 @@ + + extern fragS zero_address_frag; + extern fragS predefined_address_frag; ++ ++static int totalfrags; ++ ++int ++get_frag_count (void) ++{ ++ return totalfrags; ++} ++ ++void ++clear_frag_count (void) ++{ ++ totalfrags = 0; ++} + + /* Initialization for frag routines. */ + +@@ -70,6 +84,7 @@ frag_alloc (struct obstack *ob) + ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG); + obstack_alignment_mask (ob) = oalign; + memset (ptr, 0, SIZEOF_STRUCT_FRAG); ++ totalfrags++; + return ptr; + } + +diff --git a/gas/frags.h b/gas/frags.h +index 319898f..2f9e1b5 100644 +--- a/gas/frags.h ++++ b/gas/frags.h +@@ -155,4 +155,7 @@ char *frag_var (relax_stateT type, + + bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); + ++int get_frag_count (void); ++void clear_frag_count (void); ++ + #endif /* FRAGS_H */ +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 2b2c294..3683b78 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -98,6 +98,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "pcrel" + run_dump_test "weak-call" + run_dump_test "jlong" ++ run_dump_test "trampoline" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d +new file mode 100644 +index 0000000..b4f65dc +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/trampoline.d +@@ -0,0 +1,26 @@ ++#as: ++#objdump: -d ++#name: trampolines relaxation ++ ++.*: +file format .*xtensa.* ++#... ++.*0:.*j.0x1194c ++.*3:.*j.0x1194f ++.*6:.*j.0x11952 ++.*9:.*j.0x1d4e4 ++#... ++.*11949:.*j.0x11955 ++.*1194c:.*j.0x24a0e ++.*1194f:.*j.0x24a0e ++.*11952:.*j.0x24a11 ++#... ++.*1d4e1:.*j.0x1d4e7 ++.*1d4e4:.*j.0x33462 ++#... ++.*24a0e:.*j.0x24a0e ++.*24a11:.*j.0x24a11 ++#... ++.*3345f:.*ret ++.*33462:.*j.0x49407 ++#... ++.*49407:.*j.0x49407 +diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s +new file mode 100644 +index 0000000..259a3bb +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/trampoline.s +@@ -0,0 +1,21 @@ ++ .text ++ j 1f ++ j 1f ++ j 2f ++ j 3f ++ .rep 25000 ++99: ++ and a2, a2, a3 ++ bne a2, a3, 99b ++ .endr ++1: ++ j 1b ++2: ++ j 2b ++ ++ .rep 25000 ++ and a2, a2, a3 ++ _ret ++ .endr ++3: ++ j 3b +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch b/packages/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch new file mode 100644 index 0000000..e1c2d85 --- /dev/null +++ b/packages/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch @@ -0,0 +1,51 @@ +From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 15 Apr 2014 19:12:46 +0400 +Subject: [PATCH] Fix alignment for the first section frag on xtensa + +Linking object files produced by partial linking with link-time +relaxation enabled sometimes fails with the following error message: + +dangerous relocation: call8: misaligned call target: (.text.unlikely+0x63) + +This happens because no basic block with an XTENSA_PROP_ALIGN flag in the +property table is generated for the first basic block, even if the +.align directive is present. +It was believed that the first frag alignment could be derived from the +section alignment, but this was not implemented for the partial linking +case: after partial linking first frag of a section may become not +first, but no additional alignment frag is inserted before it. +Basic block for such frag may be merged with previous basic block into +extended basic block during relaxation pass losing its alignment +restrictions. + +Fix this by always recording alignment for the first section frag. + +2014-04-22 Max Filippov + +gas/ + * config/tc-xtensa.c (xtensa_handle_align): record alignment for the + first section frag. + +--- +Backported from: a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 +Changes to Changelog files and tests are dropped. + + gas/config/tc-xtensa.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index ea23c96..58ace38 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5609,7 +5609,6 @@ xtensa_handle_align (fragS *fragP) + && ! fragP->tc_frag_data.is_literal + && (fragP->fr_type == rs_align + || fragP->fr_type == rs_align_code) +- && fragP->fr_address + fragP->fr_fix > 0 + && fragP->fr_offset > 0 + && now_seg != bss_section) + { +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch b/packages/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch new file mode 100644 index 0000000..ba24f4e --- /dev/null +++ b/packages/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch @@ -0,0 +1,133 @@ +From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001 +From: Volodymyr Arbatov +Date: Mon, 6 May 2013 09:43:21 -0800 +Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets. + +R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such. +Add testcase that examines ld behaviour on R_XTENSA_DIFF relocation +changing sign during relaxation. + +2014-05-02 Volodymyr Arbatov + David Weatherford + Max Filippov + +bfd/ + * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as + signed. + +gas/ + * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF* + fixups as signed. +--- +Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6 +Changes to Changelog files and tests are dropped. + + bfd/elf32-xtensa.c | 32 ++++++++++++----------- + gas/config/tc-xtensa.c | 3 +++ + 2 files changed, 20 insertions(+), 15 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index edb04b4..8818d67 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] = + FALSE, 0, 0, FALSE), + + /* Relocations for supporting difference of symbols. */ +- HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE), +- HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE), +- HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, ++ HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE), + + /* General immediate operand relocations. */ +@@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + || r_type == R_XTENSA_DIFF16 + || r_type == R_XTENSA_DIFF32) + { +- bfd_vma diff_value = 0, new_end_offset, diff_mask = 0; ++ bfd_signed_vma diff_value = 0; ++ bfd_vma new_end_offset, diff_mask = 0; + + if (bfd_get_section_limit (abfd, sec) < old_source_offset) + { +@@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + { + case R_XTENSA_DIFF8: + diff_value = +- bfd_get_8 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_8 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: + diff_value = +- bfd_get_16 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_16 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: + diff_value = +- bfd_get_32 (abfd, &contents[old_source_offset]); ++ bfd_get_signed_32 (abfd, &contents[old_source_offset]); + break; + } + +@@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + switch (r_type) + { + case R_XTENSA_DIFF8: +- diff_mask = 0xff; +- bfd_put_8 (abfd, diff_value, ++ diff_mask = 0x7f; ++ bfd_put_signed_8 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: +- diff_mask = 0xffff; +- bfd_put_16 (abfd, diff_value, ++ diff_mask = 0x7fff; ++ bfd_put_signed_16 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: +- diff_mask = 0xffffffff; +- bfd_put_32 (abfd, diff_value, ++ diff_mask = 0x7fffffff; ++ bfd_put_signed_32 (abfd, diff_value, + &contents[old_source_offset]); + break; + } + +- /* Check for overflow. */ +- if ((diff_value & ~diff_mask) != 0) ++ /* Check for overflow. Sign bits must be all zeroes or all ones */ ++ if ((diff_value & ~diff_mask) != 0 && ++ (diff_value & ~diff_mask) != (-1 & ~diff_mask)) + { + (*link_info->callbacks->reloc_dangerous) + (link_info, _("overflow after relaxation"), +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 58ace38..7547c0a0 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; ++ fixP->fx_signed = 1; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; ++ fixP->fx_signed = 1; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; ++ fixP->fx_signed = 1; + break; + default: + break; +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch b/packages/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch new file mode 100644 index 0000000..6a0846e --- /dev/null +++ b/packages/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch @@ -0,0 +1,47 @@ +From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 10 Jul 2014 01:47:33 +0400 +Subject: [PATCH] Fix xtensa ld segfault when linking linux modules + +is_inconsistent_linkonce_section makes an assumption that section name +that starts with ".gnu.linkonce.prop." has one more dot in its suffix. +However gas generates such section name by insertion of "prop." right +after ".gnu.linkonce." part of the name of the original section. So, for +section named ".gnu.linkonce.this_module" corresponding property section +name does not satisfy the assumption. Such section names are common in +linux modules. This bug was exposed by the patch "a35d5e8 Fix alignment +for the first section frag on xtensa", that makes gas produce property +section for each section that has ".align" directive in it. + +Use suffix that immediately follows ".gnu.linkonce.prop." when there are +no more dots following it. + +2014-07-10 Max Filippov + +ld/ + * emultempl/xtensaelf.em (is_inconsistent_linkonce_section): + correctly handle missing dot in section name after + ".gnu.linkonce.prop.". +--- +Backported from: e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 +Changes to ld/ChangeLog file are dropped. + + ld/emultempl/xtensaelf.em | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em +index 151eea4..948d18d 100644 +--- a/ld/emultempl/xtensaelf.em ++++ b/ld/emultempl/xtensaelf.em +@@ -1310,7 +1310,7 @@ is_inconsistent_linkonce_section (asection *sec) + for Tensilica's XCC compiler. */ + name = sec_name + linkonce_len; + if (CONST_STRNEQ (name, "prop.")) +- name = strchr (name + 5, '.') + 1; ++ name = strchr (name + 5, '.') ? strchr (name + 5, '.') + 1 : name + 5; + else if (name[1] == '.' + && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h')) + name += 2; +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/packages/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch new file mode 100644 index 0000000..e4c600e --- /dev/null +++ b/packages/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch @@ -0,0 +1,79 @@ +From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 +From: Sterling Augustine +Date: Tue, 25 Jan 2011 13:59:13 -0800 +Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation + bug + +During link-time relaxation distance between cross-section call site and +its target may grow, producing 'call target out of range' error for +relaxed calls. Be more conservative when calculating whether or not a +callx can be converted to a straight call. + +2014-09-23 Sterling Augustine + +bfd/ + * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section + call relaxation use furthermost addresses where call source and + destination can be to check whether it's in the range of a direct + call. + +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 09862e3..e32496a 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, + || is_reloc_sym_weak (abfd, irel))) + return FALSE; + +- self_address = (sec->output_section->vma +- + sec->output_offset + irel->r_offset + 3); +- dest_address = (target_sec->output_section->vma +- + target_sec->output_offset + target_offset); ++ if (target_sec->output_section != sec->output_section) ++ { ++ /* If the two sections are sufficiently far away that relaxation ++ might take the call out of range, we can't simplify. For ++ example, a positive displacement call into another memory ++ could get moved to a lower address due to literal removal, ++ but the destination won't move, and so the displacment might ++ get larger. ++ ++ If the displacement is negative, assume the destination could ++ move as far back as the start of the output section. The ++ self_address will be at least as far into the output section ++ as it is prior to relaxation. ++ ++ If the displacement is postive, assume the destination will be in ++ it's pre-relaxed location (because relaxation only makes sections ++ smaller). The self_address could go all the way to the beginning ++ of the output section. */ ++ ++ dest_address = target_sec->output_section->vma; ++ self_address = sec->output_section->vma; ++ ++ if (sec->output_section->vma > target_sec->output_section->vma) ++ self_address += sec->output_offset + irel->r_offset + 3; ++ else ++ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); ++ /* Call targets should be four-byte aligned. */ ++ dest_address = (dest_address + 3) & ~3; ++ } ++ else ++ { ++ ++ self_address = (sec->output_section->vma ++ + sec->output_offset + irel->r_offset + 3); ++ dest_address = (target_sec->output_section->vma ++ + target_sec->output_offset + target_offset); ++ } + + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch b/packages/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch new file mode 100644 index 0000000..8aeb064 --- /dev/null +++ b/packages/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch @@ -0,0 +1,90 @@ +From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 25 Nov 2014 21:33:21 +0300 +Subject: [PATCH] Fix trampolines search code for conditional branches + +For conditional branches that need more than one trampoline to reach its +target assembler couldn't always find suitable trampoline because +post-loop condition check was placed inside the loop, resulting in +premature loop termination. Move check outside the loop. + +This fixes the following build errors seen when assembling huge files +produced by gcc: + Error: jump target out of range; no usable trampoline found + Error: operand 1 of 'j' has out of range value '307307' + +2014-11-25 Max Filippov + +gas/ + * config/tc-xtensa.c (search_trampolines): Move post-loop + condition check outside the search loop. + +gas/testsuite/ + * gas/xtensa/trampoline.d: Add expected output for branches. + * gas/xtensa/trampoline.s: Add test case for branches. + +Signed-off-by: Max Filippov +--- +Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 +Changes to ChangeLogs are dropped. + + gas/config/tc-xtensa.c | 8 ++++---- + gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ + gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index d11b0c7..f23ccf8 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) + if (next_addr == 0 || addr - next_addr > J_RANGE) + break; + } +- if (abs (addr - this_addr) < J_RANGE) +- return tf; +- +- return NULL; + } ++ if (abs (addr - this_addr) < J_RANGE) ++ return tf; ++ ++ return NULL; + } + for ( ; tf; tf = tf->next) + { +diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d +index b4f65dc..5ae32a6 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.d ++++ b/gas/testsuite/gas/xtensa/trampoline.d +@@ -24,3 +24,12 @@ + .*33462:.*j.0x49407 + #... + .*49407:.*j.0x49407 ++.*4940a:.*beqz.n.a2,.0x4940f ++.*4940c:.*j.0x693d1 ++#... ++.*693d1:.*j.0x7ddd4 ++#... ++.*7ddd4:.*j.0x927f5 ++#... ++.*927f5:.*j.0x927f5 ++#... +diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s +index 259a3bb..4465786 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.s ++++ b/gas/testsuite/gas/xtensa/trampoline.s +@@ -19,3 +19,10 @@ + .endr + 3: + j 3b ++ bnez a2, 4f ++ .rep 50000 ++ and a2, a2, a3 ++ _ret ++ .endr ++4: ++ j 4b +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch b/packages/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch new file mode 100644 index 0000000..8a21100 --- /dev/null +++ b/packages/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch @@ -0,0 +1,502 @@ +From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 27 Mar 2015 07:13:55 +0300 +Subject: [PATCH 1/4] xtensa: optimize check_section_ebb_pcrels_fit + +The original check_section_ebb_pcrels_fit algorithm checks that text +actions proposed for current EBB are OK for every relocation in a +section. There's no need to check every relocation, because text actions +for EBB can only change size of that EBB, thus only affecting +relocations that in any way cross that EBB. In addition EBBs are +iterated in ascending order of their VMA, making it easier to track +relevant relocations. + +Introduce a structure that can track relocations that cross the range of +VMAs of EBB and use it to only check relocations relevant to current EBB +in check_section_ebb_pcrels_fit. +It takes O(N log N) operations to build it and O(N) operations to move +current EBB VMA window through its entire range, where N is the number +of relocations in a section. The resulting complexity of +compute_text_actions is thus reduced from O(N^2) to O(N log N + N * M), +where M is the average number of relocations crossing each EBB. + +Original profile: + +% time self children called name +----------------------------------------- + 44.26 71.53 6429/6429 compute_text_actions + 50.2 44.26 71.53 6429 check_section_ebb_pcrels_fit + 1.16 20.12 347506666/347576152 pcrel_reloc_fits + 2.95 16.52 347506666/348104944 get_relocation_opnd + 2.01 9.74 347575100/361252208 r_reloc_init + 0.55 7.53 347575100/363381467 r_reloc_get_section + 5.76 0.02 695013332/695013332 xlate_offset_with_removed_text + 0.68 3.89 347575100/363483827 bfd_octets_per_byte + 0.32 0.00 347506666/349910253 is_alt_relocation + 0.18 0.11 6391/6391 build_xlate_map + 0.00 0.00 6429/19417168 get_xtensa_relax_info + 0.00 0.00 6391/6391 free_xlate_map +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 2.56 3.08 6429/6429 compute_text_actions + 8.2 2.56 3.08 6429 check_section_ebb_pcrels_fit + 0.08 0.91 17721075/17790561 pcrel_reloc_fits + 0.17 0.47 17721075/31685977 r_reloc_init + 0.43 0.00 35442150/35442150 xlate_offset_with_removed_text + 0.02 0.37 17721075/33815236 r_reloc_get_section + 0.22 0.11 6391/6391 build_xlate_map + 0.05 0.22 17721075/33917596 bfd_octets_per_byte + 0.03 0.00 17721075/20405299 is_alt_relocation + 0.01 0.00 6429/6429 reloc_range_list_update_range + 0.00 0.00 6429/19417168 get_xtensa_relax_info + 0.00 0.00 6391/6391 free_xlate_map +----------------------------------------- + +2015-04-01 Max Filippov +bfd/ + * elf32-xtensa.c (reloc_range_list, reloc_range_list_entry, + reloc_range): new typedef. + (reloc_range_list_struct, reloc_range_list_entry_struct, + reloc_range_struct): new structures. + (reloc_range_compare, build_reloc_ranges, + reloc_range_list_append, reloc_range_list_remove, + reloc_range_list_update_range, free_reloc_range_list): new + functions. + (compute_text_actions): precompute relocation opcodes before the + loop. Add relevant_relocs variable, initialize it before the + loop, pass it to the check_section_ebb_pcrels_fit. + (check_section_ebb_pcrels_fit): add new parameter: + relevant_relocs. Update address range in the relevant_relocs if + it's non-NULL and iterate only over relevant relocations. + +Backported from: b2b326d246f839ee218192ac88da2384d929a072 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 298 insertions(+), 23 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 0b6f584..872370b 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -6619,8 +6619,10 @@ static bfd_boolean compute_text_actions + (bfd *, asection *, struct bfd_link_info *); + static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *); + static bfd_boolean compute_ebb_actions (ebb_constraint *); ++typedef struct reloc_range_list_struct reloc_range_list; + static bfd_boolean check_section_ebb_pcrels_fit +- (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *, ++ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, ++ reloc_range_list *, const ebb_constraint *, + const xtensa_opcode *); + static bfd_boolean check_section_ebb_reduces (const ebb_constraint *); + static void text_action_add_proposed +@@ -7219,6 +7221,221 @@ build_reloc_opcodes (bfd *abfd, + return reloc_opcodes; + } + ++struct reloc_range_struct ++{ ++ bfd_vma addr; ++ bfd_boolean add; /* TRUE if start of a range, FALSE otherwise. */ ++ /* Original irel index in the array of relocations for a section. */ ++ unsigned irel_index; ++}; ++typedef struct reloc_range_struct reloc_range; ++ ++typedef struct reloc_range_list_entry_struct reloc_range_list_entry; ++struct reloc_range_list_entry_struct ++{ ++ reloc_range_list_entry *next; ++ reloc_range_list_entry *prev; ++ Elf_Internal_Rela *irel; ++ xtensa_opcode opcode; ++ int opnum; ++}; ++ ++struct reloc_range_list_struct ++{ ++ /* The rest of the structure is only meaningful when ok is TRUE. */ ++ bfd_boolean ok; ++ ++ unsigned n_range; /* Number of range markers. */ ++ reloc_range *range; /* Sorted range markers. */ ++ ++ unsigned first; /* Index of a first range element in the list. */ ++ unsigned last; /* One past index of a last range element in the list. */ ++ ++ unsigned n_list; /* Number of list elements. */ ++ reloc_range_list_entry *reloc; /* */ ++ reloc_range_list_entry list_root; ++}; ++ ++static int ++reloc_range_compare (const void *a, const void *b) ++{ ++ const reloc_range *ra = a; ++ const reloc_range *rb = b; ++ ++ if (ra->addr != rb->addr) ++ return ra->addr < rb->addr ? -1 : 1; ++ if (ra->add != rb->add) ++ return ra->add ? -1 : 1; ++ return 0; ++} ++ ++static void ++build_reloc_ranges (bfd *abfd, asection *sec, ++ bfd_byte *contents, ++ Elf_Internal_Rela *internal_relocs, ++ xtensa_opcode *reloc_opcodes, ++ reloc_range_list *list) ++{ ++ unsigned i; ++ size_t n = 0; ++ size_t max_n = 0; ++ reloc_range *ranges = NULL; ++ reloc_range_list_entry *reloc = ++ bfd_malloc (sec->reloc_count * sizeof (*reloc)); ++ ++ memset (list, 0, sizeof (*list)); ++ list->ok = TRUE; ++ ++ for (i = 0; i < sec->reloc_count; i++) ++ { ++ Elf_Internal_Rela *irel = &internal_relocs[i]; ++ int r_type = ELF32_R_TYPE (irel->r_info); ++ reloc_howto_type *howto = &elf_howto_table[r_type]; ++ r_reloc r_rel; ++ ++ if (r_type == R_XTENSA_ASM_SIMPLIFY ++ || r_type == R_XTENSA_32_PCREL ++ || !howto->pc_relative) ++ continue; ++ ++ r_reloc_init (&r_rel, abfd, irel, contents, ++ bfd_get_section_limit (abfd, sec)); ++ ++ if (r_reloc_get_section (&r_rel) != sec) ++ continue; ++ ++ if (n + 2 > max_n) ++ { ++ max_n = (max_n + 2) * 2; ++ ranges = bfd_realloc (ranges, max_n * sizeof (*ranges)); ++ } ++ ++ ranges[n].addr = irel->r_offset; ++ ranges[n + 1].addr = r_rel.target_offset; ++ ++ ranges[n].add = ranges[n].addr < ranges[n + 1].addr; ++ ranges[n + 1].add = !ranges[n].add; ++ ++ ranges[n].irel_index = i; ++ ranges[n + 1].irel_index = i; ++ ++ n += 2; ++ ++ reloc[i].irel = irel; ++ ++ /* Every relocation won't possibly be checked in the optimized version of ++ check_section_ebb_pcrels_fit, so this needs to be done here. */ ++ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) ++ { ++ /* None of the current alternate relocs are PC-relative, ++ and only PC-relative relocs matter here. */ ++ } ++ else ++ { ++ xtensa_opcode opcode; ++ int opnum; ++ ++ if (reloc_opcodes) ++ opcode = reloc_opcodes[i]; ++ else ++ opcode = get_relocation_opcode (abfd, sec, contents, irel); ++ ++ if (opcode == XTENSA_UNDEFINED) ++ { ++ list->ok = FALSE; ++ break; ++ } ++ ++ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); ++ if (opnum == XTENSA_UNDEFINED) ++ { ++ list->ok = FALSE; ++ break; ++ } ++ ++ /* Record relocation opcode and opnum as we've calculated them ++ anyway and they won't change. */ ++ reloc[i].opcode = opcode; ++ reloc[i].opnum = opnum; ++ } ++ } ++ ++ if (list->ok) ++ { ++ ranges = bfd_realloc (ranges, n * sizeof (*ranges)); ++ qsort (ranges, n, sizeof (*ranges), reloc_range_compare); ++ ++ list->n_range = n; ++ list->range = ranges; ++ list->reloc = reloc; ++ list->list_root.prev = &list->list_root; ++ list->list_root.next = &list->list_root; ++ } ++ else ++ { ++ free (ranges); ++ free (reloc); ++ } ++} ++ ++static void reloc_range_list_append (reloc_range_list *list, ++ unsigned irel_index) ++{ ++ reloc_range_list_entry *entry = list->reloc + irel_index; ++ ++ entry->prev = list->list_root.prev; ++ entry->next = &list->list_root; ++ entry->prev->next = entry; ++ entry->next->prev = entry; ++ ++list->n_list; ++} ++ ++static void reloc_range_list_remove (reloc_range_list *list, ++ unsigned irel_index) ++{ ++ reloc_range_list_entry *entry = list->reloc + irel_index; ++ ++ entry->next->prev = entry->prev; ++ entry->prev->next = entry->next; ++ --list->n_list; ++} ++ ++/* Update relocation list object so that it lists all relocations that cross ++ [first; last] range. Range bounds should not decrease with successive ++ invocations. */ ++static void reloc_range_list_update_range (reloc_range_list *list, ++ bfd_vma first, bfd_vma last) ++{ ++ /* This should not happen: EBBs are iterated from lower addresses to higher. ++ But even if that happens there's no need to break: just flush current list ++ and start from scratch. */ ++ if ((list->last > 0 && list->range[list->last - 1].addr > last) || ++ (list->first > 0 && list->range[list->first - 1].addr >= first)) ++ { ++ list->first = 0; ++ list->last = 0; ++ list->n_list = 0; ++ list->list_root.next = &list->list_root; ++ list->list_root.prev = &list->list_root; ++ fprintf (stderr, "%s: move backwards requested\n", __func__); ++ } ++ ++ for (; list->last < list->n_range && ++ list->range[list->last].addr <= last; ++list->last) ++ if (list->range[list->last].add) ++ reloc_range_list_append (list, list->range[list->last].irel_index); ++ ++ for (; list->first < list->n_range && ++ list->range[list->first].addr < first; ++list->first) ++ if (!list->range[list->first].add) ++ reloc_range_list_remove (list, list->range[list->first].irel_index); ++} ++ ++static void free_reloc_range_list (reloc_range_list *list) ++{ ++ free (list->range); ++ free (list->reloc); ++} + + /* The compute_text_actions function will build a list of potential + transformation actions for code in the extended basic block of each +@@ -7245,6 +7462,7 @@ compute_text_actions (bfd *abfd, + property_table_entry *prop_table = 0; + int ptblsize = 0; + bfd_size_type sec_size; ++ reloc_range_list relevant_relocs; + + relax_info = get_xtensa_relax_info (sec); + BFD_ASSERT (relax_info); +@@ -7277,6 +7495,12 @@ compute_text_actions (bfd *abfd, + goto error_return; + } + ++ /* Precompute the opcode for each relocation. */ ++ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs); ++ ++ build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes, ++ &relevant_relocs); ++ + for (i = 0; i < sec->reloc_count; i++) + { + Elf_Internal_Rela *irel = &internal_relocs[i]; +@@ -7340,17 +7564,13 @@ compute_text_actions (bfd *abfd, + ebb->start_reloc_idx = i; + ebb->end_reloc_idx = i; + +- /* Precompute the opcode for each relocation. */ +- if (reloc_opcodes == NULL) +- reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, +- internal_relocs); +- + if (!extend_ebb_bounds (ebb) + || !compute_ebb_proposed_actions (&ebb_table) + || !compute_ebb_actions (&ebb_table) + || !check_section_ebb_pcrels_fit (abfd, sec, contents, +- internal_relocs, &ebb_table, +- reloc_opcodes) ++ internal_relocs, ++ &relevant_relocs, ++ &ebb_table, reloc_opcodes) + || !check_section_ebb_reduces (&ebb_table)) + { + /* If anything goes wrong or we get unlucky and something does +@@ -7372,6 +7592,8 @@ compute_text_actions (bfd *abfd, + free_ebb_constraint (&ebb_table); + } + ++ free_reloc_range_list (&relevant_relocs); ++ + #if DEBUG + if (relax_info->action_list.head) + print_action_list (stderr, &relax_info->action_list); +@@ -7974,14 +8196,17 @@ check_section_ebb_pcrels_fit (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *internal_relocs, ++ reloc_range_list *relevant_relocs, + const ebb_constraint *constraint, + const xtensa_opcode *reloc_opcodes) + { + unsigned i, j; ++ unsigned n = sec->reloc_count; + Elf_Internal_Rela *irel; + xlate_map_t *xmap = NULL; + bfd_boolean ok = TRUE; + xtensa_relax_info *relax_info; ++ reloc_range_list_entry *entry = NULL; + + relax_info = get_xtensa_relax_info (sec); + +@@ -7992,7 +8217,40 @@ check_section_ebb_pcrels_fit (bfd *abfd, + can still be used. */ + } + +- for (i = 0; i < sec->reloc_count; i++) ++ if (relevant_relocs && constraint->action_count) ++ { ++ if (!relevant_relocs->ok) ++ { ++ ok = FALSE; ++ n = 0; ++ } ++ else ++ { ++ bfd_vma min_offset, max_offset; ++ min_offset = max_offset = constraint->actions[0].offset; ++ ++ for (i = 1; i < constraint->action_count; ++i) ++ { ++ proposed_action *action = &constraint->actions[i]; ++ bfd_vma offset = action->offset; ++ ++ if (offset < min_offset) ++ min_offset = offset; ++ if (offset > max_offset) ++ max_offset = offset; ++ } ++ reloc_range_list_update_range (relevant_relocs, min_offset, ++ max_offset); ++ n = relevant_relocs->n_list; ++ entry = &relevant_relocs->list_root; ++ } ++ } ++ else ++ { ++ relevant_relocs = NULL; ++ } ++ ++ for (i = 0; i < n; i++) + { + r_reloc r_rel; + bfd_vma orig_self_offset, orig_target_offset; +@@ -8001,7 +8259,15 @@ check_section_ebb_pcrels_fit (bfd *abfd, + reloc_howto_type *howto; + int self_removed_bytes, target_removed_bytes; + +- irel = &internal_relocs[i]; ++ if (relevant_relocs) ++ { ++ entry = entry->next; ++ irel = entry->irel; ++ } ++ else ++ { ++ irel = internal_relocs + i; ++ } + r_type = ELF32_R_TYPE (irel->r_info); + + howto = &elf_howto_table[r_type]; +@@ -8067,21 +8333,30 @@ check_section_ebb_pcrels_fit (bfd *abfd, + xtensa_opcode opcode; + int opnum; + +- if (reloc_opcodes) +- opcode = reloc_opcodes[i]; +- else +- opcode = get_relocation_opcode (abfd, sec, contents, irel); +- if (opcode == XTENSA_UNDEFINED) ++ if (relevant_relocs) + { +- ok = FALSE; +- break; ++ opcode = entry->opcode; ++ opnum = entry->opnum; + } +- +- opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); +- if (opnum == XTENSA_UNDEFINED) ++ else + { +- ok = FALSE; +- break; ++ if (reloc_opcodes) ++ opcode = reloc_opcodes[relevant_relocs ? ++ (unsigned)(entry - relevant_relocs->reloc) : i]; ++ else ++ opcode = get_relocation_opcode (abfd, sec, contents, irel); ++ if (opcode == XTENSA_UNDEFINED) ++ { ++ ok = FALSE; ++ break; ++ } ++ ++ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); ++ if (opnum == XTENSA_UNDEFINED) ++ { ++ ok = FALSE; ++ break; ++ } + } + + if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset)) +@@ -8778,7 +9053,7 @@ move_shared_literal (asection *sec, + /* Check all of the PC-relative relocations to make sure they still fit. */ + relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, + target_sec_cache->contents, +- target_sec_cache->relocs, ++ target_sec_cache->relocs, NULL, + &ebb_table, NULL); + + if (!relocs_fit) +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch b/packages/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch new file mode 100644 index 0000000..9df8065 --- /dev/null +++ b/packages/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch @@ -0,0 +1,356 @@ +From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 28 Mar 2015 08:46:28 +0300 +Subject: [PATCH 2/4] xtensa: optimize removed_by_actions + +The function removed_by_actions iterates through text actions to +calculate an offset applied by text actions to a given VMA. Although it +has a parameter p_start_action that allows for incremental offset +calculation, in many places it's used with p_start_action explicitly set +to the first action. After the first relaxation pass when the list of +text actions is finalized, an array of offsets sorted by VMA may be used +to speed up this function. + +Original profile: + +% time self children called name +----------------------------------------- + 0.35 0.00 33872/4808961 relax_section_symbols + 3.32 0.00 326022/4808961 relax_property_section + 12.83 0.00 1259379/4808961 offset_with_removed_text + 32.50 0.00 3189688/4808961 translate_reloc + 71.5 49.00 0.00 4808961 removed_by_actions +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 33872/4808537 relax_section_symbols + 0.01 0.00 326022/4808537 relax_property_section + 0.05 0.00 1258955/4808537 offset_with_removed_text_map + 0.13 0.00 3189688/4808537 translate_reloc + 1.0 0.20 0.00 4808537 removed_by_actions_map + 0.00 0.00 120/120 map_removal_by_action +----------------------------------------- + +2015-04-01 Max Filippov +bfd/ + * elf32-xtensa.c (removal_by_action_entry_struct, + removal_by_action_map_struct): new structures. + (removal_by_action_entry, removal_by_action_map): new typedefs. + (text_action_list_struct): add new field: map. + (map_removal_by_action, removed_by_actions_map, + offset_with_removed_text_map): new functions. + (relax_section): replace offset_with_removed_text with + offset_with_removed_text_map. + (translate_reloc, relax_property_section, relax_section_symbols): + replace removed_by_actions with removed_by_actions_map. + +Backported from: 071aa5c98a31c966f5fbfc573fcee61350fd1936 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 181 +++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 156 insertions(+), 25 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 872370b..21b2871 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -5420,11 +5420,28 @@ struct text_action_struct + text_action *next; + }; + ++struct removal_by_action_entry_struct ++{ ++ bfd_vma offset; ++ int removed; ++ int eq_removed; ++ int eq_removed_before_fill; ++}; ++typedef struct removal_by_action_entry_struct removal_by_action_entry; ++ ++struct removal_by_action_map_struct ++{ ++ unsigned n_entries; ++ removal_by_action_entry *entry; ++}; ++typedef struct removal_by_action_map_struct removal_by_action_map; ++ + + /* List of all of the actions taken on a text section. */ + struct text_action_list_struct + { + text_action *head; ++ removal_by_action_map map; + }; + + +@@ -5636,6 +5653,101 @@ action_list_count (text_action_list *action_list) + return count; + } + ++static void ++map_removal_by_action (text_action_list *action_list) ++{ ++ text_action *r; ++ int removed = 0; ++ removal_by_action_map map; ++ bfd_boolean eq_complete; ++ ++ map.n_entries = 0; ++ map.entry = bfd_malloc (action_list_count (action_list) * ++ sizeof (removal_by_action_entry)); ++ eq_complete = FALSE; ++ ++ for (r = action_list->head; r;) ++ { ++ removal_by_action_entry *ientry = map.entry + map.n_entries; ++ ++ if (map.n_entries && (ientry - 1)->offset == r->offset) ++ { ++ --ientry; ++ } ++ else ++ { ++ ++map.n_entries; ++ eq_complete = FALSE; ++ ientry->offset = r->offset; ++ ientry->eq_removed_before_fill = removed; ++ } ++ ++ if (!eq_complete) ++ { ++ if (r->action != ta_fill || r->removed_bytes >= 0) ++ { ++ ientry->eq_removed = removed; ++ eq_complete = TRUE; ++ } ++ else ++ ientry->eq_removed = removed + r->removed_bytes; ++ } ++ ++ removed += r->removed_bytes; ++ ientry->removed = removed; ++ r = r->next; ++ } ++ action_list->map = map; ++} ++ ++static int ++removed_by_actions_map (text_action_list *action_list, bfd_vma offset, ++ bfd_boolean before_fill) ++{ ++ unsigned a, b; ++ ++ if (!action_list->map.entry) ++ map_removal_by_action (action_list); ++ ++ if (!action_list->map.n_entries) ++ return 0; ++ ++ a = 0; ++ b = action_list->map.n_entries; ++ ++ while (b - a > 1) ++ { ++ unsigned c = (a + b) / 2; ++ ++ if (action_list->map.entry[c].offset <= offset) ++ a = c; ++ else ++ b = c; ++ } ++ ++ if (action_list->map.entry[a].offset < offset) ++ { ++ return action_list->map.entry[a].removed; ++ } ++ else if (action_list->map.entry[a].offset == offset) ++ { ++ return before_fill ? ++ action_list->map.entry[a].eq_removed_before_fill : ++ action_list->map.entry[a].eq_removed; ++ } ++ else ++ { ++ return 0; ++ } ++} ++ ++static bfd_vma ++offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) ++{ ++ int removed = removed_by_actions_map (action_list, offset, FALSE); ++ return offset - removed; ++} ++ + + /* The find_insn_action routine will only find non-fill actions. */ + +@@ -5909,6 +6021,9 @@ init_xtensa_relax_info (asection *sec) + + relax_info->action_list.head = NULL; + ++ relax_info->action_list.map.n_entries = 0; ++ relax_info->action_list.map.entry = NULL; ++ + relax_info->fix_list = NULL; + relax_info->fix_array = NULL; + relax_info->fix_array_count = 0; +@@ -9218,7 +9333,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + if (elf_hash_table (link_info)->dynamic_sections_created) + shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); + irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); +- irel->r_offset = offset_with_removed_text ++ irel->r_offset = offset_with_removed_text_map + (&relax_info->action_list, irel->r_offset); + continue; + } +@@ -9255,7 +9370,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + } + } + +- source_offset = offset_with_removed_text ++ source_offset = offset_with_removed_text_map + (&relax_info->action_list, irel->r_offset); + irel->r_offset = source_offset; + } +@@ -9352,7 +9467,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + break; + } + +- new_end_offset = offset_with_removed_text ++ new_end_offset = offset_with_removed_text_map + (&target_relax_info->action_list, + r_rel.target_offset + diff_value); + diff_value = new_end_offset - new_reloc.target_offset; +@@ -9750,7 +9865,6 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) + xtensa_relax_info *relax_info; + removed_literal *removed; + bfd_vma target_offset, base_offset; +- text_action *act; + + *new_rel = *orig_rel; + +@@ -9803,19 +9917,26 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) + offset. */ + + base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend; +- act = relax_info->action_list.head; + if (base_offset <= target_offset) + { +- int base_removed = removed_by_actions (&act, base_offset, FALSE); +- int addend_removed = removed_by_actions (&act, target_offset, FALSE); ++ int base_removed = removed_by_actions_map (&relax_info->action_list, ++ base_offset, FALSE); ++ int addend_removed = removed_by_actions_map (&relax_info->action_list, ++ target_offset, FALSE) - ++ base_removed; ++ + new_rel->target_offset = target_offset - base_removed - addend_removed; + new_rel->rela.r_addend -= addend_removed; + } + else + { + /* Handle a negative addend. The base offset comes first. */ +- int tgt_removed = removed_by_actions (&act, target_offset, FALSE); +- int addend_removed = removed_by_actions (&act, base_offset, FALSE); ++ int tgt_removed = removed_by_actions_map (&relax_info->action_list, ++ target_offset, FALSE); ++ int addend_removed = removed_by_actions_map (&relax_info->action_list, ++ base_offset, FALSE) - ++ tgt_removed; ++ + new_rel->target_offset = target_offset - tgt_removed; + new_rel->rela.r_addend += addend_removed; + } +@@ -10138,9 +10259,10 @@ relax_property_section (bfd *abfd, + bfd_vma old_offset = val.r_rel.target_offset; + bfd_vma new_offset; + long old_size, new_size; +- text_action *act = target_relax_info->action_list.head; +- new_offset = old_offset - +- removed_by_actions (&act, old_offset, FALSE); ++ int removed_by_old_offset = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset, FALSE); ++ new_offset = old_offset - removed_by_old_offset; + + /* Assert that we are not out of bounds. */ + old_size = bfd_get_32 (abfd, size_p); +@@ -10164,9 +10286,10 @@ relax_property_section (bfd *abfd, + + /* Recompute the new_offset, but this time don't + include any fill inserted by relaxation. */ +- act = target_relax_info->action_list.head; +- new_offset = old_offset - +- removed_by_actions (&act, old_offset, TRUE); ++ removed_by_old_offset = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset, TRUE); ++ new_offset = old_offset - removed_by_old_offset; + + /* If it is not unreachable and we have not yet + seen an unreachable at this address, place it +@@ -10182,8 +10305,12 @@ relax_property_section (bfd *abfd, + } + } + else +- new_size -= +- removed_by_actions (&act, old_offset + old_size, TRUE); ++ { ++ int removed_by_old_offset_size = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset + old_size, TRUE); ++ new_size -= removed_by_old_offset_size - removed_by_old_offset; ++ } + + if (new_size != old_size) + { +@@ -10441,14 +10568,16 @@ relax_section_symbols (bfd *abfd, asection *sec) + + if (isym->st_shndx == sec_shndx) + { +- text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = isym->st_value; ++ int removed = removed_by_actions_map (&relax_info->action_list, ++ orig_addr, FALSE); + +- isym->st_value -= removed_by_actions (&act, orig_addr, FALSE); +- ++ isym->st_value -= removed; + if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) + isym->st_size -= +- removed_by_actions (&act, orig_addr + isym->st_size, FALSE); ++ removed_by_actions_map (&relax_info->action_list, ++ orig_addr + isym->st_size, FALSE) - ++ removed; + } + } + +@@ -10466,15 +10595,17 @@ relax_section_symbols (bfd *abfd, asection *sec) + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) + { +- text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = sym_hash->root.u.def.value; ++ int removed = removed_by_actions_map (&relax_info->action_list, ++ orig_addr, FALSE); + +- sym_hash->root.u.def.value -= +- removed_by_actions (&act, orig_addr, FALSE); ++ sym_hash->root.u.def.value -= removed; + + if (sym_hash->type == STT_FUNC) + sym_hash->size -= +- removed_by_actions (&act, orig_addr + sym_hash->size, FALSE); ++ removed_by_actions_map (&relax_info->action_list, ++ orig_addr + sym_hash->size, FALSE) - ++ removed; + } + } + +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch b/packages/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch new file mode 100644 index 0000000..96d526f --- /dev/null +++ b/packages/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch @@ -0,0 +1,146 @@ +From 288c2b709e5e6841484e1a129eaccd299db36877 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 4 Apr 2015 14:49:42 +0300 +Subject: [PATCH 3/4] xtensa: optimize find_removed_literal + +find_removed_literal uses linear search to find removed literal by its +VMA. The list of literals is fixed at that point, build an ordered index +array and use binary search instead. + +Original profile: + +% time self children called name +----------------------------------------- + 56.72 0.00 297578/669392 translate_reloc + 70.86 0.00 371814/669392 relax_section + 67.9 127.58 0.00 669392 find_removed_literal +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 297578/669392 translate_reloc + 0.00 0.00 371814/669392 relax_section + 0.0 0.00 0.00 669392 find_removed_literal + 0.00 0.00 23838/23838 map_removed_literal +----------------------------------------- + +2015-04-03 Max Filippov +bfd/ + * elf32-xtensa.c (removed_literal_map_entry): new typedef. + (removed_literal_map_entry_struct): new structure. + (removed_literal_list_struct): add new fields: n_map and map. + (map_removed_literal, removed_literal_compare): new functions. + (find_removed_literal): build index array for literals ordered + by VMA, use binary search to find removed literal. + +Backported from: 3439c466273378021821473d3fc84990e089ae34 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 58 insertions(+), 6 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 21b2871..51733ad 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -5832,6 +5832,7 @@ print_action_list (FILE *fp, text_action_list *action_list) + by the "from" offset field. */ + + typedef struct removed_literal_struct removed_literal; ++typedef struct removed_literal_map_entry_struct removed_literal_map_entry; + typedef struct removed_literal_list_struct removed_literal_list; + + struct removed_literal_struct +@@ -5841,10 +5842,19 @@ struct removed_literal_struct + removed_literal *next; + }; + ++struct removed_literal_map_entry_struct ++{ ++ bfd_vma addr; ++ removed_literal *literal; ++}; ++ + struct removed_literal_list_struct + { + removed_literal *head; + removed_literal *tail; ++ ++ unsigned n_map; ++ removed_literal_map_entry *map; + }; + + +@@ -5893,6 +5903,39 @@ add_removed_literal (removed_literal_list *removed_list, + } + } + ++static void ++map_removed_literal (removed_literal_list *removed_list) ++{ ++ unsigned n_map = 0; ++ unsigned i; ++ removed_literal_map_entry *map = NULL; ++ removed_literal *r = removed_list->head; ++ ++ for (i = 0; r; ++i, r = r->next) ++ { ++ if (i == n_map) ++ { ++ n_map = (n_map * 2) + 2; ++ map = bfd_realloc (map, n_map * sizeof (*map)); ++ } ++ map[i].addr = r->from.target_offset; ++ map[i].literal = r; ++ } ++ removed_list->map = map; ++ removed_list->n_map = i; ++} ++ ++static int ++removed_literal_compare (const void *a, const void *b) ++{ ++ const removed_literal_map_entry *pa = a; ++ const removed_literal_map_entry *pb = b; ++ ++ if (pa->addr == pb->addr) ++ return 0; ++ else ++ return pa->addr < pb->addr ? -1 : 1; ++} + + /* Check if the list of removed literals contains an entry for the + given address. Return the entry if found. */ +@@ -5900,12 +5943,21 @@ add_removed_literal (removed_literal_list *removed_list, + static removed_literal * + find_removed_literal (removed_literal_list *removed_list, bfd_vma addr) + { +- removed_literal *r = removed_list->head; +- while (r && r->from.target_offset < addr) +- r = r->next; +- if (r && r->from.target_offset == addr) +- return r; +- return NULL; ++ removed_literal_map_entry *p; ++ removed_literal *r = NULL; ++ ++ if (removed_list->map == NULL) ++ map_removed_literal (removed_list); ++ ++ p = bsearch (&addr, removed_list->map, removed_list->n_map, ++ sizeof (*removed_list->map), removed_literal_compare); ++ if (p) ++ { ++ while (p != removed_list->map && (p - 1)->addr == addr) ++ --p; ++ r = p->literal; ++ } ++ return r; + } + + +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch b/packages/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch new file mode 100644 index 0000000..3090cc2 --- /dev/null +++ b/packages/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch @@ -0,0 +1,826 @@ +From e5409aedd3ee2192855018a564650ffb75c26e60 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 5 Apr 2015 17:04:22 +0300 +Subject: [PATCH 4/4] xtensa: replace action list with splay tree + +text_action_add uses linear list search to order text actions list by +action VMA. The list is used at the first relaxation pass, when it's not +fixed yet. +Replace the list with splay tree from libiberty. + +Original profile: + +% time self children called name +----------------------------------------- + 0.00 0.00 14/158225 compute_text_actions + 3.62 0.00 25211/158225 remove_dead_literal + 8.42 0.00 58645/158225 coalesce_shared_literal + 10.68 0.00 74355/158225 text_action_add_proposed + 38.8 22.73 0.00 158225 text_action_add + 0.00 0.00 144527/293246 bfd_zmalloc +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 14/158225 compute_text_actions + 0.00 0.00 25211/158225 remove_dead_literal + 0.00 0.01 58645/158225 coalesce_shared_literal + 0.00 0.01 74355/158225 text_action_add_proposed + 0.1 0.00 0.02 158225 text_action_add + 0.01 0.00 144527/144527 splay_tree_insert + 0.00 0.00 144527/195130 splay_tree_lookup + 0.00 0.00 144527/293246 bfd_zmalloc +----------------------------------------- + +2015-04-03 Max Filippov +bfd/ + * elf32-xtensa.c (splay-tree.h): include header. + (text_action_struct): drop next pointer. + (text_action_list_struct): drop head pointer, add count and + tree fields. + (find_fill_action): instead of linear search in text_action_list + search in the tree. + (text_action_compare, action_first, action_next): new functions. + (text_action_add, text_action_add_literal): instead of linear + search and insertion insert new node into the tree. + (removed_by_actions): pass additional parameter: action_list, + use it to traverse the tree. + (offset_with_removed_text): pass additional action_list parameter + to removed_by_actions. + (map_action_fn_context): new typedef. + (map_action_fn_context_struct): new structure. + (map_action_fn): new function. + (map_removal_by_action): use splay_tree_foreach to build map. + (find_insn_action): replace linear search in text_action_list + with series of splay_tree_lookups. + (print_action, print_action_list_fn): new functions. + (print_action_list): use splay_tree_foreach. + (init_xtensa_relax_info): drop action_list.head initialization. + Initialize the tree. + (compute_text_actions): use non-zero action_list_count instead of + non-NULL action list. + (xlate_map_context): new typedef. + (xlate_map_context_struct): new structure. + (xlate_map_fn): new function. + (build_xlate_map): use splay_tree_foreach to build map. + (action_remove_bytes_fn): new function. + (relax_section): use zero action_list_count instead of NULL + action list. Use splay_tree_foreach to count final section size. + Drop unused variable 'removed'. + +Backported from: 4c2af04fe8b4452bf51d2debf1bb467fafcd0f08 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 488 +++++++++++++++++++++++++++++++---------------------- + 1 file changed, 282 insertions(+), 206 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 51733ad..53af1c6 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -28,6 +28,7 @@ + #include "libbfd.h" + #include "elf-bfd.h" + #include "elf/xtensa.h" ++#include "splay-tree.h" + #include "xtensa-isa.h" + #include "xtensa-config.h" + +@@ -5416,8 +5417,6 @@ struct text_action_struct + bfd_vma virtual_offset; /* Zero except for adding literals. */ + int removed_bytes; + literal_value value; /* Only valid when adding literals. */ +- +- text_action *next; + }; + + struct removal_by_action_entry_struct +@@ -5440,7 +5439,8 @@ typedef struct removal_by_action_map_struct removal_by_action_map; + /* List of all of the actions taken on a text section. */ + struct text_action_list_struct + { +- text_action *head; ++ unsigned count; ++ splay_tree tree; + removal_by_action_map map; + }; + +@@ -5448,20 +5448,18 @@ struct text_action_list_struct + static text_action * + find_fill_action (text_action_list *l, asection *sec, bfd_vma offset) + { +- text_action **m_p; ++ text_action a; + + /* It is not necessary to fill at the end of a section. */ + if (sec->size == offset) + return NULL; + +- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) +- { +- text_action *t = *m_p; +- /* When the action is another fill at the same address, +- just increase the size. */ +- if (t->offset == offset && t->action == ta_fill) +- return t; +- } ++ a.offset = offset; ++ a.action = ta_fill; ++ ++ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); ++ if (node) ++ return (text_action *)node->value; + return NULL; + } + +@@ -5509,6 +5507,49 @@ adjust_fill_action (text_action *ta, int fill_diff) + } + + ++static int ++text_action_compare (splay_tree_key a, splay_tree_key b) ++{ ++ text_action *pa = (text_action *)a; ++ text_action *pb = (text_action *)b; ++ static const int action_priority[] = ++ { ++ [ta_fill] = 0, ++ [ta_none] = 1, ++ [ta_convert_longcall] = 2, ++ [ta_narrow_insn] = 3, ++ [ta_remove_insn] = 4, ++ [ta_remove_longcall] = 5, ++ [ta_remove_literal] = 6, ++ [ta_widen_insn] = 7, ++ [ta_add_literal] = 8, ++ }; ++ ++ if (pa->offset == pb->offset) ++ { ++ if (pa->action == pb->action) ++ return 0; ++ return action_priority[pa->action] - action_priority[pb->action]; ++ } ++ else ++ return pa->offset < pb->offset ? -1 : 1; ++} ++ ++static text_action * ++action_first (text_action_list *action_list) ++{ ++ splay_tree_node node = splay_tree_min (action_list->tree); ++ return node ? (text_action *)node->value : NULL; ++} ++ ++static text_action * ++action_next (text_action_list *action_list, text_action *action) ++{ ++ splay_tree_node node = splay_tree_successor (action_list->tree, ++ (splay_tree_key)action); ++ return node ? (text_action *)node->value : NULL; ++} ++ + /* Add a modification action to the text. For the case of adding or + removing space, modify any current fill and assume that + "unreachable_space" bytes can be freely contracted. Note that a +@@ -5521,8 +5562,8 @@ text_action_add (text_action_list *l, + bfd_vma offset, + int removed) + { +- text_action **m_p; + text_action *ta; ++ text_action a; + + /* It is not necessary to fill at the end of a section. */ + if (action == ta_fill && sec->size == offset) +@@ -5532,34 +5573,30 @@ text_action_add (text_action_list *l, + if (action == ta_fill && removed == 0) + return; + +- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) ++ a.action = action; ++ a.offset = offset; ++ ++ if (action == ta_fill) + { +- text_action *t = *m_p; ++ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); + +- if (action == ta_fill) ++ if (node) + { +- /* When the action is another fill at the same address, +- just increase the size. */ +- if (t->offset == offset && t->action == ta_fill) +- { +- t->removed_bytes += removed; +- return; +- } +- /* Fills need to happen before widens so that we don't +- insert fill bytes into the instruction stream. */ +- if (t->offset == offset && t->action == ta_widen_insn) +- break; ++ ta = (text_action *)node->value; ++ ta->removed_bytes += removed; ++ return; + } + } ++ else ++ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&a) == NULL); + +- /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; + ta->sec = sec; + ta->offset = offset; + ta->removed_bytes = removed; +- ta->next = (*m_p); +- *m_p = ta; ++ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); ++ ++l->count; + } + + +@@ -5570,7 +5607,6 @@ text_action_add_literal (text_action_list *l, + const literal_value *value, + int removed) + { +- text_action **m_p; + text_action *ta; + asection *sec = r_reloc_get_section (loc); + bfd_vma offset = loc->target_offset; +@@ -5578,14 +5614,6 @@ text_action_add_literal (text_action_list *l, + + BFD_ASSERT (action == ta_add_literal); + +- for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next) +- { +- if ((*m_p)->offset > offset +- && ((*m_p)->offset != offset +- || (*m_p)->virtual_offset > virtual_offset)) +- break; +- } +- + /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; +@@ -5594,8 +5622,10 @@ text_action_add_literal (text_action_list *l, + ta->virtual_offset = virtual_offset; + ta->value = *value; + ta->removed_bytes = removed; +- ta->next = (*m_p); +- *m_p = ta; ++ ++ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) == NULL); ++ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); ++ ++l->count; + } + + +@@ -5606,7 +5636,8 @@ text_action_add_literal (text_action_list *l, + so that each search may begin where the previous one left off. */ + + static int +-removed_by_actions (text_action **p_start_action, ++removed_by_actions (text_action_list *action_list, ++ text_action **p_start_action, + bfd_vma offset, + bfd_boolean before_fill) + { +@@ -5614,6 +5645,13 @@ removed_by_actions (text_action **p_start_action, + int removed = 0; + + r = *p_start_action; ++ if (r) ++ { ++ splay_tree_node node = splay_tree_lookup (action_list->tree, ++ (splay_tree_key)r); ++ BFD_ASSERT (node != NULL && r == (text_action *)node->value); ++ } ++ + while (r) + { + if (r->offset > offset) +@@ -5625,7 +5663,7 @@ removed_by_actions (text_action **p_start_action, + + removed += r->removed_bytes; + +- r = r->next; ++ r = action_next (action_list, r); + } + + *p_start_action = r; +@@ -5636,68 +5674,74 @@ removed_by_actions (text_action **p_start_action, + static bfd_vma + offset_with_removed_text (text_action_list *action_list, bfd_vma offset) + { +- text_action *r = action_list->head; +- return offset - removed_by_actions (&r, offset, FALSE); ++ text_action *r = action_first (action_list); ++ ++ return offset - removed_by_actions (action_list, &r, offset, FALSE); + } + + + static unsigned + action_list_count (text_action_list *action_list) + { +- text_action *r = action_list->head; +- unsigned count = 0; +- for (r = action_list->head; r != NULL; r = r->next) +- { +- count++; +- } +- return count; ++ return action_list->count; + } + +-static void +-map_removal_by_action (text_action_list *action_list) ++typedef struct map_action_fn_context_struct map_action_fn_context; ++struct map_action_fn_context_struct + { +- text_action *r; +- int removed = 0; ++ int removed; + removal_by_action_map map; + bfd_boolean eq_complete; ++}; + +- map.n_entries = 0; +- map.entry = bfd_malloc (action_list_count (action_list) * +- sizeof (removal_by_action_entry)); +- eq_complete = FALSE; ++static int ++map_action_fn (splay_tree_node node, void *p) ++{ ++ map_action_fn_context *ctx = p; ++ text_action *r = (text_action *)node->value; ++ removal_by_action_entry *ientry = ctx->map.entry + ctx->map.n_entries; + +- for (r = action_list->head; r;) ++ if (ctx->map.n_entries && (ientry - 1)->offset == r->offset) + { +- removal_by_action_entry *ientry = map.entry + map.n_entries; ++ --ientry; ++ } ++ else ++ { ++ ++ctx->map.n_entries; ++ ctx->eq_complete = FALSE; ++ ientry->offset = r->offset; ++ ientry->eq_removed_before_fill = ctx->removed; ++ } + +- if (map.n_entries && (ientry - 1)->offset == r->offset) ++ if (!ctx->eq_complete) ++ { ++ if (r->action != ta_fill || r->removed_bytes >= 0) + { +- --ientry; ++ ientry->eq_removed = ctx->removed; ++ ctx->eq_complete = TRUE; + } + else +- { +- ++map.n_entries; +- eq_complete = FALSE; +- ientry->offset = r->offset; +- ientry->eq_removed_before_fill = removed; +- } ++ ientry->eq_removed = ctx->removed + r->removed_bytes; ++ } + +- if (!eq_complete) +- { +- if (r->action != ta_fill || r->removed_bytes >= 0) +- { +- ientry->eq_removed = removed; +- eq_complete = TRUE; +- } +- else +- ientry->eq_removed = removed + r->removed_bytes; +- } ++ ctx->removed += r->removed_bytes; ++ ientry->removed = ctx->removed; ++ return 0; ++} + +- removed += r->removed_bytes; +- ientry->removed = removed; +- r = r->next; +- } +- action_list->map = map; ++static void ++map_removal_by_action (text_action_list *action_list) ++{ ++ map_action_fn_context ctx; ++ ++ ctx.removed = 0; ++ ctx.map.n_entries = 0; ++ ctx.map.entry = bfd_malloc (action_list_count (action_list) * ++ sizeof (removal_by_action_entry)); ++ ctx.eq_complete = FALSE; ++ ++ splay_tree_foreach (action_list->tree, map_action_fn, &ctx); ++ action_list->map = ctx.map; + } + + static int +@@ -5754,28 +5798,26 @@ offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) + static text_action * + find_insn_action (text_action_list *action_list, bfd_vma offset) + { +- text_action *t; +- for (t = action_list->head; t; t = t->next) ++ static const text_action_t action[] = + { +- if (t->offset == offset) +- { +- switch (t->action) +- { +- case ta_none: +- case ta_fill: +- break; +- case ta_remove_insn: +- case ta_remove_longcall: +- case ta_convert_longcall: +- case ta_narrow_insn: +- case ta_widen_insn: +- return t; +- case ta_remove_literal: +- case ta_add_literal: +- BFD_ASSERT (0); +- break; +- } +- } ++ ta_convert_longcall, ++ ta_remove_longcall, ++ ta_widen_insn, ++ ta_narrow_insn, ++ ta_remove_insn, ++ }; ++ text_action a; ++ unsigned i; ++ ++ a.offset = offset; ++ for (i = 0; i < sizeof (action) / sizeof (*action); ++i) ++ { ++ splay_tree_node node; ++ ++ a.action = action[i]; ++ node = splay_tree_lookup (action_list->tree, (splay_tree_key)&a); ++ if (node) ++ return (text_action *)node->value; + } + return NULL; + } +@@ -5784,40 +5826,50 @@ find_insn_action (text_action_list *action_list, bfd_vma offset) + #if DEBUG + + static void +-print_action_list (FILE *fp, text_action_list *action_list) ++print_action (FILE *fp, text_action *r) ++{ ++ const char *t = "unknown"; ++ switch (r->action) ++ { ++ case ta_remove_insn: ++ t = "remove_insn"; break; ++ case ta_remove_longcall: ++ t = "remove_longcall"; break; ++ case ta_convert_longcall: ++ t = "convert_longcall"; break; ++ case ta_narrow_insn: ++ t = "narrow_insn"; break; ++ case ta_widen_insn: ++ t = "widen_insn"; break; ++ case ta_fill: ++ t = "fill"; break; ++ case ta_none: ++ t = "none"; break; ++ case ta_remove_literal: ++ t = "remove_literal"; break; ++ case ta_add_literal: ++ t = "add_literal"; break; ++ } ++ ++ fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", ++ r->sec->owner->filename, ++ r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); ++} ++ ++static int ++print_action_list_fn (splay_tree_node node, void *p) + { +- text_action *r; ++ text_action *r = (text_action *)node->value; + +- fprintf (fp, "Text Action\n"); +- for (r = action_list->head; r != NULL; r = r->next) +- { +- const char *t = "unknown"; +- switch (r->action) +- { +- case ta_remove_insn: +- t = "remove_insn"; break; +- case ta_remove_longcall: +- t = "remove_longcall"; break; +- case ta_convert_longcall: +- t = "convert_longcall"; break; +- case ta_narrow_insn: +- t = "narrow_insn"; break; +- case ta_widen_insn: +- t = "widen_insn"; break; +- case ta_fill: +- t = "fill"; break; +- case ta_none: +- t = "none"; break; +- case ta_remove_literal: +- t = "remove_literal"; break; +- case ta_add_literal: +- t = "add_literal"; break; +- } ++ print_action (p, r); ++ return 0; ++} + +- fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", +- r->sec->owner->filename, +- r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); +- } ++static void ++print_action_list (FILE *fp, text_action_list *action_list) ++{ ++ fprintf (fp, "Text Action\n"); ++ splay_tree_foreach (action_list->tree, print_action_list_fn, fp); + } + + #endif /* DEBUG */ +@@ -6071,8 +6123,8 @@ init_xtensa_relax_info (asection *sec) + relax_info->removed_list.head = NULL; + relax_info->removed_list.tail = NULL; + +- relax_info->action_list.head = NULL; +- ++ relax_info->action_list.tree = splay_tree_new (text_action_compare, ++ NULL, NULL); + relax_info->action_list.map.n_entries = 0; + relax_info->action_list.map.entry = NULL; + +@@ -7762,7 +7814,7 @@ compute_text_actions (bfd *abfd, + free_reloc_range_list (&relevant_relocs); + + #if DEBUG +- if (relax_info->action_list.head) ++ if (action_list_count (&relax_info->action_list)) + print_action_list (stderr, &relax_info->action_list); + #endif + +@@ -8263,6 +8315,54 @@ xlate_offset_with_removed_text (const xlate_map_t *map, + return e->new_address - e->orig_address + offset; + } + ++typedef struct xlate_map_context_struct xlate_map_context; ++struct xlate_map_context_struct ++{ ++ xlate_map_t *map; ++ xlate_map_entry_t *current_entry; ++ int removed; ++}; ++ ++static int ++xlate_map_fn (splay_tree_node node, void *p) ++{ ++ text_action *r = (text_action *)node->value; ++ xlate_map_context *ctx = p; ++ unsigned orig_size = 0; ++ ++ switch (r->action) ++ { ++ case ta_none: ++ case ta_remove_insn: ++ case ta_convert_longcall: ++ case ta_remove_literal: ++ case ta_add_literal: ++ break; ++ case ta_remove_longcall: ++ orig_size = 6; ++ break; ++ case ta_narrow_insn: ++ orig_size = 3; ++ break; ++ case ta_widen_insn: ++ orig_size = 2; ++ break; ++ case ta_fill: ++ break; ++ } ++ ctx->current_entry->size = ++ r->offset + orig_size - ctx->current_entry->orig_address; ++ if (ctx->current_entry->size != 0) ++ { ++ ctx->current_entry++; ++ ctx->map->entry_count++; ++ } ++ ctx->current_entry->orig_address = r->offset + orig_size; ++ ctx->removed += r->removed_bytes; ++ ctx->current_entry->new_address = r->offset + orig_size - ctx->removed; ++ ctx->current_entry->size = 0; ++ return 0; ++} + + /* Build a binary searchable offset translation map from a section's + action list. */ +@@ -8270,75 +8370,40 @@ xlate_offset_with_removed_text (const xlate_map_t *map, + static xlate_map_t * + build_xlate_map (asection *sec, xtensa_relax_info *relax_info) + { +- xlate_map_t *map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); + text_action_list *action_list = &relax_info->action_list; + unsigned num_actions = 0; +- text_action *r; +- int removed; +- xlate_map_entry_t *current_entry; ++ xlate_map_context ctx; + +- if (map == NULL) ++ ctx.map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); ++ ++ if (ctx.map == NULL) + return NULL; + + num_actions = action_list_count (action_list); +- map->entry = (xlate_map_entry_t *) ++ ctx.map->entry = (xlate_map_entry_t *) + bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1)); +- if (map->entry == NULL) ++ if (ctx.map->entry == NULL) + { +- free (map); ++ free (ctx.map); + return NULL; + } +- map->entry_count = 0; ++ ctx.map->entry_count = 0; + +- removed = 0; +- current_entry = &map->entry[0]; ++ ctx.removed = 0; ++ ctx.current_entry = &ctx.map->entry[0]; + +- current_entry->orig_address = 0; +- current_entry->new_address = 0; +- current_entry->size = 0; ++ ctx.current_entry->orig_address = 0; ++ ctx.current_entry->new_address = 0; ++ ctx.current_entry->size = 0; + +- for (r = action_list->head; r != NULL; r = r->next) +- { +- unsigned orig_size = 0; +- switch (r->action) +- { +- case ta_none: +- case ta_remove_insn: +- case ta_convert_longcall: +- case ta_remove_literal: +- case ta_add_literal: +- break; +- case ta_remove_longcall: +- orig_size = 6; +- break; +- case ta_narrow_insn: +- orig_size = 3; +- break; +- case ta_widen_insn: +- orig_size = 2; +- break; +- case ta_fill: +- break; +- } +- current_entry->size = +- r->offset + orig_size - current_entry->orig_address; +- if (current_entry->size != 0) +- { +- current_entry++; +- map->entry_count++; +- } +- current_entry->orig_address = r->offset + orig_size; +- removed += r->removed_bytes; +- current_entry->new_address = r->offset + orig_size - removed; +- current_entry->size = 0; +- } ++ splay_tree_foreach (action_list->tree, xlate_map_fn, &ctx); + +- current_entry->size = (bfd_get_section_limit (sec->owner, sec) +- - current_entry->orig_address); +- if (current_entry->size != 0) +- map->entry_count++; ++ ctx.current_entry->size = (bfd_get_section_limit (sec->owner, sec) ++ - ctx.current_entry->orig_address); ++ if (ctx.current_entry->size != 0) ++ ctx.map->entry_count++; + +- return map; ++ return ctx.map; + } + + +@@ -9302,6 +9367,16 @@ move_shared_literal (asection *sec, + + /* Second relaxation pass. */ + ++static int ++action_remove_bytes_fn (splay_tree_node node, void *p) ++{ ++ bfd_size_type *final_size = p; ++ text_action *action = (text_action *)node->value; ++ ++ *final_size -= action->removed_bytes; ++ return 0; ++} ++ + /* Modify all of the relocations to point to the right spot, and if this + is a relaxable section, delete the unwanted literals and fix the + section size. */ +@@ -9334,7 +9409,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + + internal_relocs = retrieve_internal_relocs (abfd, sec, + link_info->keep_memory); +- if (!internal_relocs && !relax_info->action_list.head) ++ if (!internal_relocs && !action_list_count (&relax_info->action_list)) + return TRUE; + + contents = retrieve_contents (abfd, sec, link_info->keep_memory); +@@ -9412,6 +9487,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + } + /* Update the action so that the code that moves + the contents will do the right thing. */ ++ /* ta_remove_longcall and ta_remove_insn actions are ++ grouped together in the tree as well as ++ ta_convert_longcall and ta_none, so that changes below ++ can be done w/o removing and reinserting action into ++ the tree. */ ++ + if (action->action == ta_remove_longcall) + action->action = ta_remove_insn; + else +@@ -9584,13 +9665,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + + if ((relax_info->is_relaxable_literal_section + || relax_info->is_relaxable_asm_section) +- && relax_info->action_list.head) ++ && action_list_count (&relax_info->action_list)) + { + /* Walk through the planned actions and build up a table + of move, copy and fill records. Use the move, copy and + fill records to perform the actions once. */ + +- int removed = 0; + bfd_size_type final_size, copy_size, orig_insn_size; + bfd_byte *scratch = NULL; + bfd_byte *dup_contents = NULL; +@@ -9601,15 +9681,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */ + bfd_vma dup_dot = 0; + +- text_action *action = relax_info->action_list.head; ++ text_action *action; + + final_size = sec->size; +- for (action = relax_info->action_list.head; action; +- action = action->next) +- { +- final_size -= action->removed_bytes; +- } + ++ splay_tree_foreach (relax_info->action_list.tree, ++ action_remove_bytes_fn, &final_size); + scratch = (bfd_byte *) bfd_zmalloc (final_size); + dup_contents = (bfd_byte *) bfd_zmalloc (final_size); + +@@ -9618,8 +9695,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + print_action_list (stderr, &relax_info->action_list); + #endif + +- for (action = relax_info->action_list.head; action; +- action = action->next) ++ for (action = action_first (&relax_info->action_list); action; ++ action = action_next (&relax_info->action_list, action)) + { + virtual_action = FALSE; + if (action->offset > orig_dot) +@@ -9748,7 +9825,6 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + break; + } + +- removed += action->removed_bytes; + BFD_ASSERT (dup_dot <= final_size); + BFD_ASSERT (orig_dot <= orig_size); + } +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch b/packages/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch new file mode 100644 index 0000000..043ff4d --- /dev/null +++ b/packages/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch @@ -0,0 +1,345 @@ +From cbe53e134d4c3a656880a906738ce19fdcd38e8b Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 1 May 2015 11:39:12 +0300 +Subject: [PATCH] xtensa: optimize trampolines relaxation + +Currently every fixup in the current segment is checked when relaxing +trampoline frag. This is very expensive. Make a searchable array of +fixups pointing at potentially oversized jumps at the beginning of every +relaxation pass and only check subset of this cache in the reach of +single jump from the trampoline frag currently being relaxed. + +Original profile: + +% time self children called name +----------------------------------------- + 370.16 593.38 12283048/12283048 relax_segment + 98.4 370.16 593.38 12283048 xtensa_relax_frag + 58.91 269.26 2691463834/2699602236 xtensa_insnbuf_from_chars + 68.35 68.17 811266668/813338977 S_GET_VALUE + 36.85 29.51 2684369246/2685538060 xtensa_opcode_decode + 28.34 8.84 2684369246/2685538060 xtensa_format_get_slot + 12.39 5.94 2691463834/2699775044 xtensa_format_decode + 0.03 4.60 4101109/4101109 relax_frag_for_align + 0.18 1.76 994617/994617 relax_frag_immed + 0.07 0.09 24556277/24851220 new_logical_line + 0.06 0.00 12283048/14067410 as_where + 0.04 0.00 7094588/15460506 xtensa_format_num_slots + 0.00 0.00 1/712477 xtensa_insnbuf_alloc +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.51 7.47 12283048/12283048 relax_segment + 58.0 0.51 7.47 12283048 xtensa_relax_frag + 0.02 4.08 4101109/4101109 relax_frag_for_align + 0.18 1.39 994617/994617 relax_frag_immed + 0.01 0.98 555/555 xtensa_cache_relaxable_fixups + 0.21 0.25 7094588/16693271 xtensa_insnbuf_from_chars + 0.06 0.12 24556277/24851220 new_logical_line + 0.06 0.00 7094588/15460506 xtensa_format_num_slots + 0.02 0.04 7094588/16866079 xtensa_format_decode + 0.05 0.00 12283048/14067410 as_where + 0.00 0.00 1/712477 xtensa_insnbuf_alloc + 0.00 0.00 93808/93808 xtensa_find_first_cached_fixup +----------------------------------------- + +2015-05-02 Max Filippov +gas/ + * config/tc-xtensa.c (cached_fixupS, fixup_cacheS): New typedefs. + (struct cached_fixup, struct fixup_cache): New structures. + (fixup_order, xtensa_make_cached_fixup), + (xtensa_realloc_fixup_cache, xtensa_cache_relaxable_fixups), + (xtensa_find_first_cached_fixup, xtensa_delete_cached_fixup), + (xtensa_add_cached_fixup): New functions. + (xtensa_relax_frag): Cache fixups pointing at potentially + oversized jumps at the beginning of every relaxation pass. Only + check subset of this cache in the reach of single jump from the + trampoline frag currently being relaxed. + +Signed-off-by: Max Filippov +--- +Backported from: b76f99d702c3501ac320396ea06bc7f9237173c3 +Changes to ChangeLog are dropped. + + gas/config/tc-xtensa.c | 220 +++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 194 insertions(+), 26 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 3e85b69..31c0b6b 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -8785,6 +8785,154 @@ static long relax_frag_for_align (fragS *, long); + static long relax_frag_immed + (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean); + ++typedef struct cached_fixup cached_fixupS; ++struct cached_fixup ++{ ++ int addr; ++ int target; ++ int delta; ++ fixS *fixP; ++}; ++ ++typedef struct fixup_cache fixup_cacheS; ++struct fixup_cache ++{ ++ cached_fixupS *fixups; ++ unsigned n_fixups; ++ unsigned n_max; ++ ++ segT seg; ++ fragS *first_frag; ++}; ++ ++static int fixup_order (const void *a, const void *b) ++{ ++ const cached_fixupS *pa = a; ++ const cached_fixupS *pb = b; ++ ++ if (pa->addr == pb->addr) ++ { ++ if (pa->target == pb->target) ++ { ++ if (pa->fixP->fx_r_type == pb->fixP->fx_r_type) ++ return 0; ++ return pa->fixP->fx_r_type < pb->fixP->fx_r_type ? -1 : 1; ++ } ++ return pa->target - pb->target; ++ } ++ return pa->addr - pb->addr; ++} ++ ++static bfd_boolean xtensa_make_cached_fixup (cached_fixupS *o, fixS *fixP) ++{ ++ xtensa_isa isa = xtensa_default_isa; ++ int addr = fixP->fx_frag->fr_address; ++ int target; ++ int delta; ++ symbolS *s = fixP->fx_addsy; ++ int slot; ++ xtensa_format fmt; ++ xtensa_opcode opcode; ++ ++ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || ++ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) ++ return FALSE; ++ target = S_GET_VALUE (s); ++ delta = target - addr; ++ ++ if (abs(delta) < J_RANGE / 2) ++ return FALSE; ++ ++ xtensa_insnbuf_from_chars (isa, trampoline_buf, ++ (unsigned char *) fixP->fx_frag->fr_literal + ++ fixP->fx_where, 0); ++ fmt = xtensa_format_decode (isa, trampoline_buf); ++ gas_assert (fmt != XTENSA_UNDEFINED); ++ slot = fixP->tc_fix_data.slot; ++ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); ++ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); ++ if (opcode != xtensa_j_opcode) ++ return FALSE; ++ ++ o->addr = addr; ++ o->target = target; ++ o->delta = delta; ++ o->fixP = fixP; ++ ++ return TRUE; ++} ++ ++static void xtensa_realloc_fixup_cache (fixup_cacheS *cache, unsigned add) ++{ ++ if (cache->n_fixups + add > cache->n_max) ++ { ++ cache->n_max = (cache->n_fixups + add) * 2; ++ cache->fixups = xrealloc (cache->fixups, ++ sizeof (*cache->fixups) * cache->n_max); ++ } ++} ++ ++static void xtensa_cache_relaxable_fixups (fixup_cacheS *cache, ++ segment_info_type *seginfo) ++{ ++ fixS *fixP; ++ ++ cache->n_fixups = 0; ++ ++ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ { ++ xtensa_realloc_fixup_cache (cache, 1); ++ ++ if (xtensa_make_cached_fixup (cache->fixups + cache->n_fixups, fixP)) ++ ++cache->n_fixups; ++ } ++ qsort (cache->fixups, cache->n_fixups, sizeof (*cache->fixups), fixup_order); ++} ++ ++static unsigned xtensa_find_first_cached_fixup (const fixup_cacheS *cache, ++ int addr) ++{ ++ unsigned a = 0; ++ unsigned b = cache->n_fixups; ++ ++ while (b - a > 1) ++ { ++ unsigned c = (a + b) / 2; ++ ++ if (cache->fixups[c].addr < addr) ++ a = c; ++ else ++ b = c; ++ } ++ return a; ++} ++ ++static void xtensa_delete_cached_fixup (fixup_cacheS *cache, unsigned i) ++{ ++ memmove (cache->fixups + i, cache->fixups + i + 1, ++ (cache->n_fixups - i - 1) * sizeof (*cache->fixups)); ++ --cache->n_fixups; ++} ++ ++static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP) ++{ ++ cached_fixupS o; ++ unsigned i; ++ ++ if (!xtensa_make_cached_fixup (&o, fixP)) ++ return FALSE; ++ xtensa_realloc_fixup_cache (cache, 1); ++ i = xtensa_find_first_cached_fixup (cache, o.addr); ++ if (i < cache->n_fixups) ++ { ++ ++i; ++ memmove (cache->fixups + i + 1, cache->fixups + i, ++ (cache->n_fixups - i) * sizeof (*cache->fixups)); ++ } ++ cache->fixups[i] = o; ++ ++cache->n_fixups; ++ return TRUE; ++} + + /* Return the number of bytes added to this fragment, given that the + input has been stretched already by "stretch". */ +@@ -8896,35 +9044,42 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + case RELAX_TRAMPOLINE: + if (fragP->tc_frag_data.relax_seen) + { +- segment_info_type *seginfo = seg_info (now_seg); +- fragS *fP; /* The out-of-range jump. */ +- fixS *fixP; ++ static fixup_cacheS fixup_cache; ++ segment_info_type *seginfo = seg_info (now_seg); ++ int trampaddr = fragP->fr_address + fragP->fr_fix; ++ int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE; ++ unsigned i; ++ ++ if (now_seg != fixup_cache.seg || ++ fragP == fixup_cache.first_frag || ++ fixup_cache.first_frag == NULL) ++ { ++ xtensa_cache_relaxable_fixups (&fixup_cache, seginfo); ++ fixup_cache.seg = now_seg; ++ fixup_cache.first_frag = fragP; ++ } + + /* Scan for jumps that will not reach. */ +- for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr); ++ i < fixup_cache.n_fixups; ++i) ++ + { +- symbolS *s = fixP->fx_addsy; +- xtensa_opcode opcode; +- int target; +- int addr; +- int delta; +- +- if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || +- fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) +- continue; +- xtensa_insnbuf_from_chars (isa, trampoline_buf, +- (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, +- 0); +- fmt = xtensa_format_decode (isa, trampoline_buf); +- gas_assert (fmt != XTENSA_UNDEFINED); +- slot = fixP->tc_fix_data.slot; +- xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); +- opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); +- if (opcode != xtensa_j_opcode) ++ fixS *fixP = fixup_cache.fixups[i].fixP; ++ int target = fixup_cache.fixups[i].target; ++ int addr = fixup_cache.fixups[i].addr; ++ int delta = fixup_cache.fixups[i].delta + stretch; ++ ++ trampaddr = fragP->fr_address + fragP->fr_fix; ++ ++ if (addr + J_RANGE < trampaddr) + continue; +- target = S_GET_VALUE (s); +- addr = fixP->fx_frag->fr_address; +- delta = target - addr + stretch; ++ if (addr > trampaddr + J_RANGE) ++ break; ++ if (abs (delta) < J_RANGE) ++ continue; ++ ++ slot = fixP->tc_fix_data.slot; ++ + if (delta > J_RANGE || delta < -1 * J_RANGE) + { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ + struct trampoline_seg *ts = find_trampoline_seg (now_seg); +@@ -8978,14 +9133,13 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + } + if (tf->fragP == fragP) + { +- int trampaddr = fragP->fr_address + fragP->fr_fix; +- + if (abs (addr - trampaddr) < J_RANGE) + { /* The trampoline is in range of original; fix it! */ + fixS *newfixP; + int offset; + TInsn insn; + symbolS *lsym; ++ fragS *fP; /* The out-of-range jump. */ + + new_stretch += init_trampoline_frag (tf); + offset = fragP->fr_fix; /* Where to assemble the j insn. */ +@@ -9009,10 +9163,20 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + newfixP->tc_fix_data.X_add_symbol = lsym; + newfixP->tc_fix_data.X_add_number = offset; + newfixP->tc_fix_data.slot = slot; ++ ++ xtensa_delete_cached_fixup (&fixup_cache, i); ++ xtensa_add_cached_fixup (&fixup_cache, newfixP); ++ + /* Move the fix-up from the original j insn to this one. */ + fixP->fx_frag = fragP; + fixP->fx_where = fragP->fr_fix - 3; + fixP->tc_fix_data.slot = 0; ++ ++ xtensa_add_cached_fixup (&fixup_cache, fixP); ++ ++ /* re-do current fixup */ ++ --i; ++ + /* Adjust the jump around this trampoline (if present). */ + if (tf->fixP != NULL) + { +@@ -9027,6 +9191,8 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + fragP->fr_subtype = 0; + /* Remove from the trampoline_list. */ + prev->next = tf->next; ++ if (fragP == fixup_cache.first_frag) ++ fixup_cache.first_frag = NULL; + break; + } + } +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/packages/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch new file mode 100644 index 0000000..9ad6b3b --- /dev/null +++ b/packages/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch @@ -0,0 +1,57 @@ +From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 14 May 2015 05:22:55 +0300 +Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections + +elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were +made local, that results in link failure with the following message: + + BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line + 3372 in elf_xtensa_finish_dynamic_sections + +elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by +relocation type. Relocation types are not changed when symbol becomes +local, but its PLT references are added to GOT references and +plt.refcount is set to 0. Such symbol cannot be unreferences in the +elf_xtensa_gc_sweep_hook and its extra references make calculated GOT +relocations section size not match number of GOT relocations. + +Fix it by treating PLT reference as GOT reference when plt.refcount is +not positive. + +2015-05-14 Max Filippov +bfd/ + * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference + as GOT reference when plt.refcount is not positive. + +Signed-off-by: Max Filippov +--- +Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 +Changes to ChangeLog are dropped. + + bfd/elf32-xtensa.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 53af1c6..2523670 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, + { + if (is_plt) + { ++ /* If the symbol has been localized its plt.refcount got moved ++ to got.refcount. Handle it as GOT. */ + if (h->plt.refcount > 0) + h->plt.refcount--; ++ else ++ is_got = TRUE; + } +- else if (is_got) ++ if (is_got) + { + if (h->got.refcount > 0) + h->got.refcount--; +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/packages/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch new file mode 100644 index 0000000..4a3de2c --- /dev/null +++ b/packages/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch @@ -0,0 +1,56 @@ +From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 17 May 2015 06:46:15 +0300 +Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals + +When --text-section-literals is used and code in the .init or .fini +emits literal in the absence of .literal_position, xtensa_move_literals +segfaults. + +Check that search_frag is non-NULL in the xtensa_move_literals and +report error otherwise. + +2015-05-26 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Check that + search_frag is non-NULL. Report error if literal frag is not + found. + +Signed-off-by: Max Filippov +--- +Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 +Changes to ChangeLog are dropped. + + gas/config/tc-xtensa.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 31c0b6b..18307c1 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) + frchain_to = NULL; + frag_splice = &(frchain_from->frch_root); + +- while (!search_frag->tc_frag_data.literal_frag) ++ while (search_frag && !search_frag->tc_frag_data.literal_frag) + { + gas_assert (search_frag->fr_fix == 0 + || search_frag->fr_type == rs_align); + search_frag = search_frag->fr_next; + } + ++ if (!search_frag) ++ { ++ search_frag = frchain_from->frch_root; ++ as_bad_where (search_frag->fr_file, search_frag->fr_line, ++ _("literal pool location required for text-section-literals; specify with .literal_position")); ++ continue; ++ } ++ + gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype + == RELAX_LITERAL_POOL_BEGIN); + xtensa_switch_section_emit_state (&state, segment->seg, 0); +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/913-xtensa-add-auto-litpools-option.patch b/packages/binutils/2.24/913-xtensa-add-auto-litpools-option.patch new file mode 100644 index 0000000..f0199e1 --- /dev/null +++ b/packages/binutils/2.24/913-xtensa-add-auto-litpools-option.patch @@ -0,0 +1,698 @@ +From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Wed, 29 Jul 2015 17:42:54 +0300 +Subject: [PATCH] xtensa: add --auto-litpools option + +Auto-litpools is the automated version of text-section-literals: literal +pool candidate frags are planted every N frags and during relaxation +they are turned into actual literal pools where literals are moved to +become reachable for their first reference by L32R instruction. + +2015-08-12 David Weatherford +gas/ + * config/tc-xtensa.c (struct litpool_frag, struct litpool_seg): + New structures. + (xtensa_maybe_create_literal_pool_frag): New function. + (litpool_seg_list, auto_litpools, auto_litpool_limit) + (litpool_buf, litpool_slotbuf): New static variables. + (option_auto_litpools, option_no_auto_litpools) + (option_auto_litpool_limit): New enum identifiers. + (md_longopts): Add entries for auto-litpools, no-auto-litpools + and auto-litpool-limit. + (md_parse_option): Handle option_auto_litpools, + option_no_auto_litpools and option_auto_litpool_limit. + (md_show_usage): Add help for --[no-]auto-litpools and + --auto-litpool-limit. + (xtensa_mark_literal_pool_location): Record a place for literal + pool with a call to xtensa_maybe_create_literal_pool_frag. + (get_literal_pool_location): Find highest priority literal pool + or convert candidate to literal pool when auto-litpools are used. + (xg_assemble_vliw_tokens): Create literal pool after jump + instruction. + (xtensa_check_frag_count): Create candidate literal pool every + auto_litpool_limit frags. + (xtensa_relax_frag): Add jump around literals to non-empty + literal pool. + (xtensa_move_literals): Estimate literal pool addresses and move + unreachable literals closer to their users, converting candidate + to literal pool if needed. + (xtensa_switch_to_non_abs_literal_fragment): Only emit error + about missing .literal_position in case auto-litpools are not + used. + * config/tc-xtensa.h (xtensa_relax_statesE): New relaxation + state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN. + +2015-08-12 Max Filippov +gas/testsuite/ + * gas/xtensa/all.exp: Add auto-litpools to the list of xtensa + tests. + * gas/xtensa/auto-litpools.s: New file: auto-litpools test. + * gas/xtensa/auto-litpools.s: New file: auto-litpools test + result pattern. + +Signed-off-by: Max Filippov +--- +Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5 +Changes to ChangeLogs and documentation are dropped. + + gas/config/tc-xtensa.c | 432 ++++++++++++++++++++++++++++++- + gas/config/tc-xtensa.h | 1 + + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/auto-litpools.d | 12 + + gas/testsuite/gas/xtensa/auto-litpools.s | 13 + + 5 files changed, 454 insertions(+), 5 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d + create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 7311a05..b8b1e7d 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -440,6 +440,29 @@ bfd_boolean directive_state[] = + #endif + }; + ++/* A circular list of all potential and actual literal pool locations ++ in a segment. */ ++struct litpool_frag ++{ ++ struct litpool_frag *next; ++ struct litpool_frag *prev; ++ fragS *fragP; ++ addressT addr; ++ short priority; /* 1, 2, or 3 -- 1 is highest */ ++ short original_priority; ++}; ++ ++/* Map a segment to its litpool_frag list. */ ++struct litpool_seg ++{ ++ struct litpool_seg *next; ++ asection *seg; ++ struct litpool_frag frag_list; ++ int frag_count; /* since last litpool location */ ++}; ++ ++static struct litpool_seg litpool_seg_list; ++ + + /* Directive functions. */ + +@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean); + static void xtensa_maybe_create_trampoline_frag (void); + struct trampoline_frag; + static int init_trampoline_frag (struct trampoline_frag *); ++static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean); ++static bfd_boolean auto_litpools = FALSE; ++static int auto_litpool_limit = 10000; + + /* Alignment Functions. */ + +@@ -698,6 +724,10 @@ enum + + option_trampolines, + option_no_trampolines, ++ ++ option_auto_litpools, ++ option_no_auto_litpools, ++ option_auto_litpool_limit, + }; + + const char *md_shortopts = ""; +@@ -773,6 +803,10 @@ struct option md_longopts[] = + { "trampolines", no_argument, NULL, option_trampolines }, + { "no-trampolines", no_argument, NULL, option_no_trampolines }, + ++ { "auto-litpools", no_argument, NULL, option_auto_litpools }, ++ { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools }, ++ { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit }, ++ + { NULL, no_argument, NULL, 0 } + }; + +@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg) + use_trampolines = FALSE; + return 1; + ++ case option_auto_litpools: ++ auto_litpools = TRUE; ++ use_literal_section = FALSE; ++ return 1; ++ ++ case option_no_auto_litpools: ++ auto_litpools = FALSE; ++ auto_litpool_limit = -1; ++ return 1; ++ ++ case option_auto_litpool_limit: ++ { ++ int value = 0; ++ if (auto_litpool_limit < 0) ++ as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit")); ++ if (*arg == 0 || *arg == '-') ++ as_fatal (_("invalid auto-litpool-limit argument")); ++ value = strtol (arg, &arg, 10); ++ if (*arg != 0) ++ as_fatal (_("invalid auto-litpool-limit argument")); ++ if (value < 100 || value > 10000) ++ as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)")); ++ auto_litpool_limit = value; ++ auto_litpools = TRUE; ++ use_literal_section = FALSE; ++ return 1; ++ } ++ + default: + return 0; + } +@@ -986,7 +1048,12 @@ Xtensa options:\n\ + flix bundles\n\ + --rename-section old=new Rename section 'old' to 'new'\n\ + --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ +- when jumps do not reach their targets\n", stream); ++ when jumps do not reach their targets\n\ ++ --[no-]auto-litpools [Do not] automatically create literal pools\n\ ++ --auto-litpool-limit=\n\ ++ (range 100-10000) Maximum number of blocks of\n\ ++ instructions to emit between literal pool\n\ ++ locations; implies --auto-litpools flag\n", stream); + } + + +@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void) + pool_location = frag_now; + frag_now->tc_frag_data.lit_frchain = frchain_now; + frag_now->tc_frag_data.literal_frag = frag_now; ++ /* Just record this frag. */ ++ xtensa_maybe_create_literal_pool_frag (FALSE, FALSE); + frag_variant (rs_machine_dependent, 0, 0, + RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL); + xtensa_set_frag_assembly_state (frag_now); +@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode) + static fragS * + get_literal_pool_location (segT seg) + { ++ struct litpool_seg *lps = litpool_seg_list.next; ++ struct litpool_frag *lpf; ++ for ( ; lps && lps->seg->id != seg->id; lps = lps->next) ++ ; ++ if (lps) ++ { ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { /* Skip "candidates" for now. */ ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && ++ lpf->priority == 1) ++ return lpf->fragP; ++ } ++ /* Must convert a lower-priority pool. */ ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) ++ return lpf->fragP; ++ } ++ /* Still no match -- try for a low priority pool. */ ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) ++ return lpf->fragP; ++ } ++ } + return seg_info (seg)->tc_segment_info_data.literal_pool_loc; + } + +@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol; + frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset; + frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag; ++ if (tinsn->opcode == xtensa_l32r_opcode) ++ { ++ frag_now->tc_frag_data.literal_frags[slot] = ++ tinsn->tok[1].X_add_symbol->sy_frag; ++ } + if (tinsn->literal_space != 0) + xg_assemble_literal_space (tinsn->literal_space, slot); + frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg; +@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + frag_now->fr_symbol, frag_now->fr_offset, NULL); + xtensa_set_frag_assembly_state (frag_now); + xtensa_maybe_create_trampoline_frag (); ++ /* Always create one here. */ ++ xtensa_maybe_create_literal_pool_frag (TRUE, FALSE); + } + else if (is_branch && do_align_targets ()) + { +@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void) + clear_frag_count (); + unreachable_count = 0; + } ++ ++ /* We create an area for a possible literal pool every N (default 5000) ++ frags or so. */ ++ xtensa_maybe_create_literal_pool_frag (TRUE, TRUE); + } + + static xtensa_insnbuf trampoline_buf = NULL; + static xtensa_insnbuf trampoline_slotbuf = NULL; + ++static xtensa_insnbuf litpool_buf = NULL; ++static xtensa_insnbuf litpool_slotbuf = NULL; ++ + #define TRAMPOLINE_FRAG_SIZE 3000 + + static void +@@ -7410,6 +7518,135 @@ dump_trampolines (void) + } + } + ++static void dump_litpools (void) __attribute__ ((unused)); ++ ++static void ++dump_litpools (void) ++{ ++ struct litpool_seg *lps = litpool_seg_list.next; ++ struct litpool_frag *lpf; ++ ++ for ( ; lps ; lps = lps->next ) ++ { ++ printf("litpool seg %s\n", lps->seg->name); ++ for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next ) ++ { ++ fragS *litfrag = lpf->fragP->fr_next; ++ int count = 0; ++ while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END) ++ { ++ if (litfrag->fr_fix == 4) ++ count++; ++ litfrag = litfrag->fr_next; ++ } ++ printf(" %ld <%d:%d> (%d) [%d]: ", ++ lpf->addr, lpf->priority, lpf->original_priority, ++ lpf->fragP->fr_line, count); ++ //dump_frag(lpf->fragP); ++ } ++ } ++} ++ ++static void ++xtensa_maybe_create_literal_pool_frag (bfd_boolean create, ++ bfd_boolean only_if_needed) ++{ ++ struct litpool_seg *lps = litpool_seg_list.next; ++ fragS *fragP; ++ struct litpool_frag *lpf; ++ bfd_boolean needed = FALSE; ++ ++ if (use_literal_section || !auto_litpools) ++ return; ++ ++ for ( ; lps ; lps = lps->next ) ++ { ++ if (lps->seg == now_seg) ++ break; ++ } ++ ++ if (lps == NULL) ++ { ++ lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1); ++ lps->next = litpool_seg_list.next; ++ litpool_seg_list.next = lps; ++ lps->seg = now_seg; ++ lps->frag_list.next = &lps->frag_list; ++ lps->frag_list.prev = &lps->frag_list; ++ } ++ ++ lps->frag_count++; ++ ++ if (create) ++ { ++ if (only_if_needed) ++ { ++ if (past_xtensa_end || !use_transform() || ++ frag_now->tc_frag_data.is_no_transform) ++ { ++ return; ++ } ++ if (auto_litpool_limit <= 0) ++ { ++ /* Don't create a litpool based only on frag count. */ ++ return; ++ } ++ else if (lps->frag_count > auto_litpool_limit) ++ { ++ needed = TRUE; ++ } ++ else ++ { ++ return; ++ } ++ } ++ else ++ { ++ needed = TRUE; ++ } ++ } ++ ++ if (needed) ++ { ++ int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn. */ ++ /* Create a potential site for a literal pool. */ ++ frag_wane (frag_now); ++ frag_new (0); ++ xtensa_set_frag_assembly_state (frag_now); ++ fragP = frag_now; ++ fragP->tc_frag_data.lit_frchain = frchain_now; ++ fragP->tc_frag_data.literal_frag = fragP; ++ frag_var (rs_machine_dependent, size, size, ++ (only_if_needed) ? ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN : ++ RELAX_LITERAL_POOL_BEGIN, ++ NULL, 0, NULL); ++ frag_now->tc_frag_data.lit_seg = now_seg; ++ frag_variant (rs_machine_dependent, 0, 0, ++ RELAX_LITERAL_POOL_END, NULL, 0, NULL); ++ xtensa_set_frag_assembly_state (frag_now); ++ } ++ else ++ { ++ /* RELAX_LITERAL_POOL_BEGIN frag is being created; ++ just record it here. */ ++ fragP = frag_now; ++ } ++ ++ lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag)); ++ /* Insert at tail of circular list. */ ++ lpf->addr = 0; ++ lps->frag_list.prev->next = lpf; ++ lpf->next = &lps->frag_list; ++ lpf->prev = lps->frag_list.prev; ++ lps->frag_list.prev = lpf; ++ lpf->fragP = fragP; ++ lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1; ++ lpf->original_priority = lpf->priority; ++ ++ lps->frag_count = 0; ++} ++ + static void + xtensa_cleanup_align_frags (void) + { +@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + break; + + case RELAX_LITERAL_POOL_BEGIN: ++ if (fragP->fr_var != 0) ++ { ++ /* We have a converted "candidate" literal pool; ++ assemble a jump around it. */ ++ TInsn insn; ++ if (!litpool_slotbuf) ++ { ++ litpool_buf = xtensa_insnbuf_alloc (isa); ++ litpool_slotbuf = xtensa_insnbuf_alloc (isa); ++ } ++ new_stretch += 3; ++ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ ++ fragP->tc_frag_data.is_insn = TRUE; ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol, ++ fragP->fr_fix); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf); ++ xtensa_insnbuf_to_chars (isa, litpool_buf, ++ (unsigned char *)fragP->fr_literal + ++ fragP->fr_fix, 3); ++ fragP->fr_fix += 3; ++ fragP->fr_var -= 3; ++ /* Add a fix-up. */ ++ fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE, ++ BFD_RELOC_XTENSA_SLOT0_OP); ++ } ++ break; ++ + case RELAX_LITERAL_POOL_END: ++ case RELAX_LITERAL_POOL_CANDIDATE_BEGIN: + case RELAX_MAYBE_UNREACHABLE: + case RELAX_MAYBE_DESIRE_ALIGN: + /* No relaxation required. */ +@@ -10789,12 +11060,115 @@ xtensa_move_literals (void) + segT dest_seg; + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; ++ struct litpool_seg *lps; + + mark_literal_frags (literal_head->next); + + if (use_literal_section) + return; + ++ /* Assign addresses (rough estimates) to the potential literal pool locations ++ and create new ones if the gaps are too large. */ ++ ++ for (lps = litpool_seg_list.next; lps; lps = lps->next) ++ { ++ frchainS *frchP = seg_info (lps->seg)->frchainP; ++ struct litpool_frag *lpf = lps->frag_list.next; ++ addressT addr = 0; ++ ++ for ( ; frchP; frchP = frchP->frch_next) ++ { ++ fragS *fragP; ++ for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next) ++ { ++ if (lpf && fragP == lpf->fragP) ++ { ++ gas_assert(fragP->fr_type == rs_machine_dependent && ++ (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN || ++ fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)); ++ /* Found a litpool location. */ ++ lpf->addr = addr; ++ lpf = lpf->next; ++ } ++ if (fragP->fr_type == rs_machine_dependent && ++ fragP->fr_subtype == RELAX_SLOTS) ++ { ++ int slot; ++ for (slot = 0; slot < MAX_SLOTS; slot++) ++ { ++ if (fragP->tc_frag_data.literal_frags[slot]) ++ { ++ /* L32R; point its literal to the nearest litpool ++ preferring non-"candidate" positions to avoid ++ the jump-around. */ ++ fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; ++ struct litpool_frag *lp = lpf->prev; ++ if (!lp->fragP) ++ { ++ break; ++ } ++ while (lp->fragP->fr_subtype == ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN) ++ { ++ lp = lp->prev; ++ if (lp->fragP == NULL) ++ { ++ /* End of list; have to bite the bullet. ++ Take the nearest. */ ++ lp = lpf->prev; ++ break; ++ } ++ /* Does it (conservatively) reach? */ ++ if (addr - lp->addr <= 128 * 1024) ++ { ++ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) ++ { ++ /* Found a good one. */ ++ break; ++ } ++ else if (lp->prev->fragP && ++ addr - lp->prev->addr > 128 * 1024) ++ { ++ /* This is still a "candidate" but the next one ++ will be too far away, so revert to the nearest ++ one, convert it and add the jump around. */ ++ fragS *poolbeg; ++ fragS *poolend; ++ symbolS *lsym; ++ char label[10 + 2 * sizeof (fragS *)]; ++ lp = lpf->prev; ++ poolbeg = lp->fragP; ++ lp->priority = 1; ++ poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; ++ poolend = poolbeg->fr_next; ++ gas_assert (poolend->fr_type == rs_machine_dependent && ++ poolend->fr_subtype == RELAX_LITERAL_POOL_END); ++ /* Create a local symbol pointing to the ++ end of the pool. */ ++ sprintf (label, ".L0_LT_%p", poolbeg); ++ lsym = (symbolS *)local_symbol_make (label, lps->seg, ++ 0, poolend); ++ poolbeg->fr_symbol = lsym; ++ /* Rest is done in xtensa_relax_frag. */ ++ } ++ } ++ } ++ if (! litfrag->tc_frag_data.literal_frag) ++ { ++ /* Take earliest use of this literal to avoid ++ forward refs. */ ++ litfrag->tc_frag_data.literal_frag = lp->fragP; ++ } ++ } ++ } ++ } ++ addr += fragP->fr_fix; ++ if (fragP->fr_type == rs_fill) ++ addr += fragP->fr_offset; ++ } ++ } ++ } ++ + for (segment = literal_head->next; segment; segment = segment->next) + { + /* Keep the literals for .init and .fini in separate sections. */ +@@ -10839,9 +11213,6 @@ xtensa_move_literals (void) + while (search_frag != frag_now) + { + next_frag = search_frag->fr_next; +- +- /* First, move the frag out of the literal section and +- to the appropriate place. */ + if (search_frag->tc_frag_data.literal_frag) + { + literal_pool = search_frag->tc_frag_data.literal_frag; +@@ -10849,8 +11220,56 @@ xtensa_move_literals (void) + frchain_to = literal_pool->tc_frag_data.lit_frchain; + gas_assert (frchain_to); + } ++ ++ if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0) ++ { ++ /* Skip empty fill frags. */ ++ *frag_splice = next_frag; ++ search_frag = next_frag; ++ continue; ++ } ++ ++ if (search_frag->fr_type == rs_align) ++ { ++ /* Skip alignment frags, because the pool as a whole will be ++ aligned if used, and we don't want to force alignment if the ++ pool is unused. */ ++ *frag_splice = next_frag; ++ search_frag = next_frag; ++ continue; ++ } ++ ++ /* First, move the frag out of the literal section and ++ to the appropriate place. */ ++ ++ /* Insert an aligmnent frag at start of pool. */ ++ if (literal_pool->fr_next->fr_type == rs_machine_dependent && ++ literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END) ++ { ++ segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg; ++ emit_state prev_state; ++ fragS *prev_frag; ++ fragS *align_frag; ++ xtensa_switch_section_emit_state (&prev_state, pool_seg, 0); ++ prev_frag = frag_now; ++ frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL); ++ align_frag = frag_now; ++ frag_align (2, 0, 0); ++ /* Splice it into the right place. */ ++ prev_frag->fr_next = align_frag->fr_next; ++ align_frag->fr_next = literal_pool->fr_next; ++ literal_pool->fr_next = align_frag; ++ /* Insert after this one. */ ++ literal_pool->tc_frag_data.literal_frag = align_frag; ++ xtensa_restore_emit_state (&prev_state); ++ } + insert_after = literal_pool->tc_frag_data.literal_frag; + dest_seg = insert_after->fr_next->tc_frag_data.lit_seg; ++ /* Skip align frag. */ ++ if (insert_after->fr_next->fr_type == rs_align) ++ { ++ insert_after = insert_after->fr_next; ++ } + + *frag_splice = next_frag; + search_frag->fr_next = insert_after->fr_next; +@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) + && !recursive + && !is_init && ! is_fini) + { +- as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); ++ if (!auto_litpools) ++ { ++ as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); ++ } + + /* When we mark a literal pool location, we want to put a frag in + the literal pool that points to it. But to do that, we want to +diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h +index b2e43fa..290d902 100644 +--- a/gas/config/tc-xtensa.h ++++ b/gas/config/tc-xtensa.h +@@ -124,6 +124,7 @@ enum xtensa_relax_statesE + + RELAX_LITERAL_POOL_BEGIN, + RELAX_LITERAL_POOL_END, ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN, + /* Technically these are not relaxations at all but mark a location + to store literals later. Note that fr_var stores the frchain for + BEGIN frags and fr_var stores now_seg for END frags. */ +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index d197ec8..db39629 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -100,5 +100,6 @@ if [istarget xtensa*-*-*] then { + run_dump_test "jlong" + run_dump_test "trampoline" ++ run_dump_test "auto-litpools" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d +new file mode 100644 +index 0000000..4d1a690 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/auto-litpools.d +@@ -0,0 +1,12 @@ ++#as: --auto-litpools ++#objdump: -d ++#name: auto literal pool placement ++ ++.*: +file format .*xtensa.* ++#... ++.*4:.*l32r.a2, 0 .* ++#... ++.*3e437:.*j.3e440 .* ++#... ++.*40750:.*l32r.a2, 3e43c .* ++#... +diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s +new file mode 100644 +index 0000000..9a5b26b +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/auto-litpools.s +@@ -0,0 +1,13 @@ ++ .text ++ .align 4 ++ .literal .L0, 0x12345 ++ .literal .L1, 0x12345 ++ ++f: ++ l32r a2, .L0 ++ .rep 44000 ++ _nop ++ _nop ++ .endr ++ l32r a2, .L1 ++ ret +-- +1.8.1.4 + diff --git a/packages/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch b/packages/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch new file mode 100644 index 0000000..2955e11 --- /dev/null +++ b/packages/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch @@ -0,0 +1,47 @@ +From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 2 Feb 2016 17:11:38 +0300 +Subject: [PATCH] xtensa: fix signedness of gas relocations + +Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation +offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations +substituted for BFD_RELOC_*. This made it impossible to encode arbitrary +8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc +directive. Revert this part and add test. + +gas/ +2016-02-03 Max Filippov + * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* + substitutions for BFD_RELOC_* as unsigned. + +Signed-off-by: Max Filippov +--- + gas/config/tc-xtensa.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index a119871..36a06cc 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + default: + break; +-- +2.1.4 + diff --git a/packages/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch b/packages/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..656373f --- /dev/null +++ b/packages/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,71 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] xtensa: fix .init/.fini literals moving + +Despite the documentation and the comment in xtensa_move_literals, in +the presence of --text-section-literals and --auto-litpools literals are +moved from the separate literal sections into .init and .fini, because +the check in the xtensa_move_literals is incorrect. + +This moving was broken with introduction of auto litpools: some literals +now may be lost. This happens because literal frags emitted from .init +and .fini are not closed when new .literal_position marks new literal +pool. Then frag_align(2, 0, 0) changes type of the last literal frag to +rs_align. rs_align frags are skipped in the xtensa_move_literals. As a +result fixups against such literals are not moved out of .init.literal/ +.fini.literal sections producing the following assembler error: + + test.S: Warning: fixes not all moved from .init.literal + test.S: Internal error! + +Fix check for .init.literal/.fini.literal in the xtensa_move_literals +and don't let it move literals from there in the presence of +--text-section-literals or --auto-litpools. + +2016-02-17 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 36a06cc..5773634 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; + struct litpool_seg *lps; ++ const char *init_name = INIT_SECTION_NAME; ++ const char *fini_name = FINI_SECTION_NAME; ++ int init_name_len = strlen(init_name); ++ int fini_name_len = strlen(fini_name); + + mark_literal_frags (literal_head->next); + +@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) + + for (segment = literal_head->next; segment; segment = segment->next) + { ++ const char *seg_name = segment_name (segment->seg); ++ + /* Keep the literals for .init and .fini in separate sections. */ +- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) +- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) ++ if ((!memcmp (seg_name, init_name, init_name_len) && ++ !strcmp (seg_name + init_name_len, ".literal")) || ++ (!memcmp (seg_name, fini_name, fini_name_len) && ++ !strcmp (seg_name + fini_name_len, ".literal"))) + continue; + + frchain_from = seg_info (segment->seg)->frchainP; +-- +2.1.4 + diff --git a/packages/binutils/2.24/version.desc b/packages/binutils/2.24/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils/2.24/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils/2.25.1/120-sh-conf.patch b/packages/binutils/2.25.1/120-sh-conf.patch new file mode 100644 index 0000000..c12a023 --- /dev/null +++ b/packages/binutils/2.25.1/120-sh-conf.patch @@ -0,0 +1,33 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +diff --git a/configure b/configure +index 87677bc..2d916f1 100755 +--- a/configure ++++ b/configure +@@ -3812,7 +3812,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +diff --git a/configure.ac b/configure.ac +index 8fe0eca..b10a99f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1140,7 +1140,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.25.1/300-001_ld_makefile_patch.patch b/packages/binutils/2.25.1/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..2a1320c --- /dev/null +++ b/packages/binutils/2.25.1/300-001_ld_makefile_patch.patch @@ -0,0 +1,26 @@ +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 9575f1f..84df0bf 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -54,7 +54,7 @@ endif + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 9f56ca1..272860f 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.25.1/300-012_check_ldrunpath_length.patch b/packages/binutils/2.25.1/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..f1f31af --- /dev/null +++ b/packages/binutils/2.25.1/300-012_check_ldrunpath_length.patch @@ -0,0 +1,22 @@ +diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em +index 137446f..bb8391a 100644 +--- a/ld/emultempl/elf32.em ++++ b/ld/emultempl/elf32.em +@@ -1195,6 +1195,8 @@ fragment <link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.25.1/310-fix-gold-pthreads-typo.patch b/packages/binutils/2.25.1/310-fix-gold-pthreads-typo.patch new file mode 100644 index 0000000..f2e6ff2 --- /dev/null +++ b/packages/binutils/2.25.1/310-fix-gold-pthreads-typo.patch @@ -0,0 +1,14 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 +@@ -102,9 +102,9 @@ + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); + #ifdef PTHREAD_MUTEX_ADAPTIVE_NP +- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); ++ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) +- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); ++ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); + #endif + + err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/packages/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/packages/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch new file mode 100644 index 0000000..f9a8af6 --- /dev/null +++ b/packages/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch @@ -0,0 +1,11 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2015-10-20 22:39:36.371169400 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:39:38.182772700 +0100 +@@ -101,7 +101,7 @@ + int err = pthread_mutexattr_init(&attr); + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); +-#ifdef PTHREAD_MUTEX_ADAPTIVE_NP ++#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) + err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) + gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/packages/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch b/packages/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch new file mode 100644 index 0000000..af4032a --- /dev/null +++ b/packages/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch @@ -0,0 +1,102 @@ +diff -urN binutils-2.25.1.orig/binutils/configure binutils-2.25.1/binutils/configure +--- binutils-2.25.1.orig/binutils/configure 2015-10-25 13:18:46.249052806 +0000 ++++ binutils-2.25.1/binutils/configure 2015-10-25 13:39:21.339034801 +0000 +@@ -12067,6 +12067,7 @@ + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12227,6 +12228,8 @@ + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" + # If we haven't got the data from the intl directory, +diff -urN binutils-2.25.1.orig/binutils/configure.ac binutils-2.25.1/binutils/configure.ac +--- binutils-2.25.1.orig/binutils/configure.ac 2015-10-25 13:18:46.249052806 +0000 ++++ binutils-2.25.1/binutils/configure.ac 2015-10-25 13:38:52.969035216 +0000 +@@ -87,7 +87,10 @@ + fi + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" + ZW_GNU_GETTEXT_SISTER_DIR +diff -urN binutils-2.25.1.orig/gas/configure binutils-2.25.1/gas/configure +--- binutils-2.25.1.orig/gas/configure 2015-10-25 13:18:46.389052803 +0000 ++++ binutils-2.25.1/gas/configure 2015-10-25 15:16:55.988949456 +0000 +@@ -12795,6 +12795,7 @@ + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12955,6 +12956,8 @@ + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja" + # If we haven't got the data from the intl directory, +diff -urN binutils-2.25.1.orig/gas/configure.ac binutils-2.25.1/gas/configure.ac +--- binutils-2.25.1.orig/gas/configure.ac 2015-10-25 15:15:06.000000000 +0000 ++++ binutils-2.25.1/gas/configure.ac 2015-10-25 14:45:32.000000000 +0000 +@@ -717,7 +717,10 @@ + AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja" + ZW_GNU_GETTEXT_SISTER_DIR +diff -urN binutils-2.25.1.orig/ld/configure binutils-2.25.1/ld/configure +--- binutils-2.25.1.orig/ld/configure 2015-10-25 13:18:47.399052788 +0000 ++++ binutils-2.25.1/ld/configure 2015-10-25 15:17:06.472282637 +0000 +@@ -16071,6 +16071,7 @@ + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -16231,6 +16232,8 @@ + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +diff -urN binutils-2.25.1.orig/ld/configure.ac binutils-2.25.1/ld/configure.ac +--- binutils-2.25.1.orig/ld/configure.ac 2015-10-25 13:18:47.415719456 +0000 ++++ binutils-2.25.1/ld/configure.ac 2015-10-25 15:14:43.000000000 +0000 +@@ -173,7 +173,10 @@ + AC_EXEEXT + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + AM_MAINTAINER_MODE + AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/packages/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/packages/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch new file mode 100644 index 0000000..33441cc --- /dev/null +++ b/packages/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch @@ -0,0 +1,11 @@ +--- binutils-2.25.orig/gold/binary.cc 2015-06-09 10:48:32.000000000 +0100 ++++ binutils-2.25/gold/binary.cc 2015-06-09 10:49:23.000000000 +0100 +@@ -23,7 +23,7 @@ + #include "gold.h" + + #include +-#include ++#include + #include "safe-ctype.h" + + #include "elfcpp.h" diff --git a/packages/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/packages/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch new file mode 100644 index 0000000..6168b31 --- /dev/null +++ b/packages/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch @@ -0,0 +1,77 @@ +From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 +From: Andrew Hsieh +Date: Wed, 18 Mar 2015 10:57:24 +0800 +Subject: [PATCH] Fix darwin build + +1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 + doesn't support ended initializer list +2. wcsncasecmp doesn't exist in MacSDK10.6.x + +Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e +--- + binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ + binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c +index 13e39e4..7a98306 100644 +--- binutils-2.25.orig/bfd/peXXigen.c ++++ binutils-2.25/bfd/peXXigen.c +@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) + } + #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ + ++#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L ++/* wcsncasecmp isn't always defined in Mac SDK */ ++static int ++wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ ++ if (n == 0) ++ return (0); ++ for (; *s1; s1++, s2++) ++ { ++ c1 = towlower(*s1); ++ c2 = towlower(*s2); ++ if (c1 != c2) ++ return ((int)c1 - c2); ++ if (--n == 0) ++ return (0); ++ } ++ return (-*s2); ++} ++#endif ++ + /* Perform a comparison of two entries. */ + static signed int + rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) +diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc +index ff5a8ac..45140e0 100644 +--- binutils-2.25.orig/gold/gold-threads.cc ++++ binutils-2.25/gold/gold-threads.cc +@@ -284,9 +284,18 @@ Condvar::~Condvar() + class Once_initialize + { + public: +- Once_initialize() +- : once_(PTHREAD_ONCE_INIT) +- { } ++ Once_initialize() ++#if !defined(__APPLE__) ++ : once_(PTHREAD_ONCE_INIT) ++ { } ++#else ++// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support ++// extended initializer list as above */ ++ { ++ pthread_once_t once_2 = PTHREAD_ONCE_INIT; ++ once_ = once_2; ++ } ++#endif + + // Return a pointer to the pthread_once_t variable. + pthread_once_t* +-- +2.1.3 + diff --git a/packages/binutils/2.25.1/400-arm-rotate_left-fix.patch b/packages/binutils/2.25.1/400-arm-rotate_left-fix.patch new file mode 100644 index 0000000..4149597 --- /dev/null +++ b/packages/binutils/2.25.1/400-arm-rotate_left-fix.patch @@ -0,0 +1,26 @@ +From d840c081f8082e8b9e63fead5306643975a97bb3 Mon Sep 17 00:00:00 2001 +From: Richard Earnshaw +Date: Thu, 20 Nov 2014 17:02:47 +0000 +Subject: [PATCH] * config/tc-arm.c (rotate_left): Avoid undefined behaviour + when N = 0. + +--- + gas/config/tc-arm.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletion(-) + +diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c +index 5077f87..9100fb2 100644 +--- a/gas/config/tc-arm.c ++++ b/gas/config/tc-arm.c +@@ -7251,7 +7251,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb) + + /* Functions for operand encoding. ARM, then Thumb. */ + +-#define rotate_left(v, n) (v << n | v >> (32 - n)) ++#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31)) + + /* If VAL can be encoded in the immediate field of an ARM instruction, + return the encoded form. Otherwise, return FAIL. */ +-- +1.9.4 + diff --git a/packages/binutils/2.25.1/500-sysroot.patch b/packages/binutils/2.25.1/500-sysroot.patch new file mode 100644 index 0000000..e49c795 --- /dev/null +++ b/packages/binutils/2.25.1/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -308,18 +308,25 @@ + directory first. */ + if (! entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.25.1/600-poison-system-directories.patch b/packages/binutils/2.25.1/600-poison-system-directories.patch new file mode 100644 index 0000000..ec3622b --- /dev/null +++ b/packages/binutils/2.25.1/600-poison-system-directories.patch @@ -0,0 +1,276 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +[Gustavo: adapt to binutils 2.25] +Signed-off-by: Thomas Petazzoni +Signed-off-by: Gustavo Zacarias + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.ac (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +diff -Nura a/ld/config.in b/ld/config.in +--- a/ld/config.in 2014-10-14 04:32:04.000000000 -0300 ++++ b/ld/config.in 2014-12-24 08:07:28.997918918 -0300 +@@ -11,6 +11,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +diff -Nura a/ld/configure b/ld/configure +--- a/ld/configure 2014-12-23 11:22:07.000000000 -0300 ++++ b/ld/configure 2014-12-24 08:07:29.002919088 -0300 +@@ -783,6 +783,7 @@ + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_werror +@@ -1439,6 +1440,8 @@ + --disable-largefile omit support for large files + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -15487,7 +15490,18 @@ + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +diff -Nura a/ld/configure.ac b/ld/configure.ac +--- a/ld/configure.ac 2014-10-14 04:32:04.000000000 -0300 ++++ b/ld/configure.ac 2014-12-24 08:07:29.002919088 -0300 +@@ -94,6 +94,16 @@ + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +diff -Nura a/ld/ldfile.c b/ld/ldfile.c +--- a/ld/ldfile.c 2014-10-14 04:32:04.000000000 -0300 ++++ b/ld/ldfile.c 2014-12-24 08:07:29.002919088 -0300 +@@ -114,6 +114,23 @@ + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +diff -Nura a/ld/ld.h b/ld/ld.h +--- a/ld/ld.h 2014-10-14 04:32:04.000000000 -0300 ++++ b/ld/ld.h 2014-12-24 08:07:29.003919122 -0300 +@@ -161,6 +161,14 @@ + /* If TRUE we'll just print the default output on stdout. */ + bfd_boolean print_output_format; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +diff -Nura a/ld/ldlex.h b/ld/ldlex.h +--- a/ld/ldlex.h 2014-11-04 06:54:41.000000000 -0300 ++++ b/ld/ldlex.h 2014-12-24 08:09:47.477644294 -0300 +@@ -140,6 +140,8 @@ + OPTION_IGNORE_UNRESOLVED_SYMBOL, + OPTION_PUSH_STATE, + OPTION_POP_STATE, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ +diff -Nura a/ld/ldmain.c b/ld/ldmain.c +--- a/ld/ldmain.c 2014-10-14 04:32:04.000000000 -0300 ++++ b/ld/ldmain.c 2014-12-24 08:07:29.003919122 -0300 +@@ -266,6 +266,8 @@ + command_line.warn_mismatch = TRUE; + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +diff -Nura a/ld/ld.texinfo b/ld/ld.texinfo +--- a/ld/ld.texinfo 2014-12-23 05:47:10.000000000 -0300 ++++ b/ld/ld.texinfo 2014-12-24 08:07:29.005919191 -0300 +@@ -2212,6 +2212,18 @@ + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +diff -Nura a/ld/lexsup.c b/ld/lexsup.c +--- a/ld/lexsup.c 2014-11-04 06:54:41.000000000 -0300 ++++ b/ld/lexsup.c 2014-12-24 08:48:50.136583414 -0300 +@@ -513,6 +513,14 @@ + { {"pop-state", no_argument, NULL, OPTION_POP_STATE}, + '\0', NULL, N_("Pop state of flags governing input file handling"), + TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -525,6 +533,7 @@ + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1458,6 +1467,14 @@ + } + break; + ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; ++ + case OPTION_PUSH_STATE: + input_flags.pushed = xmemdup (&input_flags, + sizeof (input_flags), +@@ -1483,6 +1500,10 @@ + command_line.soname = NULL; + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); diff --git a/packages/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch b/packages/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch new file mode 100644 index 0000000..cea92f3 --- /dev/null +++ b/packages/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch @@ -0,0 +1,42 @@ +From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 +From: Alexey Neyman +Date: Sat, 11 Mar 2017 17:27:09 -0800 +Subject: [PATCH] Fix library paths on PowerPC + +First, need to match against just the CPU name, not the whole triplet. +Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin +triplet. + +Second, it should be testing for $target, not $host. Host may be +little endian by default, and the sysroot directory layout shouldn't +depend on whether it is built on LE or BE machine. + +Signed-off-by: Alexey Neyman +--- + ld/emulparams/elf32ppccommon.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh +index 1f54ef8..d00cf68 100644 +--- a/ld/emulparams/elf32ppccommon.sh ++++ b/ld/emulparams/elf32ppccommon.sh +@@ -44,11 +44,11 @@ fi + + # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. + # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. +-case "$host":"$EMULATION_NAME" in +- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; +- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; +- *le-*:*64*) LIBPATH_SUFFIX=64be ;; +- *le-*:*32*) LIBPATH_SUFFIX=32be ;; ++case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in ++ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; ++ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; ++ *le:*64*) LIBPATH_SUFFIX=64be ;; ++ *le:*32*) LIBPATH_SUFFIX=32be ;; + *:*64lppc*) LIBPATH_SUFFIX=64le ;; + *:*32lppc*) LIBPATH_SUFFIX=32le ;; + *:*64*) LIBPATH_SUFFIX=64 ;; +-- +2.9.3 + diff --git a/packages/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch b/packages/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch new file mode 100644 index 0000000..8aeb064 --- /dev/null +++ b/packages/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch @@ -0,0 +1,90 @@ +From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 25 Nov 2014 21:33:21 +0300 +Subject: [PATCH] Fix trampolines search code for conditional branches + +For conditional branches that need more than one trampoline to reach its +target assembler couldn't always find suitable trampoline because +post-loop condition check was placed inside the loop, resulting in +premature loop termination. Move check outside the loop. + +This fixes the following build errors seen when assembling huge files +produced by gcc: + Error: jump target out of range; no usable trampoline found + Error: operand 1 of 'j' has out of range value '307307' + +2014-11-25 Max Filippov + +gas/ + * config/tc-xtensa.c (search_trampolines): Move post-loop + condition check outside the search loop. + +gas/testsuite/ + * gas/xtensa/trampoline.d: Add expected output for branches. + * gas/xtensa/trampoline.s: Add test case for branches. + +Signed-off-by: Max Filippov +--- +Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 +Changes to ChangeLogs are dropped. + + gas/config/tc-xtensa.c | 8 ++++---- + gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ + gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index d11b0c7..f23ccf8 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) + if (next_addr == 0 || addr - next_addr > J_RANGE) + break; + } +- if (abs (addr - this_addr) < J_RANGE) +- return tf; +- +- return NULL; + } ++ if (abs (addr - this_addr) < J_RANGE) ++ return tf; ++ ++ return NULL; + } + for ( ; tf; tf = tf->next) + { +diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d +index b4f65dc..5ae32a6 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.d ++++ b/gas/testsuite/gas/xtensa/trampoline.d +@@ -24,3 +24,12 @@ + .*33462:.*j.0x49407 + #... + .*49407:.*j.0x49407 ++.*4940a:.*beqz.n.a2,.0x4940f ++.*4940c:.*j.0x693d1 ++#... ++.*693d1:.*j.0x7ddd4 ++#... ++.*7ddd4:.*j.0x927f5 ++#... ++.*927f5:.*j.0x927f5 ++#... +diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s +index 259a3bb..4465786 100644 +--- a/gas/testsuite/gas/xtensa/trampoline.s ++++ b/gas/testsuite/gas/xtensa/trampoline.s +@@ -19,3 +19,10 @@ + .endr + 3: + j 3b ++ bnez a2, 4f ++ .rep 50000 ++ and a2, a2, a3 ++ _ret ++ .endr ++4: ++ j 4b +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch b/packages/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch new file mode 100644 index 0000000..8a21100 --- /dev/null +++ b/packages/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch @@ -0,0 +1,502 @@ +From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 27 Mar 2015 07:13:55 +0300 +Subject: [PATCH 1/4] xtensa: optimize check_section_ebb_pcrels_fit + +The original check_section_ebb_pcrels_fit algorithm checks that text +actions proposed for current EBB are OK for every relocation in a +section. There's no need to check every relocation, because text actions +for EBB can only change size of that EBB, thus only affecting +relocations that in any way cross that EBB. In addition EBBs are +iterated in ascending order of their VMA, making it easier to track +relevant relocations. + +Introduce a structure that can track relocations that cross the range of +VMAs of EBB and use it to only check relocations relevant to current EBB +in check_section_ebb_pcrels_fit. +It takes O(N log N) operations to build it and O(N) operations to move +current EBB VMA window through its entire range, where N is the number +of relocations in a section. The resulting complexity of +compute_text_actions is thus reduced from O(N^2) to O(N log N + N * M), +where M is the average number of relocations crossing each EBB. + +Original profile: + +% time self children called name +----------------------------------------- + 44.26 71.53 6429/6429 compute_text_actions + 50.2 44.26 71.53 6429 check_section_ebb_pcrels_fit + 1.16 20.12 347506666/347576152 pcrel_reloc_fits + 2.95 16.52 347506666/348104944 get_relocation_opnd + 2.01 9.74 347575100/361252208 r_reloc_init + 0.55 7.53 347575100/363381467 r_reloc_get_section + 5.76 0.02 695013332/695013332 xlate_offset_with_removed_text + 0.68 3.89 347575100/363483827 bfd_octets_per_byte + 0.32 0.00 347506666/349910253 is_alt_relocation + 0.18 0.11 6391/6391 build_xlate_map + 0.00 0.00 6429/19417168 get_xtensa_relax_info + 0.00 0.00 6391/6391 free_xlate_map +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 2.56 3.08 6429/6429 compute_text_actions + 8.2 2.56 3.08 6429 check_section_ebb_pcrels_fit + 0.08 0.91 17721075/17790561 pcrel_reloc_fits + 0.17 0.47 17721075/31685977 r_reloc_init + 0.43 0.00 35442150/35442150 xlate_offset_with_removed_text + 0.02 0.37 17721075/33815236 r_reloc_get_section + 0.22 0.11 6391/6391 build_xlate_map + 0.05 0.22 17721075/33917596 bfd_octets_per_byte + 0.03 0.00 17721075/20405299 is_alt_relocation + 0.01 0.00 6429/6429 reloc_range_list_update_range + 0.00 0.00 6429/19417168 get_xtensa_relax_info + 0.00 0.00 6391/6391 free_xlate_map +----------------------------------------- + +2015-04-01 Max Filippov +bfd/ + * elf32-xtensa.c (reloc_range_list, reloc_range_list_entry, + reloc_range): new typedef. + (reloc_range_list_struct, reloc_range_list_entry_struct, + reloc_range_struct): new structures. + (reloc_range_compare, build_reloc_ranges, + reloc_range_list_append, reloc_range_list_remove, + reloc_range_list_update_range, free_reloc_range_list): new + functions. + (compute_text_actions): precompute relocation opcodes before the + loop. Add relevant_relocs variable, initialize it before the + loop, pass it to the check_section_ebb_pcrels_fit. + (check_section_ebb_pcrels_fit): add new parameter: + relevant_relocs. Update address range in the relevant_relocs if + it's non-NULL and iterate only over relevant relocations. + +Backported from: b2b326d246f839ee218192ac88da2384d929a072 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 298 insertions(+), 23 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 0b6f584..872370b 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -6619,8 +6619,10 @@ static bfd_boolean compute_text_actions + (bfd *, asection *, struct bfd_link_info *); + static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *); + static bfd_boolean compute_ebb_actions (ebb_constraint *); ++typedef struct reloc_range_list_struct reloc_range_list; + static bfd_boolean check_section_ebb_pcrels_fit +- (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *, ++ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, ++ reloc_range_list *, const ebb_constraint *, + const xtensa_opcode *); + static bfd_boolean check_section_ebb_reduces (const ebb_constraint *); + static void text_action_add_proposed +@@ -7219,6 +7221,221 @@ build_reloc_opcodes (bfd *abfd, + return reloc_opcodes; + } + ++struct reloc_range_struct ++{ ++ bfd_vma addr; ++ bfd_boolean add; /* TRUE if start of a range, FALSE otherwise. */ ++ /* Original irel index in the array of relocations for a section. */ ++ unsigned irel_index; ++}; ++typedef struct reloc_range_struct reloc_range; ++ ++typedef struct reloc_range_list_entry_struct reloc_range_list_entry; ++struct reloc_range_list_entry_struct ++{ ++ reloc_range_list_entry *next; ++ reloc_range_list_entry *prev; ++ Elf_Internal_Rela *irel; ++ xtensa_opcode opcode; ++ int opnum; ++}; ++ ++struct reloc_range_list_struct ++{ ++ /* The rest of the structure is only meaningful when ok is TRUE. */ ++ bfd_boolean ok; ++ ++ unsigned n_range; /* Number of range markers. */ ++ reloc_range *range; /* Sorted range markers. */ ++ ++ unsigned first; /* Index of a first range element in the list. */ ++ unsigned last; /* One past index of a last range element in the list. */ ++ ++ unsigned n_list; /* Number of list elements. */ ++ reloc_range_list_entry *reloc; /* */ ++ reloc_range_list_entry list_root; ++}; ++ ++static int ++reloc_range_compare (const void *a, const void *b) ++{ ++ const reloc_range *ra = a; ++ const reloc_range *rb = b; ++ ++ if (ra->addr != rb->addr) ++ return ra->addr < rb->addr ? -1 : 1; ++ if (ra->add != rb->add) ++ return ra->add ? -1 : 1; ++ return 0; ++} ++ ++static void ++build_reloc_ranges (bfd *abfd, asection *sec, ++ bfd_byte *contents, ++ Elf_Internal_Rela *internal_relocs, ++ xtensa_opcode *reloc_opcodes, ++ reloc_range_list *list) ++{ ++ unsigned i; ++ size_t n = 0; ++ size_t max_n = 0; ++ reloc_range *ranges = NULL; ++ reloc_range_list_entry *reloc = ++ bfd_malloc (sec->reloc_count * sizeof (*reloc)); ++ ++ memset (list, 0, sizeof (*list)); ++ list->ok = TRUE; ++ ++ for (i = 0; i < sec->reloc_count; i++) ++ { ++ Elf_Internal_Rela *irel = &internal_relocs[i]; ++ int r_type = ELF32_R_TYPE (irel->r_info); ++ reloc_howto_type *howto = &elf_howto_table[r_type]; ++ r_reloc r_rel; ++ ++ if (r_type == R_XTENSA_ASM_SIMPLIFY ++ || r_type == R_XTENSA_32_PCREL ++ || !howto->pc_relative) ++ continue; ++ ++ r_reloc_init (&r_rel, abfd, irel, contents, ++ bfd_get_section_limit (abfd, sec)); ++ ++ if (r_reloc_get_section (&r_rel) != sec) ++ continue; ++ ++ if (n + 2 > max_n) ++ { ++ max_n = (max_n + 2) * 2; ++ ranges = bfd_realloc (ranges, max_n * sizeof (*ranges)); ++ } ++ ++ ranges[n].addr = irel->r_offset; ++ ranges[n + 1].addr = r_rel.target_offset; ++ ++ ranges[n].add = ranges[n].addr < ranges[n + 1].addr; ++ ranges[n + 1].add = !ranges[n].add; ++ ++ ranges[n].irel_index = i; ++ ranges[n + 1].irel_index = i; ++ ++ n += 2; ++ ++ reloc[i].irel = irel; ++ ++ /* Every relocation won't possibly be checked in the optimized version of ++ check_section_ebb_pcrels_fit, so this needs to be done here. */ ++ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) ++ { ++ /* None of the current alternate relocs are PC-relative, ++ and only PC-relative relocs matter here. */ ++ } ++ else ++ { ++ xtensa_opcode opcode; ++ int opnum; ++ ++ if (reloc_opcodes) ++ opcode = reloc_opcodes[i]; ++ else ++ opcode = get_relocation_opcode (abfd, sec, contents, irel); ++ ++ if (opcode == XTENSA_UNDEFINED) ++ { ++ list->ok = FALSE; ++ break; ++ } ++ ++ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); ++ if (opnum == XTENSA_UNDEFINED) ++ { ++ list->ok = FALSE; ++ break; ++ } ++ ++ /* Record relocation opcode and opnum as we've calculated them ++ anyway and they won't change. */ ++ reloc[i].opcode = opcode; ++ reloc[i].opnum = opnum; ++ } ++ } ++ ++ if (list->ok) ++ { ++ ranges = bfd_realloc (ranges, n * sizeof (*ranges)); ++ qsort (ranges, n, sizeof (*ranges), reloc_range_compare); ++ ++ list->n_range = n; ++ list->range = ranges; ++ list->reloc = reloc; ++ list->list_root.prev = &list->list_root; ++ list->list_root.next = &list->list_root; ++ } ++ else ++ { ++ free (ranges); ++ free (reloc); ++ } ++} ++ ++static void reloc_range_list_append (reloc_range_list *list, ++ unsigned irel_index) ++{ ++ reloc_range_list_entry *entry = list->reloc + irel_index; ++ ++ entry->prev = list->list_root.prev; ++ entry->next = &list->list_root; ++ entry->prev->next = entry; ++ entry->next->prev = entry; ++ ++list->n_list; ++} ++ ++static void reloc_range_list_remove (reloc_range_list *list, ++ unsigned irel_index) ++{ ++ reloc_range_list_entry *entry = list->reloc + irel_index; ++ ++ entry->next->prev = entry->prev; ++ entry->prev->next = entry->next; ++ --list->n_list; ++} ++ ++/* Update relocation list object so that it lists all relocations that cross ++ [first; last] range. Range bounds should not decrease with successive ++ invocations. */ ++static void reloc_range_list_update_range (reloc_range_list *list, ++ bfd_vma first, bfd_vma last) ++{ ++ /* This should not happen: EBBs are iterated from lower addresses to higher. ++ But even if that happens there's no need to break: just flush current list ++ and start from scratch. */ ++ if ((list->last > 0 && list->range[list->last - 1].addr > last) || ++ (list->first > 0 && list->range[list->first - 1].addr >= first)) ++ { ++ list->first = 0; ++ list->last = 0; ++ list->n_list = 0; ++ list->list_root.next = &list->list_root; ++ list->list_root.prev = &list->list_root; ++ fprintf (stderr, "%s: move backwards requested\n", __func__); ++ } ++ ++ for (; list->last < list->n_range && ++ list->range[list->last].addr <= last; ++list->last) ++ if (list->range[list->last].add) ++ reloc_range_list_append (list, list->range[list->last].irel_index); ++ ++ for (; list->first < list->n_range && ++ list->range[list->first].addr < first; ++list->first) ++ if (!list->range[list->first].add) ++ reloc_range_list_remove (list, list->range[list->first].irel_index); ++} ++ ++static void free_reloc_range_list (reloc_range_list *list) ++{ ++ free (list->range); ++ free (list->reloc); ++} + + /* The compute_text_actions function will build a list of potential + transformation actions for code in the extended basic block of each +@@ -7245,6 +7462,7 @@ compute_text_actions (bfd *abfd, + property_table_entry *prop_table = 0; + int ptblsize = 0; + bfd_size_type sec_size; ++ reloc_range_list relevant_relocs; + + relax_info = get_xtensa_relax_info (sec); + BFD_ASSERT (relax_info); +@@ -7277,6 +7495,12 @@ compute_text_actions (bfd *abfd, + goto error_return; + } + ++ /* Precompute the opcode for each relocation. */ ++ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs); ++ ++ build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes, ++ &relevant_relocs); ++ + for (i = 0; i < sec->reloc_count; i++) + { + Elf_Internal_Rela *irel = &internal_relocs[i]; +@@ -7340,17 +7564,13 @@ compute_text_actions (bfd *abfd, + ebb->start_reloc_idx = i; + ebb->end_reloc_idx = i; + +- /* Precompute the opcode for each relocation. */ +- if (reloc_opcodes == NULL) +- reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, +- internal_relocs); +- + if (!extend_ebb_bounds (ebb) + || !compute_ebb_proposed_actions (&ebb_table) + || !compute_ebb_actions (&ebb_table) + || !check_section_ebb_pcrels_fit (abfd, sec, contents, +- internal_relocs, &ebb_table, +- reloc_opcodes) ++ internal_relocs, ++ &relevant_relocs, ++ &ebb_table, reloc_opcodes) + || !check_section_ebb_reduces (&ebb_table)) + { + /* If anything goes wrong or we get unlucky and something does +@@ -7372,6 +7592,8 @@ compute_text_actions (bfd *abfd, + free_ebb_constraint (&ebb_table); + } + ++ free_reloc_range_list (&relevant_relocs); ++ + #if DEBUG + if (relax_info->action_list.head) + print_action_list (stderr, &relax_info->action_list); +@@ -7974,14 +8196,17 @@ check_section_ebb_pcrels_fit (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *internal_relocs, ++ reloc_range_list *relevant_relocs, + const ebb_constraint *constraint, + const xtensa_opcode *reloc_opcodes) + { + unsigned i, j; ++ unsigned n = sec->reloc_count; + Elf_Internal_Rela *irel; + xlate_map_t *xmap = NULL; + bfd_boolean ok = TRUE; + xtensa_relax_info *relax_info; ++ reloc_range_list_entry *entry = NULL; + + relax_info = get_xtensa_relax_info (sec); + +@@ -7992,7 +8217,40 @@ check_section_ebb_pcrels_fit (bfd *abfd, + can still be used. */ + } + +- for (i = 0; i < sec->reloc_count; i++) ++ if (relevant_relocs && constraint->action_count) ++ { ++ if (!relevant_relocs->ok) ++ { ++ ok = FALSE; ++ n = 0; ++ } ++ else ++ { ++ bfd_vma min_offset, max_offset; ++ min_offset = max_offset = constraint->actions[0].offset; ++ ++ for (i = 1; i < constraint->action_count; ++i) ++ { ++ proposed_action *action = &constraint->actions[i]; ++ bfd_vma offset = action->offset; ++ ++ if (offset < min_offset) ++ min_offset = offset; ++ if (offset > max_offset) ++ max_offset = offset; ++ } ++ reloc_range_list_update_range (relevant_relocs, min_offset, ++ max_offset); ++ n = relevant_relocs->n_list; ++ entry = &relevant_relocs->list_root; ++ } ++ } ++ else ++ { ++ relevant_relocs = NULL; ++ } ++ ++ for (i = 0; i < n; i++) + { + r_reloc r_rel; + bfd_vma orig_self_offset, orig_target_offset; +@@ -8001,7 +8259,15 @@ check_section_ebb_pcrels_fit (bfd *abfd, + reloc_howto_type *howto; + int self_removed_bytes, target_removed_bytes; + +- irel = &internal_relocs[i]; ++ if (relevant_relocs) ++ { ++ entry = entry->next; ++ irel = entry->irel; ++ } ++ else ++ { ++ irel = internal_relocs + i; ++ } + r_type = ELF32_R_TYPE (irel->r_info); + + howto = &elf_howto_table[r_type]; +@@ -8067,21 +8333,30 @@ check_section_ebb_pcrels_fit (bfd *abfd, + xtensa_opcode opcode; + int opnum; + +- if (reloc_opcodes) +- opcode = reloc_opcodes[i]; +- else +- opcode = get_relocation_opcode (abfd, sec, contents, irel); +- if (opcode == XTENSA_UNDEFINED) ++ if (relevant_relocs) + { +- ok = FALSE; +- break; ++ opcode = entry->opcode; ++ opnum = entry->opnum; + } +- +- opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); +- if (opnum == XTENSA_UNDEFINED) ++ else + { +- ok = FALSE; +- break; ++ if (reloc_opcodes) ++ opcode = reloc_opcodes[relevant_relocs ? ++ (unsigned)(entry - relevant_relocs->reloc) : i]; ++ else ++ opcode = get_relocation_opcode (abfd, sec, contents, irel); ++ if (opcode == XTENSA_UNDEFINED) ++ { ++ ok = FALSE; ++ break; ++ } ++ ++ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); ++ if (opnum == XTENSA_UNDEFINED) ++ { ++ ok = FALSE; ++ break; ++ } + } + + if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset)) +@@ -8778,7 +9053,7 @@ move_shared_literal (asection *sec, + /* Check all of the PC-relative relocations to make sure they still fit. */ + relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, + target_sec_cache->contents, +- target_sec_cache->relocs, ++ target_sec_cache->relocs, NULL, + &ebb_table, NULL); + + if (!relocs_fit) +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch b/packages/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch new file mode 100644 index 0000000..9df8065 --- /dev/null +++ b/packages/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch @@ -0,0 +1,356 @@ +From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 28 Mar 2015 08:46:28 +0300 +Subject: [PATCH 2/4] xtensa: optimize removed_by_actions + +The function removed_by_actions iterates through text actions to +calculate an offset applied by text actions to a given VMA. Although it +has a parameter p_start_action that allows for incremental offset +calculation, in many places it's used with p_start_action explicitly set +to the first action. After the first relaxation pass when the list of +text actions is finalized, an array of offsets sorted by VMA may be used +to speed up this function. + +Original profile: + +% time self children called name +----------------------------------------- + 0.35 0.00 33872/4808961 relax_section_symbols + 3.32 0.00 326022/4808961 relax_property_section + 12.83 0.00 1259379/4808961 offset_with_removed_text + 32.50 0.00 3189688/4808961 translate_reloc + 71.5 49.00 0.00 4808961 removed_by_actions +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 33872/4808537 relax_section_symbols + 0.01 0.00 326022/4808537 relax_property_section + 0.05 0.00 1258955/4808537 offset_with_removed_text_map + 0.13 0.00 3189688/4808537 translate_reloc + 1.0 0.20 0.00 4808537 removed_by_actions_map + 0.00 0.00 120/120 map_removal_by_action +----------------------------------------- + +2015-04-01 Max Filippov +bfd/ + * elf32-xtensa.c (removal_by_action_entry_struct, + removal_by_action_map_struct): new structures. + (removal_by_action_entry, removal_by_action_map): new typedefs. + (text_action_list_struct): add new field: map. + (map_removal_by_action, removed_by_actions_map, + offset_with_removed_text_map): new functions. + (relax_section): replace offset_with_removed_text with + offset_with_removed_text_map. + (translate_reloc, relax_property_section, relax_section_symbols): + replace removed_by_actions with removed_by_actions_map. + +Backported from: 071aa5c98a31c966f5fbfc573fcee61350fd1936 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 181 +++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 156 insertions(+), 25 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 872370b..21b2871 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -5420,11 +5420,28 @@ struct text_action_struct + text_action *next; + }; + ++struct removal_by_action_entry_struct ++{ ++ bfd_vma offset; ++ int removed; ++ int eq_removed; ++ int eq_removed_before_fill; ++}; ++typedef struct removal_by_action_entry_struct removal_by_action_entry; ++ ++struct removal_by_action_map_struct ++{ ++ unsigned n_entries; ++ removal_by_action_entry *entry; ++}; ++typedef struct removal_by_action_map_struct removal_by_action_map; ++ + + /* List of all of the actions taken on a text section. */ + struct text_action_list_struct + { + text_action *head; ++ removal_by_action_map map; + }; + + +@@ -5636,6 +5653,101 @@ action_list_count (text_action_list *action_list) + return count; + } + ++static void ++map_removal_by_action (text_action_list *action_list) ++{ ++ text_action *r; ++ int removed = 0; ++ removal_by_action_map map; ++ bfd_boolean eq_complete; ++ ++ map.n_entries = 0; ++ map.entry = bfd_malloc (action_list_count (action_list) * ++ sizeof (removal_by_action_entry)); ++ eq_complete = FALSE; ++ ++ for (r = action_list->head; r;) ++ { ++ removal_by_action_entry *ientry = map.entry + map.n_entries; ++ ++ if (map.n_entries && (ientry - 1)->offset == r->offset) ++ { ++ --ientry; ++ } ++ else ++ { ++ ++map.n_entries; ++ eq_complete = FALSE; ++ ientry->offset = r->offset; ++ ientry->eq_removed_before_fill = removed; ++ } ++ ++ if (!eq_complete) ++ { ++ if (r->action != ta_fill || r->removed_bytes >= 0) ++ { ++ ientry->eq_removed = removed; ++ eq_complete = TRUE; ++ } ++ else ++ ientry->eq_removed = removed + r->removed_bytes; ++ } ++ ++ removed += r->removed_bytes; ++ ientry->removed = removed; ++ r = r->next; ++ } ++ action_list->map = map; ++} ++ ++static int ++removed_by_actions_map (text_action_list *action_list, bfd_vma offset, ++ bfd_boolean before_fill) ++{ ++ unsigned a, b; ++ ++ if (!action_list->map.entry) ++ map_removal_by_action (action_list); ++ ++ if (!action_list->map.n_entries) ++ return 0; ++ ++ a = 0; ++ b = action_list->map.n_entries; ++ ++ while (b - a > 1) ++ { ++ unsigned c = (a + b) / 2; ++ ++ if (action_list->map.entry[c].offset <= offset) ++ a = c; ++ else ++ b = c; ++ } ++ ++ if (action_list->map.entry[a].offset < offset) ++ { ++ return action_list->map.entry[a].removed; ++ } ++ else if (action_list->map.entry[a].offset == offset) ++ { ++ return before_fill ? ++ action_list->map.entry[a].eq_removed_before_fill : ++ action_list->map.entry[a].eq_removed; ++ } ++ else ++ { ++ return 0; ++ } ++} ++ ++static bfd_vma ++offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) ++{ ++ int removed = removed_by_actions_map (action_list, offset, FALSE); ++ return offset - removed; ++} ++ + + /* The find_insn_action routine will only find non-fill actions. */ + +@@ -5909,6 +6021,9 @@ init_xtensa_relax_info (asection *sec) + + relax_info->action_list.head = NULL; + ++ relax_info->action_list.map.n_entries = 0; ++ relax_info->action_list.map.entry = NULL; ++ + relax_info->fix_list = NULL; + relax_info->fix_array = NULL; + relax_info->fix_array_count = 0; +@@ -9218,7 +9333,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + if (elf_hash_table (link_info)->dynamic_sections_created) + shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); + irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); +- irel->r_offset = offset_with_removed_text ++ irel->r_offset = offset_with_removed_text_map + (&relax_info->action_list, irel->r_offset); + continue; + } +@@ -9255,7 +9370,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + } + } + +- source_offset = offset_with_removed_text ++ source_offset = offset_with_removed_text_map + (&relax_info->action_list, irel->r_offset); + irel->r_offset = source_offset; + } +@@ -9352,7 +9467,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + break; + } + +- new_end_offset = offset_with_removed_text ++ new_end_offset = offset_with_removed_text_map + (&target_relax_info->action_list, + r_rel.target_offset + diff_value); + diff_value = new_end_offset - new_reloc.target_offset; +@@ -9750,7 +9865,6 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) + xtensa_relax_info *relax_info; + removed_literal *removed; + bfd_vma target_offset, base_offset; +- text_action *act; + + *new_rel = *orig_rel; + +@@ -9803,19 +9917,26 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) + offset. */ + + base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend; +- act = relax_info->action_list.head; + if (base_offset <= target_offset) + { +- int base_removed = removed_by_actions (&act, base_offset, FALSE); +- int addend_removed = removed_by_actions (&act, target_offset, FALSE); ++ int base_removed = removed_by_actions_map (&relax_info->action_list, ++ base_offset, FALSE); ++ int addend_removed = removed_by_actions_map (&relax_info->action_list, ++ target_offset, FALSE) - ++ base_removed; ++ + new_rel->target_offset = target_offset - base_removed - addend_removed; + new_rel->rela.r_addend -= addend_removed; + } + else + { + /* Handle a negative addend. The base offset comes first. */ +- int tgt_removed = removed_by_actions (&act, target_offset, FALSE); +- int addend_removed = removed_by_actions (&act, base_offset, FALSE); ++ int tgt_removed = removed_by_actions_map (&relax_info->action_list, ++ target_offset, FALSE); ++ int addend_removed = removed_by_actions_map (&relax_info->action_list, ++ base_offset, FALSE) - ++ tgt_removed; ++ + new_rel->target_offset = target_offset - tgt_removed; + new_rel->rela.r_addend += addend_removed; + } +@@ -10138,9 +10259,10 @@ relax_property_section (bfd *abfd, + bfd_vma old_offset = val.r_rel.target_offset; + bfd_vma new_offset; + long old_size, new_size; +- text_action *act = target_relax_info->action_list.head; +- new_offset = old_offset - +- removed_by_actions (&act, old_offset, FALSE); ++ int removed_by_old_offset = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset, FALSE); ++ new_offset = old_offset - removed_by_old_offset; + + /* Assert that we are not out of bounds. */ + old_size = bfd_get_32 (abfd, size_p); +@@ -10164,9 +10286,10 @@ relax_property_section (bfd *abfd, + + /* Recompute the new_offset, but this time don't + include any fill inserted by relaxation. */ +- act = target_relax_info->action_list.head; +- new_offset = old_offset - +- removed_by_actions (&act, old_offset, TRUE); ++ removed_by_old_offset = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset, TRUE); ++ new_offset = old_offset - removed_by_old_offset; + + /* If it is not unreachable and we have not yet + seen an unreachable at this address, place it +@@ -10182,8 +10305,12 @@ relax_property_section (bfd *abfd, + } + } + else +- new_size -= +- removed_by_actions (&act, old_offset + old_size, TRUE); ++ { ++ int removed_by_old_offset_size = ++ removed_by_actions_map (&target_relax_info->action_list, ++ old_offset + old_size, TRUE); ++ new_size -= removed_by_old_offset_size - removed_by_old_offset; ++ } + + if (new_size != old_size) + { +@@ -10441,14 +10568,16 @@ relax_section_symbols (bfd *abfd, asection *sec) + + if (isym->st_shndx == sec_shndx) + { +- text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = isym->st_value; ++ int removed = removed_by_actions_map (&relax_info->action_list, ++ orig_addr, FALSE); + +- isym->st_value -= removed_by_actions (&act, orig_addr, FALSE); +- ++ isym->st_value -= removed; + if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) + isym->st_size -= +- removed_by_actions (&act, orig_addr + isym->st_size, FALSE); ++ removed_by_actions_map (&relax_info->action_list, ++ orig_addr + isym->st_size, FALSE) - ++ removed; + } + } + +@@ -10466,15 +10595,17 @@ relax_section_symbols (bfd *abfd, asection *sec) + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) + { +- text_action *act = relax_info->action_list.head; + bfd_vma orig_addr = sym_hash->root.u.def.value; ++ int removed = removed_by_actions_map (&relax_info->action_list, ++ orig_addr, FALSE); + +- sym_hash->root.u.def.value -= +- removed_by_actions (&act, orig_addr, FALSE); ++ sym_hash->root.u.def.value -= removed; + + if (sym_hash->type == STT_FUNC) + sym_hash->size -= +- removed_by_actions (&act, orig_addr + sym_hash->size, FALSE); ++ removed_by_actions_map (&relax_info->action_list, ++ orig_addr + sym_hash->size, FALSE) - ++ removed; + } + } + +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch b/packages/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch new file mode 100644 index 0000000..96d526f --- /dev/null +++ b/packages/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch @@ -0,0 +1,146 @@ +From 288c2b709e5e6841484e1a129eaccd299db36877 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 4 Apr 2015 14:49:42 +0300 +Subject: [PATCH 3/4] xtensa: optimize find_removed_literal + +find_removed_literal uses linear search to find removed literal by its +VMA. The list of literals is fixed at that point, build an ordered index +array and use binary search instead. + +Original profile: + +% time self children called name +----------------------------------------- + 56.72 0.00 297578/669392 translate_reloc + 70.86 0.00 371814/669392 relax_section + 67.9 127.58 0.00 669392 find_removed_literal +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 297578/669392 translate_reloc + 0.00 0.00 371814/669392 relax_section + 0.0 0.00 0.00 669392 find_removed_literal + 0.00 0.00 23838/23838 map_removed_literal +----------------------------------------- + +2015-04-03 Max Filippov +bfd/ + * elf32-xtensa.c (removed_literal_map_entry): new typedef. + (removed_literal_map_entry_struct): new structure. + (removed_literal_list_struct): add new fields: n_map and map. + (map_removed_literal, removed_literal_compare): new functions. + (find_removed_literal): build index array for literals ordered + by VMA, use binary search to find removed literal. + +Backported from: 3439c466273378021821473d3fc84990e089ae34 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 58 insertions(+), 6 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 21b2871..51733ad 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -5832,6 +5832,7 @@ print_action_list (FILE *fp, text_action_list *action_list) + by the "from" offset field. */ + + typedef struct removed_literal_struct removed_literal; ++typedef struct removed_literal_map_entry_struct removed_literal_map_entry; + typedef struct removed_literal_list_struct removed_literal_list; + + struct removed_literal_struct +@@ -5841,10 +5842,19 @@ struct removed_literal_struct + removed_literal *next; + }; + ++struct removed_literal_map_entry_struct ++{ ++ bfd_vma addr; ++ removed_literal *literal; ++}; ++ + struct removed_literal_list_struct + { + removed_literal *head; + removed_literal *tail; ++ ++ unsigned n_map; ++ removed_literal_map_entry *map; + }; + + +@@ -5893,6 +5903,39 @@ add_removed_literal (removed_literal_list *removed_list, + } + } + ++static void ++map_removed_literal (removed_literal_list *removed_list) ++{ ++ unsigned n_map = 0; ++ unsigned i; ++ removed_literal_map_entry *map = NULL; ++ removed_literal *r = removed_list->head; ++ ++ for (i = 0; r; ++i, r = r->next) ++ { ++ if (i == n_map) ++ { ++ n_map = (n_map * 2) + 2; ++ map = bfd_realloc (map, n_map * sizeof (*map)); ++ } ++ map[i].addr = r->from.target_offset; ++ map[i].literal = r; ++ } ++ removed_list->map = map; ++ removed_list->n_map = i; ++} ++ ++static int ++removed_literal_compare (const void *a, const void *b) ++{ ++ const removed_literal_map_entry *pa = a; ++ const removed_literal_map_entry *pb = b; ++ ++ if (pa->addr == pb->addr) ++ return 0; ++ else ++ return pa->addr < pb->addr ? -1 : 1; ++} + + /* Check if the list of removed literals contains an entry for the + given address. Return the entry if found. */ +@@ -5900,12 +5943,21 @@ add_removed_literal (removed_literal_list *removed_list, + static removed_literal * + find_removed_literal (removed_literal_list *removed_list, bfd_vma addr) + { +- removed_literal *r = removed_list->head; +- while (r && r->from.target_offset < addr) +- r = r->next; +- if (r && r->from.target_offset == addr) +- return r; +- return NULL; ++ removed_literal_map_entry *p; ++ removed_literal *r = NULL; ++ ++ if (removed_list->map == NULL) ++ map_removed_literal (removed_list); ++ ++ p = bsearch (&addr, removed_list->map, removed_list->n_map, ++ sizeof (*removed_list->map), removed_literal_compare); ++ if (p) ++ { ++ while (p != removed_list->map && (p - 1)->addr == addr) ++ --p; ++ r = p->literal; ++ } ++ return r; + } + + +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch b/packages/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch new file mode 100644 index 0000000..3090cc2 --- /dev/null +++ b/packages/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch @@ -0,0 +1,826 @@ +From e5409aedd3ee2192855018a564650ffb75c26e60 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 5 Apr 2015 17:04:22 +0300 +Subject: [PATCH 4/4] xtensa: replace action list with splay tree + +text_action_add uses linear list search to order text actions list by +action VMA. The list is used at the first relaxation pass, when it's not +fixed yet. +Replace the list with splay tree from libiberty. + +Original profile: + +% time self children called name +----------------------------------------- + 0.00 0.00 14/158225 compute_text_actions + 3.62 0.00 25211/158225 remove_dead_literal + 8.42 0.00 58645/158225 coalesce_shared_literal + 10.68 0.00 74355/158225 text_action_add_proposed + 38.8 22.73 0.00 158225 text_action_add + 0.00 0.00 144527/293246 bfd_zmalloc +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.00 0.00 14/158225 compute_text_actions + 0.00 0.00 25211/158225 remove_dead_literal + 0.00 0.01 58645/158225 coalesce_shared_literal + 0.00 0.01 74355/158225 text_action_add_proposed + 0.1 0.00 0.02 158225 text_action_add + 0.01 0.00 144527/144527 splay_tree_insert + 0.00 0.00 144527/195130 splay_tree_lookup + 0.00 0.00 144527/293246 bfd_zmalloc +----------------------------------------- + +2015-04-03 Max Filippov +bfd/ + * elf32-xtensa.c (splay-tree.h): include header. + (text_action_struct): drop next pointer. + (text_action_list_struct): drop head pointer, add count and + tree fields. + (find_fill_action): instead of linear search in text_action_list + search in the tree. + (text_action_compare, action_first, action_next): new functions. + (text_action_add, text_action_add_literal): instead of linear + search and insertion insert new node into the tree. + (removed_by_actions): pass additional parameter: action_list, + use it to traverse the tree. + (offset_with_removed_text): pass additional action_list parameter + to removed_by_actions. + (map_action_fn_context): new typedef. + (map_action_fn_context_struct): new structure. + (map_action_fn): new function. + (map_removal_by_action): use splay_tree_foreach to build map. + (find_insn_action): replace linear search in text_action_list + with series of splay_tree_lookups. + (print_action, print_action_list_fn): new functions. + (print_action_list): use splay_tree_foreach. + (init_xtensa_relax_info): drop action_list.head initialization. + Initialize the tree. + (compute_text_actions): use non-zero action_list_count instead of + non-NULL action list. + (xlate_map_context): new typedef. + (xlate_map_context_struct): new structure. + (xlate_map_fn): new function. + (build_xlate_map): use splay_tree_foreach to build map. + (action_remove_bytes_fn): new function. + (relax_section): use zero action_list_count instead of NULL + action list. Use splay_tree_foreach to count final section size. + Drop unused variable 'removed'. + +Backported from: 4c2af04fe8b4452bf51d2debf1bb467fafcd0f08 +Signed-off-by: Max Filippov +--- + bfd/elf32-xtensa.c | 488 +++++++++++++++++++++++++++++++---------------------- + 1 file changed, 282 insertions(+), 206 deletions(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 51733ad..53af1c6 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -28,6 +28,7 @@ + #include "libbfd.h" + #include "elf-bfd.h" + #include "elf/xtensa.h" ++#include "splay-tree.h" + #include "xtensa-isa.h" + #include "xtensa-config.h" + +@@ -5416,8 +5417,6 @@ struct text_action_struct + bfd_vma virtual_offset; /* Zero except for adding literals. */ + int removed_bytes; + literal_value value; /* Only valid when adding literals. */ +- +- text_action *next; + }; + + struct removal_by_action_entry_struct +@@ -5440,7 +5439,8 @@ typedef struct removal_by_action_map_struct removal_by_action_map; + /* List of all of the actions taken on a text section. */ + struct text_action_list_struct + { +- text_action *head; ++ unsigned count; ++ splay_tree tree; + removal_by_action_map map; + }; + +@@ -5448,20 +5448,18 @@ struct text_action_list_struct + static text_action * + find_fill_action (text_action_list *l, asection *sec, bfd_vma offset) + { +- text_action **m_p; ++ text_action a; + + /* It is not necessary to fill at the end of a section. */ + if (sec->size == offset) + return NULL; + +- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) +- { +- text_action *t = *m_p; +- /* When the action is another fill at the same address, +- just increase the size. */ +- if (t->offset == offset && t->action == ta_fill) +- return t; +- } ++ a.offset = offset; ++ a.action = ta_fill; ++ ++ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); ++ if (node) ++ return (text_action *)node->value; + return NULL; + } + +@@ -5509,6 +5507,49 @@ adjust_fill_action (text_action *ta, int fill_diff) + } + + ++static int ++text_action_compare (splay_tree_key a, splay_tree_key b) ++{ ++ text_action *pa = (text_action *)a; ++ text_action *pb = (text_action *)b; ++ static const int action_priority[] = ++ { ++ [ta_fill] = 0, ++ [ta_none] = 1, ++ [ta_convert_longcall] = 2, ++ [ta_narrow_insn] = 3, ++ [ta_remove_insn] = 4, ++ [ta_remove_longcall] = 5, ++ [ta_remove_literal] = 6, ++ [ta_widen_insn] = 7, ++ [ta_add_literal] = 8, ++ }; ++ ++ if (pa->offset == pb->offset) ++ { ++ if (pa->action == pb->action) ++ return 0; ++ return action_priority[pa->action] - action_priority[pb->action]; ++ } ++ else ++ return pa->offset < pb->offset ? -1 : 1; ++} ++ ++static text_action * ++action_first (text_action_list *action_list) ++{ ++ splay_tree_node node = splay_tree_min (action_list->tree); ++ return node ? (text_action *)node->value : NULL; ++} ++ ++static text_action * ++action_next (text_action_list *action_list, text_action *action) ++{ ++ splay_tree_node node = splay_tree_successor (action_list->tree, ++ (splay_tree_key)action); ++ return node ? (text_action *)node->value : NULL; ++} ++ + /* Add a modification action to the text. For the case of adding or + removing space, modify any current fill and assume that + "unreachable_space" bytes can be freely contracted. Note that a +@@ -5521,8 +5562,8 @@ text_action_add (text_action_list *l, + bfd_vma offset, + int removed) + { +- text_action **m_p; + text_action *ta; ++ text_action a; + + /* It is not necessary to fill at the end of a section. */ + if (action == ta_fill && sec->size == offset) +@@ -5532,34 +5573,30 @@ text_action_add (text_action_list *l, + if (action == ta_fill && removed == 0) + return; + +- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) ++ a.action = action; ++ a.offset = offset; ++ ++ if (action == ta_fill) + { +- text_action *t = *m_p; ++ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); + +- if (action == ta_fill) ++ if (node) + { +- /* When the action is another fill at the same address, +- just increase the size. */ +- if (t->offset == offset && t->action == ta_fill) +- { +- t->removed_bytes += removed; +- return; +- } +- /* Fills need to happen before widens so that we don't +- insert fill bytes into the instruction stream. */ +- if (t->offset == offset && t->action == ta_widen_insn) +- break; ++ ta = (text_action *)node->value; ++ ta->removed_bytes += removed; ++ return; + } + } ++ else ++ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&a) == NULL); + +- /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; + ta->sec = sec; + ta->offset = offset; + ta->removed_bytes = removed; +- ta->next = (*m_p); +- *m_p = ta; ++ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); ++ ++l->count; + } + + +@@ -5570,7 +5607,6 @@ text_action_add_literal (text_action_list *l, + const literal_value *value, + int removed) + { +- text_action **m_p; + text_action *ta; + asection *sec = r_reloc_get_section (loc); + bfd_vma offset = loc->target_offset; +@@ -5578,14 +5614,6 @@ text_action_add_literal (text_action_list *l, + + BFD_ASSERT (action == ta_add_literal); + +- for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next) +- { +- if ((*m_p)->offset > offset +- && ((*m_p)->offset != offset +- || (*m_p)->virtual_offset > virtual_offset)) +- break; +- } +- + /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; +@@ -5594,8 +5622,10 @@ text_action_add_literal (text_action_list *l, + ta->virtual_offset = virtual_offset; + ta->value = *value; + ta->removed_bytes = removed; +- ta->next = (*m_p); +- *m_p = ta; ++ ++ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) == NULL); ++ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); ++ ++l->count; + } + + +@@ -5606,7 +5636,8 @@ text_action_add_literal (text_action_list *l, + so that each search may begin where the previous one left off. */ + + static int +-removed_by_actions (text_action **p_start_action, ++removed_by_actions (text_action_list *action_list, ++ text_action **p_start_action, + bfd_vma offset, + bfd_boolean before_fill) + { +@@ -5614,6 +5645,13 @@ removed_by_actions (text_action **p_start_action, + int removed = 0; + + r = *p_start_action; ++ if (r) ++ { ++ splay_tree_node node = splay_tree_lookup (action_list->tree, ++ (splay_tree_key)r); ++ BFD_ASSERT (node != NULL && r == (text_action *)node->value); ++ } ++ + while (r) + { + if (r->offset > offset) +@@ -5625,7 +5663,7 @@ removed_by_actions (text_action **p_start_action, + + removed += r->removed_bytes; + +- r = r->next; ++ r = action_next (action_list, r); + } + + *p_start_action = r; +@@ -5636,68 +5674,74 @@ removed_by_actions (text_action **p_start_action, + static bfd_vma + offset_with_removed_text (text_action_list *action_list, bfd_vma offset) + { +- text_action *r = action_list->head; +- return offset - removed_by_actions (&r, offset, FALSE); ++ text_action *r = action_first (action_list); ++ ++ return offset - removed_by_actions (action_list, &r, offset, FALSE); + } + + + static unsigned + action_list_count (text_action_list *action_list) + { +- text_action *r = action_list->head; +- unsigned count = 0; +- for (r = action_list->head; r != NULL; r = r->next) +- { +- count++; +- } +- return count; ++ return action_list->count; + } + +-static void +-map_removal_by_action (text_action_list *action_list) ++typedef struct map_action_fn_context_struct map_action_fn_context; ++struct map_action_fn_context_struct + { +- text_action *r; +- int removed = 0; ++ int removed; + removal_by_action_map map; + bfd_boolean eq_complete; ++}; + +- map.n_entries = 0; +- map.entry = bfd_malloc (action_list_count (action_list) * +- sizeof (removal_by_action_entry)); +- eq_complete = FALSE; ++static int ++map_action_fn (splay_tree_node node, void *p) ++{ ++ map_action_fn_context *ctx = p; ++ text_action *r = (text_action *)node->value; ++ removal_by_action_entry *ientry = ctx->map.entry + ctx->map.n_entries; + +- for (r = action_list->head; r;) ++ if (ctx->map.n_entries && (ientry - 1)->offset == r->offset) + { +- removal_by_action_entry *ientry = map.entry + map.n_entries; ++ --ientry; ++ } ++ else ++ { ++ ++ctx->map.n_entries; ++ ctx->eq_complete = FALSE; ++ ientry->offset = r->offset; ++ ientry->eq_removed_before_fill = ctx->removed; ++ } + +- if (map.n_entries && (ientry - 1)->offset == r->offset) ++ if (!ctx->eq_complete) ++ { ++ if (r->action != ta_fill || r->removed_bytes >= 0) + { +- --ientry; ++ ientry->eq_removed = ctx->removed; ++ ctx->eq_complete = TRUE; + } + else +- { +- ++map.n_entries; +- eq_complete = FALSE; +- ientry->offset = r->offset; +- ientry->eq_removed_before_fill = removed; +- } ++ ientry->eq_removed = ctx->removed + r->removed_bytes; ++ } + +- if (!eq_complete) +- { +- if (r->action != ta_fill || r->removed_bytes >= 0) +- { +- ientry->eq_removed = removed; +- eq_complete = TRUE; +- } +- else +- ientry->eq_removed = removed + r->removed_bytes; +- } ++ ctx->removed += r->removed_bytes; ++ ientry->removed = ctx->removed; ++ return 0; ++} + +- removed += r->removed_bytes; +- ientry->removed = removed; +- r = r->next; +- } +- action_list->map = map; ++static void ++map_removal_by_action (text_action_list *action_list) ++{ ++ map_action_fn_context ctx; ++ ++ ctx.removed = 0; ++ ctx.map.n_entries = 0; ++ ctx.map.entry = bfd_malloc (action_list_count (action_list) * ++ sizeof (removal_by_action_entry)); ++ ctx.eq_complete = FALSE; ++ ++ splay_tree_foreach (action_list->tree, map_action_fn, &ctx); ++ action_list->map = ctx.map; + } + + static int +@@ -5754,28 +5798,26 @@ offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) + static text_action * + find_insn_action (text_action_list *action_list, bfd_vma offset) + { +- text_action *t; +- for (t = action_list->head; t; t = t->next) ++ static const text_action_t action[] = + { +- if (t->offset == offset) +- { +- switch (t->action) +- { +- case ta_none: +- case ta_fill: +- break; +- case ta_remove_insn: +- case ta_remove_longcall: +- case ta_convert_longcall: +- case ta_narrow_insn: +- case ta_widen_insn: +- return t; +- case ta_remove_literal: +- case ta_add_literal: +- BFD_ASSERT (0); +- break; +- } +- } ++ ta_convert_longcall, ++ ta_remove_longcall, ++ ta_widen_insn, ++ ta_narrow_insn, ++ ta_remove_insn, ++ }; ++ text_action a; ++ unsigned i; ++ ++ a.offset = offset; ++ for (i = 0; i < sizeof (action) / sizeof (*action); ++i) ++ { ++ splay_tree_node node; ++ ++ a.action = action[i]; ++ node = splay_tree_lookup (action_list->tree, (splay_tree_key)&a); ++ if (node) ++ return (text_action *)node->value; + } + return NULL; + } +@@ -5784,40 +5826,50 @@ find_insn_action (text_action_list *action_list, bfd_vma offset) + #if DEBUG + + static void +-print_action_list (FILE *fp, text_action_list *action_list) ++print_action (FILE *fp, text_action *r) ++{ ++ const char *t = "unknown"; ++ switch (r->action) ++ { ++ case ta_remove_insn: ++ t = "remove_insn"; break; ++ case ta_remove_longcall: ++ t = "remove_longcall"; break; ++ case ta_convert_longcall: ++ t = "convert_longcall"; break; ++ case ta_narrow_insn: ++ t = "narrow_insn"; break; ++ case ta_widen_insn: ++ t = "widen_insn"; break; ++ case ta_fill: ++ t = "fill"; break; ++ case ta_none: ++ t = "none"; break; ++ case ta_remove_literal: ++ t = "remove_literal"; break; ++ case ta_add_literal: ++ t = "add_literal"; break; ++ } ++ ++ fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", ++ r->sec->owner->filename, ++ r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); ++} ++ ++static int ++print_action_list_fn (splay_tree_node node, void *p) + { +- text_action *r; ++ text_action *r = (text_action *)node->value; + +- fprintf (fp, "Text Action\n"); +- for (r = action_list->head; r != NULL; r = r->next) +- { +- const char *t = "unknown"; +- switch (r->action) +- { +- case ta_remove_insn: +- t = "remove_insn"; break; +- case ta_remove_longcall: +- t = "remove_longcall"; break; +- case ta_convert_longcall: +- t = "convert_longcall"; break; +- case ta_narrow_insn: +- t = "narrow_insn"; break; +- case ta_widen_insn: +- t = "widen_insn"; break; +- case ta_fill: +- t = "fill"; break; +- case ta_none: +- t = "none"; break; +- case ta_remove_literal: +- t = "remove_literal"; break; +- case ta_add_literal: +- t = "add_literal"; break; +- } ++ print_action (p, r); ++ return 0; ++} + +- fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", +- r->sec->owner->filename, +- r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); +- } ++static void ++print_action_list (FILE *fp, text_action_list *action_list) ++{ ++ fprintf (fp, "Text Action\n"); ++ splay_tree_foreach (action_list->tree, print_action_list_fn, fp); + } + + #endif /* DEBUG */ +@@ -6071,8 +6123,8 @@ init_xtensa_relax_info (asection *sec) + relax_info->removed_list.head = NULL; + relax_info->removed_list.tail = NULL; + +- relax_info->action_list.head = NULL; +- ++ relax_info->action_list.tree = splay_tree_new (text_action_compare, ++ NULL, NULL); + relax_info->action_list.map.n_entries = 0; + relax_info->action_list.map.entry = NULL; + +@@ -7762,7 +7814,7 @@ compute_text_actions (bfd *abfd, + free_reloc_range_list (&relevant_relocs); + + #if DEBUG +- if (relax_info->action_list.head) ++ if (action_list_count (&relax_info->action_list)) + print_action_list (stderr, &relax_info->action_list); + #endif + +@@ -8263,6 +8315,54 @@ xlate_offset_with_removed_text (const xlate_map_t *map, + return e->new_address - e->orig_address + offset; + } + ++typedef struct xlate_map_context_struct xlate_map_context; ++struct xlate_map_context_struct ++{ ++ xlate_map_t *map; ++ xlate_map_entry_t *current_entry; ++ int removed; ++}; ++ ++static int ++xlate_map_fn (splay_tree_node node, void *p) ++{ ++ text_action *r = (text_action *)node->value; ++ xlate_map_context *ctx = p; ++ unsigned orig_size = 0; ++ ++ switch (r->action) ++ { ++ case ta_none: ++ case ta_remove_insn: ++ case ta_convert_longcall: ++ case ta_remove_literal: ++ case ta_add_literal: ++ break; ++ case ta_remove_longcall: ++ orig_size = 6; ++ break; ++ case ta_narrow_insn: ++ orig_size = 3; ++ break; ++ case ta_widen_insn: ++ orig_size = 2; ++ break; ++ case ta_fill: ++ break; ++ } ++ ctx->current_entry->size = ++ r->offset + orig_size - ctx->current_entry->orig_address; ++ if (ctx->current_entry->size != 0) ++ { ++ ctx->current_entry++; ++ ctx->map->entry_count++; ++ } ++ ctx->current_entry->orig_address = r->offset + orig_size; ++ ctx->removed += r->removed_bytes; ++ ctx->current_entry->new_address = r->offset + orig_size - ctx->removed; ++ ctx->current_entry->size = 0; ++ return 0; ++} + + /* Build a binary searchable offset translation map from a section's + action list. */ +@@ -8270,75 +8370,40 @@ xlate_offset_with_removed_text (const xlate_map_t *map, + static xlate_map_t * + build_xlate_map (asection *sec, xtensa_relax_info *relax_info) + { +- xlate_map_t *map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); + text_action_list *action_list = &relax_info->action_list; + unsigned num_actions = 0; +- text_action *r; +- int removed; +- xlate_map_entry_t *current_entry; ++ xlate_map_context ctx; + +- if (map == NULL) ++ ctx.map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); ++ ++ if (ctx.map == NULL) + return NULL; + + num_actions = action_list_count (action_list); +- map->entry = (xlate_map_entry_t *) ++ ctx.map->entry = (xlate_map_entry_t *) + bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1)); +- if (map->entry == NULL) ++ if (ctx.map->entry == NULL) + { +- free (map); ++ free (ctx.map); + return NULL; + } +- map->entry_count = 0; ++ ctx.map->entry_count = 0; + +- removed = 0; +- current_entry = &map->entry[0]; ++ ctx.removed = 0; ++ ctx.current_entry = &ctx.map->entry[0]; + +- current_entry->orig_address = 0; +- current_entry->new_address = 0; +- current_entry->size = 0; ++ ctx.current_entry->orig_address = 0; ++ ctx.current_entry->new_address = 0; ++ ctx.current_entry->size = 0; + +- for (r = action_list->head; r != NULL; r = r->next) +- { +- unsigned orig_size = 0; +- switch (r->action) +- { +- case ta_none: +- case ta_remove_insn: +- case ta_convert_longcall: +- case ta_remove_literal: +- case ta_add_literal: +- break; +- case ta_remove_longcall: +- orig_size = 6; +- break; +- case ta_narrow_insn: +- orig_size = 3; +- break; +- case ta_widen_insn: +- orig_size = 2; +- break; +- case ta_fill: +- break; +- } +- current_entry->size = +- r->offset + orig_size - current_entry->orig_address; +- if (current_entry->size != 0) +- { +- current_entry++; +- map->entry_count++; +- } +- current_entry->orig_address = r->offset + orig_size; +- removed += r->removed_bytes; +- current_entry->new_address = r->offset + orig_size - removed; +- current_entry->size = 0; +- } ++ splay_tree_foreach (action_list->tree, xlate_map_fn, &ctx); + +- current_entry->size = (bfd_get_section_limit (sec->owner, sec) +- - current_entry->orig_address); +- if (current_entry->size != 0) +- map->entry_count++; ++ ctx.current_entry->size = (bfd_get_section_limit (sec->owner, sec) ++ - ctx.current_entry->orig_address); ++ if (ctx.current_entry->size != 0) ++ ctx.map->entry_count++; + +- return map; ++ return ctx.map; + } + + +@@ -9302,6 +9367,16 @@ move_shared_literal (asection *sec, + + /* Second relaxation pass. */ + ++static int ++action_remove_bytes_fn (splay_tree_node node, void *p) ++{ ++ bfd_size_type *final_size = p; ++ text_action *action = (text_action *)node->value; ++ ++ *final_size -= action->removed_bytes; ++ return 0; ++} ++ + /* Modify all of the relocations to point to the right spot, and if this + is a relaxable section, delete the unwanted literals and fix the + section size. */ +@@ -9334,7 +9409,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + + internal_relocs = retrieve_internal_relocs (abfd, sec, + link_info->keep_memory); +- if (!internal_relocs && !relax_info->action_list.head) ++ if (!internal_relocs && !action_list_count (&relax_info->action_list)) + return TRUE; + + contents = retrieve_contents (abfd, sec, link_info->keep_memory); +@@ -9412,6 +9487,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + } + /* Update the action so that the code that moves + the contents will do the right thing. */ ++ /* ta_remove_longcall and ta_remove_insn actions are ++ grouped together in the tree as well as ++ ta_convert_longcall and ta_none, so that changes below ++ can be done w/o removing and reinserting action into ++ the tree. */ ++ + if (action->action == ta_remove_longcall) + action->action = ta_remove_insn; + else +@@ -9584,13 +9665,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + + if ((relax_info->is_relaxable_literal_section + || relax_info->is_relaxable_asm_section) +- && relax_info->action_list.head) ++ && action_list_count (&relax_info->action_list)) + { + /* Walk through the planned actions and build up a table + of move, copy and fill records. Use the move, copy and + fill records to perform the actions once. */ + +- int removed = 0; + bfd_size_type final_size, copy_size, orig_insn_size; + bfd_byte *scratch = NULL; + bfd_byte *dup_contents = NULL; +@@ -9601,15 +9681,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */ + bfd_vma dup_dot = 0; + +- text_action *action = relax_info->action_list.head; ++ text_action *action; + + final_size = sec->size; +- for (action = relax_info->action_list.head; action; +- action = action->next) +- { +- final_size -= action->removed_bytes; +- } + ++ splay_tree_foreach (relax_info->action_list.tree, ++ action_remove_bytes_fn, &final_size); + scratch = (bfd_byte *) bfd_zmalloc (final_size); + dup_contents = (bfd_byte *) bfd_zmalloc (final_size); + +@@ -9618,8 +9695,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + print_action_list (stderr, &relax_info->action_list); + #endif + +- for (action = relax_info->action_list.head; action; +- action = action->next) ++ for (action = action_first (&relax_info->action_list); action; ++ action = action_next (&relax_info->action_list, action)) + { + virtual_action = FALSE; + if (action->offset > orig_dot) +@@ -9748,7 +9825,6 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) + break; + } + +- removed += action->removed_bytes; + BFD_ASSERT (dup_dot <= final_size); + BFD_ASSERT (orig_dot <= orig_size); + } +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch b/packages/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch new file mode 100644 index 0000000..043ff4d --- /dev/null +++ b/packages/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch @@ -0,0 +1,345 @@ +From cbe53e134d4c3a656880a906738ce19fdcd38e8b Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 1 May 2015 11:39:12 +0300 +Subject: [PATCH] xtensa: optimize trampolines relaxation + +Currently every fixup in the current segment is checked when relaxing +trampoline frag. This is very expensive. Make a searchable array of +fixups pointing at potentially oversized jumps at the beginning of every +relaxation pass and only check subset of this cache in the reach of +single jump from the trampoline frag currently being relaxed. + +Original profile: + +% time self children called name +----------------------------------------- + 370.16 593.38 12283048/12283048 relax_segment + 98.4 370.16 593.38 12283048 xtensa_relax_frag + 58.91 269.26 2691463834/2699602236 xtensa_insnbuf_from_chars + 68.35 68.17 811266668/813338977 S_GET_VALUE + 36.85 29.51 2684369246/2685538060 xtensa_opcode_decode + 28.34 8.84 2684369246/2685538060 xtensa_format_get_slot + 12.39 5.94 2691463834/2699775044 xtensa_format_decode + 0.03 4.60 4101109/4101109 relax_frag_for_align + 0.18 1.76 994617/994617 relax_frag_immed + 0.07 0.09 24556277/24851220 new_logical_line + 0.06 0.00 12283048/14067410 as_where + 0.04 0.00 7094588/15460506 xtensa_format_num_slots + 0.00 0.00 1/712477 xtensa_insnbuf_alloc +----------------------------------------- + +Same data, after optimization: + +% time self children called name +----------------------------------------- + 0.51 7.47 12283048/12283048 relax_segment + 58.0 0.51 7.47 12283048 xtensa_relax_frag + 0.02 4.08 4101109/4101109 relax_frag_for_align + 0.18 1.39 994617/994617 relax_frag_immed + 0.01 0.98 555/555 xtensa_cache_relaxable_fixups + 0.21 0.25 7094588/16693271 xtensa_insnbuf_from_chars + 0.06 0.12 24556277/24851220 new_logical_line + 0.06 0.00 7094588/15460506 xtensa_format_num_slots + 0.02 0.04 7094588/16866079 xtensa_format_decode + 0.05 0.00 12283048/14067410 as_where + 0.00 0.00 1/712477 xtensa_insnbuf_alloc + 0.00 0.00 93808/93808 xtensa_find_first_cached_fixup +----------------------------------------- + +2015-05-02 Max Filippov +gas/ + * config/tc-xtensa.c (cached_fixupS, fixup_cacheS): New typedefs. + (struct cached_fixup, struct fixup_cache): New structures. + (fixup_order, xtensa_make_cached_fixup), + (xtensa_realloc_fixup_cache, xtensa_cache_relaxable_fixups), + (xtensa_find_first_cached_fixup, xtensa_delete_cached_fixup), + (xtensa_add_cached_fixup): New functions. + (xtensa_relax_frag): Cache fixups pointing at potentially + oversized jumps at the beginning of every relaxation pass. Only + check subset of this cache in the reach of single jump from the + trampoline frag currently being relaxed. + +Signed-off-by: Max Filippov +--- +Backported from: b76f99d702c3501ac320396ea06bc7f9237173c3 +Changes to ChangeLog are dropped. + + gas/config/tc-xtensa.c | 220 +++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 194 insertions(+), 26 deletions(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 3e85b69..31c0b6b 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -8785,6 +8785,154 @@ static long relax_frag_for_align (fragS *, long); + static long relax_frag_immed + (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean); + ++typedef struct cached_fixup cached_fixupS; ++struct cached_fixup ++{ ++ int addr; ++ int target; ++ int delta; ++ fixS *fixP; ++}; ++ ++typedef struct fixup_cache fixup_cacheS; ++struct fixup_cache ++{ ++ cached_fixupS *fixups; ++ unsigned n_fixups; ++ unsigned n_max; ++ ++ segT seg; ++ fragS *first_frag; ++}; ++ ++static int fixup_order (const void *a, const void *b) ++{ ++ const cached_fixupS *pa = a; ++ const cached_fixupS *pb = b; ++ ++ if (pa->addr == pb->addr) ++ { ++ if (pa->target == pb->target) ++ { ++ if (pa->fixP->fx_r_type == pb->fixP->fx_r_type) ++ return 0; ++ return pa->fixP->fx_r_type < pb->fixP->fx_r_type ? -1 : 1; ++ } ++ return pa->target - pb->target; ++ } ++ return pa->addr - pb->addr; ++} ++ ++static bfd_boolean xtensa_make_cached_fixup (cached_fixupS *o, fixS *fixP) ++{ ++ xtensa_isa isa = xtensa_default_isa; ++ int addr = fixP->fx_frag->fr_address; ++ int target; ++ int delta; ++ symbolS *s = fixP->fx_addsy; ++ int slot; ++ xtensa_format fmt; ++ xtensa_opcode opcode; ++ ++ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || ++ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) ++ return FALSE; ++ target = S_GET_VALUE (s); ++ delta = target - addr; ++ ++ if (abs(delta) < J_RANGE / 2) ++ return FALSE; ++ ++ xtensa_insnbuf_from_chars (isa, trampoline_buf, ++ (unsigned char *) fixP->fx_frag->fr_literal + ++ fixP->fx_where, 0); ++ fmt = xtensa_format_decode (isa, trampoline_buf); ++ gas_assert (fmt != XTENSA_UNDEFINED); ++ slot = fixP->tc_fix_data.slot; ++ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); ++ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); ++ if (opcode != xtensa_j_opcode) ++ return FALSE; ++ ++ o->addr = addr; ++ o->target = target; ++ o->delta = delta; ++ o->fixP = fixP; ++ ++ return TRUE; ++} ++ ++static void xtensa_realloc_fixup_cache (fixup_cacheS *cache, unsigned add) ++{ ++ if (cache->n_fixups + add > cache->n_max) ++ { ++ cache->n_max = (cache->n_fixups + add) * 2; ++ cache->fixups = xrealloc (cache->fixups, ++ sizeof (*cache->fixups) * cache->n_max); ++ } ++} ++ ++static void xtensa_cache_relaxable_fixups (fixup_cacheS *cache, ++ segment_info_type *seginfo) ++{ ++ fixS *fixP; ++ ++ cache->n_fixups = 0; ++ ++ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ { ++ xtensa_realloc_fixup_cache (cache, 1); ++ ++ if (xtensa_make_cached_fixup (cache->fixups + cache->n_fixups, fixP)) ++ ++cache->n_fixups; ++ } ++ qsort (cache->fixups, cache->n_fixups, sizeof (*cache->fixups), fixup_order); ++} ++ ++static unsigned xtensa_find_first_cached_fixup (const fixup_cacheS *cache, ++ int addr) ++{ ++ unsigned a = 0; ++ unsigned b = cache->n_fixups; ++ ++ while (b - a > 1) ++ { ++ unsigned c = (a + b) / 2; ++ ++ if (cache->fixups[c].addr < addr) ++ a = c; ++ else ++ b = c; ++ } ++ return a; ++} ++ ++static void xtensa_delete_cached_fixup (fixup_cacheS *cache, unsigned i) ++{ ++ memmove (cache->fixups + i, cache->fixups + i + 1, ++ (cache->n_fixups - i - 1) * sizeof (*cache->fixups)); ++ --cache->n_fixups; ++} ++ ++static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP) ++{ ++ cached_fixupS o; ++ unsigned i; ++ ++ if (!xtensa_make_cached_fixup (&o, fixP)) ++ return FALSE; ++ xtensa_realloc_fixup_cache (cache, 1); ++ i = xtensa_find_first_cached_fixup (cache, o.addr); ++ if (i < cache->n_fixups) ++ { ++ ++i; ++ memmove (cache->fixups + i + 1, cache->fixups + i, ++ (cache->n_fixups - i) * sizeof (*cache->fixups)); ++ } ++ cache->fixups[i] = o; ++ ++cache->n_fixups; ++ return TRUE; ++} + + /* Return the number of bytes added to this fragment, given that the + input has been stretched already by "stretch". */ +@@ -8896,35 +9044,42 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + case RELAX_TRAMPOLINE: + if (fragP->tc_frag_data.relax_seen) + { +- segment_info_type *seginfo = seg_info (now_seg); +- fragS *fP; /* The out-of-range jump. */ +- fixS *fixP; ++ static fixup_cacheS fixup_cache; ++ segment_info_type *seginfo = seg_info (now_seg); ++ int trampaddr = fragP->fr_address + fragP->fr_fix; ++ int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE; ++ unsigned i; ++ ++ if (now_seg != fixup_cache.seg || ++ fragP == fixup_cache.first_frag || ++ fixup_cache.first_frag == NULL) ++ { ++ xtensa_cache_relaxable_fixups (&fixup_cache, seginfo); ++ fixup_cache.seg = now_seg; ++ fixup_cache.first_frag = fragP; ++ } + + /* Scan for jumps that will not reach. */ +- for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) ++ for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr); ++ i < fixup_cache.n_fixups; ++i) ++ + { +- symbolS *s = fixP->fx_addsy; +- xtensa_opcode opcode; +- int target; +- int addr; +- int delta; +- +- if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || +- fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) +- continue; +- xtensa_insnbuf_from_chars (isa, trampoline_buf, +- (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, +- 0); +- fmt = xtensa_format_decode (isa, trampoline_buf); +- gas_assert (fmt != XTENSA_UNDEFINED); +- slot = fixP->tc_fix_data.slot; +- xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); +- opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); +- if (opcode != xtensa_j_opcode) ++ fixS *fixP = fixup_cache.fixups[i].fixP; ++ int target = fixup_cache.fixups[i].target; ++ int addr = fixup_cache.fixups[i].addr; ++ int delta = fixup_cache.fixups[i].delta + stretch; ++ ++ trampaddr = fragP->fr_address + fragP->fr_fix; ++ ++ if (addr + J_RANGE < trampaddr) + continue; +- target = S_GET_VALUE (s); +- addr = fixP->fx_frag->fr_address; +- delta = target - addr + stretch; ++ if (addr > trampaddr + J_RANGE) ++ break; ++ if (abs (delta) < J_RANGE) ++ continue; ++ ++ slot = fixP->tc_fix_data.slot; ++ + if (delta > J_RANGE || delta < -1 * J_RANGE) + { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ + struct trampoline_seg *ts = find_trampoline_seg (now_seg); +@@ -8978,14 +9133,13 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + } + if (tf->fragP == fragP) + { +- int trampaddr = fragP->fr_address + fragP->fr_fix; +- + if (abs (addr - trampaddr) < J_RANGE) + { /* The trampoline is in range of original; fix it! */ + fixS *newfixP; + int offset; + TInsn insn; + symbolS *lsym; ++ fragS *fP; /* The out-of-range jump. */ + + new_stretch += init_trampoline_frag (tf); + offset = fragP->fr_fix; /* Where to assemble the j insn. */ +@@ -9009,10 +9163,20 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + newfixP->tc_fix_data.X_add_symbol = lsym; + newfixP->tc_fix_data.X_add_number = offset; + newfixP->tc_fix_data.slot = slot; ++ ++ xtensa_delete_cached_fixup (&fixup_cache, i); ++ xtensa_add_cached_fixup (&fixup_cache, newfixP); ++ + /* Move the fix-up from the original j insn to this one. */ + fixP->fx_frag = fragP; + fixP->fx_where = fragP->fr_fix - 3; + fixP->tc_fix_data.slot = 0; ++ ++ xtensa_add_cached_fixup (&fixup_cache, fixP); ++ ++ /* re-do current fixup */ ++ --i; ++ + /* Adjust the jump around this trampoline (if present). */ + if (tf->fixP != NULL) + { +@@ -9027,6 +9191,8 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + fragP->fr_subtype = 0; + /* Remove from the trampoline_list. */ + prev->next = tf->next; ++ if (fragP == fixup_cache.first_frag) ++ fixup_cache.first_frag = NULL; + break; + } + } +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/packages/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch new file mode 100644 index 0000000..9ad6b3b --- /dev/null +++ b/packages/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch @@ -0,0 +1,57 @@ +From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Thu, 14 May 2015 05:22:55 +0300 +Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections + +elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were +made local, that results in link failure with the following message: + + BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line + 3372 in elf_xtensa_finish_dynamic_sections + +elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by +relocation type. Relocation types are not changed when symbol becomes +local, but its PLT references are added to GOT references and +plt.refcount is set to 0. Such symbol cannot be unreferences in the +elf_xtensa_gc_sweep_hook and its extra references make calculated GOT +relocations section size not match number of GOT relocations. + +Fix it by treating PLT reference as GOT reference when plt.refcount is +not positive. + +2015-05-14 Max Filippov +bfd/ + * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference + as GOT reference when plt.refcount is not positive. + +Signed-off-by: Max Filippov +--- +Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 +Changes to ChangeLog are dropped. + + bfd/elf32-xtensa.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index 53af1c6..2523670 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, + { + if (is_plt) + { ++ /* If the symbol has been localized its plt.refcount got moved ++ to got.refcount. Handle it as GOT. */ + if (h->plt.refcount > 0) + h->plt.refcount--; ++ else ++ is_got = TRUE; + } +- else if (is_got) ++ if (is_got) + { + if (h->got.refcount > 0) + h->got.refcount--; +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/packages/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch new file mode 100644 index 0000000..4a3de2c --- /dev/null +++ b/packages/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch @@ -0,0 +1,56 @@ +From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 17 May 2015 06:46:15 +0300 +Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals + +When --text-section-literals is used and code in the .init or .fini +emits literal in the absence of .literal_position, xtensa_move_literals +segfaults. + +Check that search_frag is non-NULL in the xtensa_move_literals and +report error otherwise. + +2015-05-26 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Check that + search_frag is non-NULL. Report error if literal frag is not + found. + +Signed-off-by: Max Filippov +--- +Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 +Changes to ChangeLog are dropped. + + gas/config/tc-xtensa.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 31c0b6b..18307c1 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) + frchain_to = NULL; + frag_splice = &(frchain_from->frch_root); + +- while (!search_frag->tc_frag_data.literal_frag) ++ while (search_frag && !search_frag->tc_frag_data.literal_frag) + { + gas_assert (search_frag->fr_fix == 0 + || search_frag->fr_type == rs_align); + search_frag = search_frag->fr_next; + } + ++ if (!search_frag) ++ { ++ search_frag = frchain_from->frch_root; ++ as_bad_where (search_frag->fr_file, search_frag->fr_line, ++ _("literal pool location required for text-section-literals; specify with .literal_position")); ++ continue; ++ } ++ + gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype + == RELAX_LITERAL_POOL_BEGIN); + xtensa_switch_section_emit_state (&state, segment->seg, 0); +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch b/packages/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch new file mode 100644 index 0000000..3ed9af1 --- /dev/null +++ b/packages/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch @@ -0,0 +1,699 @@ +From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Wed, 29 Jul 2015 17:42:54 +0300 +Subject: [PATCH] xtensa: add --auto-litpools option + +Auto-litpools is the automated version of text-section-literals: literal +pool candidate frags are planted every N frags and during relaxation +they are turned into actual literal pools where literals are moved to +become reachable for their first reference by L32R instruction. + +2015-08-12 David Weatherford +gas/ + * config/tc-xtensa.c (struct litpool_frag, struct litpool_seg): + New structures. + (xtensa_maybe_create_literal_pool_frag): New function. + (litpool_seg_list, auto_litpools, auto_litpool_limit) + (litpool_buf, litpool_slotbuf): New static variables. + (option_auto_litpools, option_no_auto_litpools) + (option_auto_litpool_limit): New enum identifiers. + (md_longopts): Add entries for auto-litpools, no-auto-litpools + and auto-litpool-limit. + (md_parse_option): Handle option_auto_litpools, + option_no_auto_litpools and option_auto_litpool_limit. + (md_show_usage): Add help for --[no-]auto-litpools and + --auto-litpool-limit. + (xtensa_mark_literal_pool_location): Record a place for literal + pool with a call to xtensa_maybe_create_literal_pool_frag. + (get_literal_pool_location): Find highest priority literal pool + or convert candidate to literal pool when auto-litpools are used. + (xg_assemble_vliw_tokens): Create literal pool after jump + instruction. + (xtensa_check_frag_count): Create candidate literal pool every + auto_litpool_limit frags. + (xtensa_relax_frag): Add jump around literals to non-empty + literal pool. + (xtensa_move_literals): Estimate literal pool addresses and move + unreachable literals closer to their users, converting candidate + to literal pool if needed. + (xtensa_switch_to_non_abs_literal_fragment): Only emit error + about missing .literal_position in case auto-litpools are not + used. + * config/tc-xtensa.h (xtensa_relax_statesE): New relaxation + state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN. + +2015-08-12 Max Filippov +gas/testsuite/ + * gas/xtensa/all.exp: Add auto-litpools to the list of xtensa + tests. + * gas/xtensa/auto-litpools.s: New file: auto-litpools test. + * gas/xtensa/auto-litpools.s: New file: auto-litpools test + result pattern. + +Signed-off-by: Max Filippov +--- +Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5 +Changes to ChangeLogs and documentation are dropped. + + gas/config/tc-xtensa.c | 432 ++++++++++++++++++++++++++++++- + gas/config/tc-xtensa.h | 1 + + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/auto-litpools.d | 12 + + gas/testsuite/gas/xtensa/auto-litpools.s | 13 + + 5 files changed, 454 insertions(+), 5 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d + create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 7311a05..b8b1e7d 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -440,6 +440,29 @@ bfd_boolean directive_state[] = + #endif + }; + ++/* A circular list of all potential and actual literal pool locations ++ in a segment. */ ++struct litpool_frag ++{ ++ struct litpool_frag *next; ++ struct litpool_frag *prev; ++ fragS *fragP; ++ addressT addr; ++ short priority; /* 1, 2, or 3 -- 1 is highest */ ++ short original_priority; ++}; ++ ++/* Map a segment to its litpool_frag list. */ ++struct litpool_seg ++{ ++ struct litpool_seg *next; ++ asection *seg; ++ struct litpool_frag frag_list; ++ int frag_count; /* since last litpool location */ ++}; ++ ++static struct litpool_seg litpool_seg_list; ++ + + /* Directive functions. */ + +@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean); + static void xtensa_maybe_create_trampoline_frag (void); + struct trampoline_frag; + static int init_trampoline_frag (struct trampoline_frag *); ++static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean); ++static bfd_boolean auto_litpools = FALSE; ++static int auto_litpool_limit = 10000; + + /* Alignment Functions. */ + +@@ -698,6 +724,10 @@ enum + + option_trampolines, + option_no_trampolines, ++ ++ option_auto_litpools, ++ option_no_auto_litpools, ++ option_auto_litpool_limit, + }; + + const char *md_shortopts = ""; +@@ -773,6 +803,10 @@ struct option md_longopts[] = + { "trampolines", no_argument, NULL, option_trampolines }, + { "no-trampolines", no_argument, NULL, option_no_trampolines }, + ++ { "auto-litpools", no_argument, NULL, option_auto_litpools }, ++ { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools }, ++ { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit }, ++ + { NULL, no_argument, NULL, 0 } + }; + +@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg) + use_trampolines = FALSE; + return 1; + ++ case option_auto_litpools: ++ auto_litpools = TRUE; ++ use_literal_section = FALSE; ++ return 1; ++ ++ case option_no_auto_litpools: ++ auto_litpools = FALSE; ++ auto_litpool_limit = -1; ++ return 1; ++ ++ case option_auto_litpool_limit: ++ { ++ int value = 0; ++ if (auto_litpool_limit < 0) ++ as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit")); ++ if (*arg == 0 || *arg == '-') ++ as_fatal (_("invalid auto-litpool-limit argument")); ++ value = strtol (arg, &arg, 10); ++ if (*arg != 0) ++ as_fatal (_("invalid auto-litpool-limit argument")); ++ if (value < 100 || value > 10000) ++ as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)")); ++ auto_litpool_limit = value; ++ auto_litpools = TRUE; ++ use_literal_section = FALSE; ++ return 1; ++ } ++ + default: + return 0; + } +@@ -986,7 +1048,12 @@ Xtensa options:\n\ + flix bundles\n\ + --rename-section old=new Rename section 'old' to 'new'\n\ + --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ +- when jumps do not reach their targets\n", stream); ++ when jumps do not reach their targets\n\ ++ --[no-]auto-litpools [Do not] automatically create literal pools\n\ ++ --auto-litpool-limit=\n\ ++ (range 100-10000) Maximum number of blocks of\n\ ++ instructions to emit between literal pool\n\ ++ locations; implies --auto-litpools flag\n", stream); + } + + +@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void) + pool_location = frag_now; + frag_now->tc_frag_data.lit_frchain = frchain_now; + frag_now->tc_frag_data.literal_frag = frag_now; ++ /* Just record this frag. */ ++ xtensa_maybe_create_literal_pool_frag (FALSE, FALSE); + frag_variant (rs_machine_dependent, 0, 0, + RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL); + xtensa_set_frag_assembly_state (frag_now); +@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode) + static fragS * + get_literal_pool_location (segT seg) + { ++ struct litpool_seg *lps = litpool_seg_list.next; ++ struct litpool_frag *lpf; ++ for ( ; lps && lps->seg->id != seg->id; lps = lps->next) ++ ; ++ if (lps) ++ { ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { /* Skip "candidates" for now. */ ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && ++ lpf->priority == 1) ++ return lpf->fragP; ++ } ++ /* Must convert a lower-priority pool. */ ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) ++ return lpf->fragP; ++ } ++ /* Still no match -- try for a low priority pool. */ ++ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) ++ { ++ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) ++ return lpf->fragP; ++ } ++ } + return seg_info (seg)->tc_segment_info_data.literal_pool_loc; + } + +@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol; + frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset; + frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag; ++ if (tinsn->opcode == xtensa_l32r_opcode) ++ { ++ frag_now->tc_frag_data.literal_frags[slot] = ++ tinsn->tok[1].X_add_symbol->sy_frag; ++ } + if (tinsn->literal_space != 0) + xg_assemble_literal_space (tinsn->literal_space, slot); + frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg; +@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) + frag_now->fr_symbol, frag_now->fr_offset, NULL); + xtensa_set_frag_assembly_state (frag_now); + xtensa_maybe_create_trampoline_frag (); ++ /* Always create one here. */ ++ xtensa_maybe_create_literal_pool_frag (TRUE, FALSE); + } + else if (is_branch && do_align_targets ()) + { +@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void) + clear_frag_count (); + unreachable_count = 0; + } ++ ++ /* We create an area for a possible literal pool every N (default 5000) ++ frags or so. */ ++ xtensa_maybe_create_literal_pool_frag (TRUE, TRUE); + } + + static xtensa_insnbuf trampoline_buf = NULL; + static xtensa_insnbuf trampoline_slotbuf = NULL; + ++static xtensa_insnbuf litpool_buf = NULL; ++static xtensa_insnbuf litpool_slotbuf = NULL; ++ + #define TRAMPOLINE_FRAG_SIZE 3000 + + static void +@@ -7410,6 +7518,135 @@ dump_trampolines (void) + } + } + ++static void dump_litpools (void) __attribute__ ((unused)); ++ ++static void ++dump_litpools (void) ++{ ++ struct litpool_seg *lps = litpool_seg_list.next; ++ struct litpool_frag *lpf; ++ ++ for ( ; lps ; lps = lps->next ) ++ { ++ printf("litpool seg %s\n", lps->seg->name); ++ for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next ) ++ { ++ fragS *litfrag = lpf->fragP->fr_next; ++ int count = 0; ++ while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END) ++ { ++ if (litfrag->fr_fix == 4) ++ count++; ++ litfrag = litfrag->fr_next; ++ } ++ printf(" %ld <%d:%d> (%d) [%d]: ", ++ lpf->addr, lpf->priority, lpf->original_priority, ++ lpf->fragP->fr_line, count); ++ //dump_frag(lpf->fragP); ++ } ++ } ++} ++ ++static void ++xtensa_maybe_create_literal_pool_frag (bfd_boolean create, ++ bfd_boolean only_if_needed) ++{ ++ struct litpool_seg *lps = litpool_seg_list.next; ++ fragS *fragP; ++ struct litpool_frag *lpf; ++ bfd_boolean needed = FALSE; ++ ++ if (use_literal_section || !auto_litpools) ++ return; ++ ++ for ( ; lps ; lps = lps->next ) ++ { ++ if (lps->seg == now_seg) ++ break; ++ } ++ ++ if (lps == NULL) ++ { ++ lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1); ++ lps->next = litpool_seg_list.next; ++ litpool_seg_list.next = lps; ++ lps->seg = now_seg; ++ lps->frag_list.next = &lps->frag_list; ++ lps->frag_list.prev = &lps->frag_list; ++ } ++ ++ lps->frag_count++; ++ ++ if (create) ++ { ++ if (only_if_needed) ++ { ++ if (past_xtensa_end || !use_transform() || ++ frag_now->tc_frag_data.is_no_transform) ++ { ++ return; ++ } ++ if (auto_litpool_limit <= 0) ++ { ++ /* Don't create a litpool based only on frag count. */ ++ return; ++ } ++ else if (lps->frag_count > auto_litpool_limit) ++ { ++ needed = TRUE; ++ } ++ else ++ { ++ return; ++ } ++ } ++ else ++ { ++ needed = TRUE; ++ } ++ } ++ ++ if (needed) ++ { ++ int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn. */ ++ /* Create a potential site for a literal pool. */ ++ frag_wane (frag_now); ++ frag_new (0); ++ xtensa_set_frag_assembly_state (frag_now); ++ fragP = frag_now; ++ fragP->tc_frag_data.lit_frchain = frchain_now; ++ fragP->tc_frag_data.literal_frag = fragP; ++ frag_var (rs_machine_dependent, size, size, ++ (only_if_needed) ? ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN : ++ RELAX_LITERAL_POOL_BEGIN, ++ NULL, 0, NULL); ++ frag_now->tc_frag_data.lit_seg = now_seg; ++ frag_variant (rs_machine_dependent, 0, 0, ++ RELAX_LITERAL_POOL_END, NULL, 0, NULL); ++ xtensa_set_frag_assembly_state (frag_now); ++ } ++ else ++ { ++ /* RELAX_LITERAL_POOL_BEGIN frag is being created; ++ just record it here. */ ++ fragP = frag_now; ++ } ++ ++ lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag)); ++ /* Insert at tail of circular list. */ ++ lpf->addr = 0; ++ lps->frag_list.prev->next = lpf; ++ lpf->next = &lps->frag_list; ++ lpf->prev = lps->frag_list.prev; ++ lps->frag_list.prev = lpf; ++ lpf->fragP = fragP; ++ lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1; ++ lpf->original_priority = lpf->priority; ++ ++ lps->frag_count = 0; ++} ++ + static void + xtensa_cleanup_align_frags (void) + { +@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) + break; + + case RELAX_LITERAL_POOL_BEGIN: ++ if (fragP->fr_var != 0) ++ { ++ /* We have a converted "candidate" literal pool; ++ assemble a jump around it. */ ++ TInsn insn; ++ if (!litpool_slotbuf) ++ { ++ litpool_buf = xtensa_insnbuf_alloc (isa); ++ litpool_slotbuf = xtensa_insnbuf_alloc (isa); ++ } ++ new_stretch += 3; ++ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ ++ fragP->tc_frag_data.is_insn = TRUE; ++ tinsn_init (&insn); ++ insn.insn_type = ITYPE_INSN; ++ insn.opcode = xtensa_j_opcode; ++ insn.ntok = 1; ++ set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol, ++ fragP->fr_fix); ++ fmt = xg_get_single_format (xtensa_j_opcode); ++ tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf); ++ xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf); ++ xtensa_insnbuf_to_chars (isa, litpool_buf, ++ (unsigned char *)fragP->fr_literal + ++ fragP->fr_fix, 3); ++ fragP->fr_fix += 3; ++ fragP->fr_var -= 3; ++ /* Add a fix-up. */ ++ fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE, ++ BFD_RELOC_XTENSA_SLOT0_OP); ++ } ++ break; ++ + case RELAX_LITERAL_POOL_END: ++ case RELAX_LITERAL_POOL_CANDIDATE_BEGIN: + case RELAX_MAYBE_UNREACHABLE: + case RELAX_MAYBE_DESIRE_ALIGN: + /* No relaxation required. */ +@@ -10789,12 +11060,115 @@ xtensa_move_literals (void) + segT dest_seg; + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; ++ struct litpool_seg *lps; + + mark_literal_frags (literal_head->next); + + if (use_literal_section) + return; + ++ /* Assign addresses (rough estimates) to the potential literal pool locations ++ and create new ones if the gaps are too large. */ ++ ++ for (lps = litpool_seg_list.next; lps; lps = lps->next) ++ { ++ frchainS *frchP = seg_info (lps->seg)->frchainP; ++ struct litpool_frag *lpf = lps->frag_list.next; ++ addressT addr = 0; ++ ++ for ( ; frchP; frchP = frchP->frch_next) ++ { ++ fragS *fragP; ++ for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next) ++ { ++ if (lpf && fragP == lpf->fragP) ++ { ++ gas_assert(fragP->fr_type == rs_machine_dependent && ++ (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN || ++ fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)); ++ /* Found a litpool location. */ ++ lpf->addr = addr; ++ lpf = lpf->next; ++ } ++ if (fragP->fr_type == rs_machine_dependent && ++ fragP->fr_subtype == RELAX_SLOTS) ++ { ++ int slot; ++ for (slot = 0; slot < MAX_SLOTS; slot++) ++ { ++ if (fragP->tc_frag_data.literal_frags[slot]) ++ { ++ /* L32R; point its literal to the nearest litpool ++ preferring non-"candidate" positions to avoid ++ the jump-around. */ ++ fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; ++ struct litpool_frag *lp = lpf->prev; ++ if (!lp->fragP) ++ { ++ break; ++ } ++ while (lp->fragP->fr_subtype == ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN) ++ { ++ lp = lp->prev; ++ if (lp->fragP == NULL) ++ { ++ /* End of list; have to bite the bullet. ++ Take the nearest. */ ++ lp = lpf->prev; ++ break; ++ } ++ /* Does it (conservatively) reach? */ ++ if (addr - lp->addr <= 128 * 1024) ++ { ++ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) ++ { ++ /* Found a good one. */ ++ break; ++ } ++ else if (lp->prev->fragP && ++ addr - lp->prev->addr > 128 * 1024) ++ { ++ /* This is still a "candidate" but the next one ++ will be too far away, so revert to the nearest ++ one, convert it and add the jump around. */ ++ fragS *poolbeg; ++ fragS *poolend; ++ symbolS *lsym; ++ char label[10 + 2 * sizeof (fragS *)]; ++ lp = lpf->prev; ++ poolbeg = lp->fragP; ++ lp->priority = 1; ++ poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; ++ poolend = poolbeg->fr_next; ++ gas_assert (poolend->fr_type == rs_machine_dependent && ++ poolend->fr_subtype == RELAX_LITERAL_POOL_END); ++ /* Create a local symbol pointing to the ++ end of the pool. */ ++ sprintf (label, ".L0_LT_%p", poolbeg); ++ lsym = (symbolS *)local_symbol_make (label, lps->seg, ++ 0, poolend); ++ poolbeg->fr_symbol = lsym; ++ /* Rest is done in xtensa_relax_frag. */ ++ } ++ } ++ } ++ if (! litfrag->tc_frag_data.literal_frag) ++ { ++ /* Take earliest use of this literal to avoid ++ forward refs. */ ++ litfrag->tc_frag_data.literal_frag = lp->fragP; ++ } ++ } ++ } ++ } ++ addr += fragP->fr_fix; ++ if (fragP->fr_type == rs_fill) ++ addr += fragP->fr_offset; ++ } ++ } ++ } ++ + for (segment = literal_head->next; segment; segment = segment->next) + { + /* Keep the literals for .init and .fini in separate sections. */ +@@ -10839,9 +11213,6 @@ xtensa_move_literals (void) + while (search_frag != frag_now) + { + next_frag = search_frag->fr_next; +- +- /* First, move the frag out of the literal section and +- to the appropriate place. */ + if (search_frag->tc_frag_data.literal_frag) + { + literal_pool = search_frag->tc_frag_data.literal_frag; +@@ -10849,8 +11220,56 @@ xtensa_move_literals (void) + frchain_to = literal_pool->tc_frag_data.lit_frchain; + gas_assert (frchain_to); + } ++ ++ if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0) ++ { ++ /* Skip empty fill frags. */ ++ *frag_splice = next_frag; ++ search_frag = next_frag; ++ continue; ++ } ++ ++ if (search_frag->fr_type == rs_align) ++ { ++ /* Skip alignment frags, because the pool as a whole will be ++ aligned if used, and we don't want to force alignment if the ++ pool is unused. */ ++ *frag_splice = next_frag; ++ search_frag = next_frag; ++ continue; ++ } ++ ++ /* First, move the frag out of the literal section and ++ to the appropriate place. */ ++ ++ /* Insert an aligmnent frag at start of pool. */ ++ if (literal_pool->fr_next->fr_type == rs_machine_dependent && ++ literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END) ++ { ++ segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg; ++ emit_state prev_state; ++ fragS *prev_frag; ++ fragS *align_frag; ++ xtensa_switch_section_emit_state (&prev_state, pool_seg, 0); ++ prev_frag = frag_now; ++ frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL); ++ align_frag = frag_now; ++ frag_align (2, 0, 0); ++ /* Splice it into the right place. */ ++ prev_frag->fr_next = align_frag->fr_next; ++ align_frag->fr_next = literal_pool->fr_next; ++ literal_pool->fr_next = align_frag; ++ /* Insert after this one. */ ++ literal_pool->tc_frag_data.literal_frag = align_frag; ++ xtensa_restore_emit_state (&prev_state); ++ } + insert_after = literal_pool->tc_frag_data.literal_frag; + dest_seg = insert_after->fr_next->tc_frag_data.lit_seg; ++ /* Skip align frag. */ ++ if (insert_after->fr_next->fr_type == rs_align) ++ { ++ insert_after = insert_after->fr_next; ++ } + + *frag_splice = next_frag; + search_frag->fr_next = insert_after->fr_next; +@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) + && !recursive + && !is_init && ! is_fini) + { +- as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); ++ if (!auto_litpools) ++ { ++ as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); ++ } + + /* When we mark a literal pool location, we want to put a frag in + the literal pool that points to it. But to do that, we want to +diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h +index b2e43fa..290d902 100644 +--- a/gas/config/tc-xtensa.h ++++ b/gas/config/tc-xtensa.h +@@ -124,6 +124,7 @@ enum xtensa_relax_statesE + + RELAX_LITERAL_POOL_BEGIN, + RELAX_LITERAL_POOL_END, ++ RELAX_LITERAL_POOL_CANDIDATE_BEGIN, + /* Technically these are not relaxations at all but mark a location + to store literals later. Note that fr_var stores the frchain for + BEGIN frags and fr_var stores now_seg for END frags. */ +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index d197ec8..db39629 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -100,6 +100,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "jlong" + run_dump_test "trampoline" + run_dump_test "first_frag_align" ++ run_dump_test "auto-litpools" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d +new file mode 100644 +index 0000000..4d1a690 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/auto-litpools.d +@@ -0,0 +1,12 @@ ++#as: --auto-litpools ++#objdump: -d ++#name: auto literal pool placement ++ ++.*: +file format .*xtensa.* ++#... ++.*4:.*l32r.a2, 0 .* ++#... ++.*3e437:.*j.3e440 .* ++#... ++.*40750:.*l32r.a2, 3e43c .* ++#... +diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s +new file mode 100644 +index 0000000..9a5b26b +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/auto-litpools.s +@@ -0,0 +1,13 @@ ++ .text ++ .align 4 ++ .literal .L0, 0x12345 ++ .literal .L1, 0x12345 ++ ++f: ++ l32r a2, .L0 ++ .rep 44000 ++ _nop ++ _nop ++ .endr ++ l32r a2, .L1 ++ ret +-- +1.8.1.4 + diff --git a/packages/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch b/packages/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch new file mode 100644 index 0000000..66d4e60 --- /dev/null +++ b/packages/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch @@ -0,0 +1,98 @@ +From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 2 Feb 2016 17:11:38 +0300 +Subject: [PATCH] xtensa: fix signedness of gas relocations + +Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation +offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations +substituted for BFD_RELOC_*. This made it impossible to encode arbitrary +8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc +directive. Revert this part and add test. + +gas/ +2016-02-03 Max Filippov + * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* + substitutions for BFD_RELOC_* as unsigned. + * gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa + tests. + * gas/testsuite/gas/xtensa/loc.d: New file: loc test result + patterns. + * gas/testsuite/gas/xtensa/loc.s: New file: loc test. + +Signed-off-by: Max Filippov +--- + gas/config/tc-xtensa.c | 6 +++--- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/loc.d | 10 ++++++++++ + gas/testsuite/gas/xtensa/loc.s | 7 +++++++ + 4 files changed, 21 insertions(+), 3 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/loc.d + create mode 100644 gas/testsuite/gas/xtensa/loc.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index a119871..36a06cc 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + default: + break; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 31b725b..7ff7bd7 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -101,6 +101,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "trampoline" + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" ++ run_dump_test "loc" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/loc.d b/gas/testsuite/gas/xtensa/loc.d +new file mode 100644 +index 0000000..71983cc +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/loc.d +@@ -0,0 +1,10 @@ ++#as: ++#objdump: -r ++#name: .loc directive relocs ++ ++.*: +file format .*xtensa.* ++ ++RELOCATION RECORDS FOR \[\.debug_line\]: ++#... ++.*R_XTENSA_DIFF16.*\.text\+0x00009c42 ++#... +diff --git a/gas/testsuite/gas/xtensa/loc.s b/gas/testsuite/gas/xtensa/loc.s +new file mode 100644 +index 0000000..029e14e +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/loc.s +@@ -0,0 +1,7 @@ ++ .text ++ .file 1 "loc.s" ++ .loc 1 3 ++ nop ++ .space 40000 ++ .loc 1 5 ++ nop +-- +2.1.4 + diff --git a/packages/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch b/packages/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..ead3e42 --- /dev/null +++ b/packages/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,149 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] xtensa: fix .init/.fini literals moving + +Despite the documentation and the comment in xtensa_move_literals, in +the presence of --text-section-literals and --auto-litpools literals are +moved from the separate literal sections into .init and .fini, because +the check in the xtensa_move_literals is incorrect. + +This moving was broken with introduction of auto litpools: some literals +now may be lost. This happens because literal frags emitted from .init +and .fini are not closed when new .literal_position marks new literal +pool. Then frag_align(2, 0, 0) changes type of the last literal frag to +rs_align. rs_align frags are skipped in the xtensa_move_literals. As a +result fixups against such literals are not moved out of .init.literal/ +.fini.literal sections producing the following assembler error: + + test.S: Warning: fixes not all moved from .init.literal + test.S: Internal error! + +Fix check for .init.literal/.fini.literal in the xtensa_move_literals +and don't let it move literals from there in the presence of +--text-section-literals or --auto-litpools. + +2016-02-17 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + * testsuite/gas/xtensa/all.exp: Add init-fini-literals to the + list of xtensa tests. + * testsuite/gas/xtensa/init-fini-literals.d: New file: + init-fini-literals test result patterns. + * testsuite/gas/xtensa/init-fini-literals.s: New file: + init-fini-literals test. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ + gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ + 4 files changed, 54 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 36a06cc..5773634 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; + struct litpool_seg *lps; ++ const char *init_name = INIT_SECTION_NAME; ++ const char *fini_name = FINI_SECTION_NAME; ++ int init_name_len = strlen(init_name); ++ int fini_name_len = strlen(fini_name); + + mark_literal_frags (literal_head->next); + +@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) + + for (segment = literal_head->next; segment; segment = segment->next) + { ++ const char *seg_name = segment_name (segment->seg); ++ + /* Keep the literals for .init and .fini in separate sections. */ +- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) +- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) ++ if ((!memcmp (seg_name, init_name, init_name_len) && ++ !strcmp (seg_name + init_name_len, ".literal")) || ++ (!memcmp (seg_name, fini_name, fini_name_len) && ++ !strcmp (seg_name + fini_name_len, ".literal"))) + continue; + + frchain_from = seg_info (segment->seg)->frchainP; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 7ff7bd7..6b67320 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" + run_dump_test "loc" ++ run_dump_test "init-fini-literals" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d +new file mode 100644 +index 0000000..19ed121 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.d +@@ -0,0 +1,24 @@ ++#as: --text-section-literals ++#objdump: -r ++#name: check that literals for .init and .fini always go to separate sections ++ ++.*: +file format .*xtensa.* ++#... ++RELOCATION RECORDS FOR \[\.init\.literal\]: ++#... ++00000000 R_XTENSA_PLT init ++#... ++RELOCATION RECORDS FOR \[\.fini\.literal\]: ++#... ++00000000 R_XTENSA_PLT fini ++#... ++RELOCATION RECORDS FOR \[\.init\]: ++#... ++.* R_XTENSA_SLOT0_OP \.init\.literal ++.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 ++#... ++RELOCATION RECORDS FOR \[\.fini\]: ++#... ++.* R_XTENSA_SLOT0_OP \.fini\.literal ++.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 ++#... +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s +new file mode 100644 +index 0000000..7c9ec17 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.s +@@ -0,0 +1,19 @@ ++ .section .init,"ax",@progbits ++ .literal_position ++ .literal .LC0, init@PLT ++ .literal_position ++ .literal .LC1, 1 ++ .align 4 ++ ++ l32r a2, .LC0 ++ l32r a2, .LC1 ++ ++ .section .fini,"ax",@progbits ++ .literal_position ++ .literal .LC2, fini@PLT ++ .literal_position ++ .literal .LC3, 1 ++ .align 4 ++ ++ l32r a2, .LC2 ++ l32r a2, .LC3 +-- +2.1.4 + diff --git a/packages/binutils/2.25.1/version.desc b/packages/binutils/2.25.1/version.desc new file mode 100644 index 0000000..026d275 --- /dev/null +++ b/packages/binutils/2.25.1/version.desc @@ -0,0 +1 @@ +obsolete="yes" diff --git a/packages/binutils/2.26/120-sh-conf.patch b/packages/binutils/2.26/120-sh-conf.patch new file mode 100644 index 0000000..c12a023 --- /dev/null +++ b/packages/binutils/2.26/120-sh-conf.patch @@ -0,0 +1,33 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +diff --git a/configure b/configure +index 87677bc..2d916f1 100755 +--- a/configure ++++ b/configure +@@ -3812,7 +3812,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +diff --git a/configure.ac b/configure.ac +index 8fe0eca..b10a99f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1140,7 +1140,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.26/300-001_ld_makefile_patch.patch b/packages/binutils/2.26/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..2a1320c --- /dev/null +++ b/packages/binutils/2.26/300-001_ld_makefile_patch.patch @@ -0,0 +1,26 @@ +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 9575f1f..84df0bf 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -54,7 +54,7 @@ endif + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 9f56ca1..272860f 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.26/300-012_check_ldrunpath_length.patch b/packages/binutils/2.26/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..f1f31af --- /dev/null +++ b/packages/binutils/2.26/300-012_check_ldrunpath_length.patch @@ -0,0 +1,22 @@ +diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em +index 137446f..bb8391a 100644 +--- a/ld/emultempl/elf32.em ++++ b/ld/emultempl/elf32.em +@@ -1195,6 +1195,8 @@ fragment <link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.26/310-fix-gold-pthreads-typo.patch b/packages/binutils/2.26/310-fix-gold-pthreads-typo.patch new file mode 100644 index 0000000..f2e6ff2 --- /dev/null +++ b/packages/binutils/2.26/310-fix-gold-pthreads-typo.patch @@ -0,0 +1,14 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 +@@ -102,9 +102,9 @@ + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); + #ifdef PTHREAD_MUTEX_ADAPTIVE_NP +- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); ++ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) +- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); ++ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); + #endif + + err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/packages/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/packages/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch new file mode 100644 index 0000000..f9a8af6 --- /dev/null +++ b/packages/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch @@ -0,0 +1,11 @@ +--- binutils-2.25.1/gold/gold-threads.cc.orig 2015-10-20 22:39:36.371169400 +0100 ++++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:39:38.182772700 +0100 +@@ -101,7 +101,7 @@ + int err = pthread_mutexattr_init(&attr); + if (err != 0) + gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); +-#ifdef PTHREAD_MUTEX_ADAPTIVE_NP ++#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) + err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) + gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/packages/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch b/packages/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch new file mode 100644 index 0000000..334ee3e --- /dev/null +++ b/packages/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch @@ -0,0 +1,108 @@ +diff --git a/binutils/configure b/binutils/configure +index 6e1f21e..78bf4ae 100755 +--- a/binutils/configure ++++ b/binutils/configure +@@ -12069,6 +12069,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12230,6 +12231,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg ca da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" + # If we haven't got the data from the intl directory, +diff --git a/binutils/configure.ac b/binutils/configure.ac +index defe781..8fd236a 100644 +--- a/binutils/configure.ac ++++ b/binutils/configure.ac +@@ -87,7 +87,10 @@ if test -z "$host" ; then + fi + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg ca da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/gas/configure b/gas/configure +index f959e95..9bb4043 100755 +--- a/gas/configure ++++ b/gas/configure +@@ -12819,6 +12819,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12980,6 +12981,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + # If we haven't got the data from the intl directory, +diff --git a/gas/configure.ac b/gas/configure.ac +index 07f825d..c552b7e 100644 +--- a/gas/configure.ac ++++ b/gas/configure.ac +@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) + AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/ld/configure b/ld/configure +index a446283..1a6bf81 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -16087,6 +16087,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -16248,6 +16249,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..45eec53 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -186,7 +186,10 @@ AM_PO_SUBDIRS + AC_EXEEXT + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + AM_MAINTAINER_MODE + AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/packages/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/packages/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch new file mode 100644 index 0000000..e4f235b --- /dev/null +++ b/packages/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch @@ -0,0 +1,13 @@ +diff --git a/gold/binary.cc b/gold/binary.cc +index 52df81a..03a8f20 100644 +--- a/gold/binary.cc ++++ b/gold/binary.cc +@@ -23,7 +23,7 @@ + #include "gold.h" + + #include +-#include ++#include + + #include "elfcpp.h" + #include "stringpool.h" diff --git a/packages/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/packages/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch new file mode 100644 index 0000000..6168b31 --- /dev/null +++ b/packages/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch @@ -0,0 +1,77 @@ +From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 +From: Andrew Hsieh +Date: Wed, 18 Mar 2015 10:57:24 +0800 +Subject: [PATCH] Fix darwin build + +1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 + doesn't support ended initializer list +2. wcsncasecmp doesn't exist in MacSDK10.6.x + +Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e +--- + binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ + binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c +index 13e39e4..7a98306 100644 +--- binutils-2.25.orig/bfd/peXXigen.c ++++ binutils-2.25/bfd/peXXigen.c +@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) + } + #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ + ++#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L ++/* wcsncasecmp isn't always defined in Mac SDK */ ++static int ++wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ ++ if (n == 0) ++ return (0); ++ for (; *s1; s1++, s2++) ++ { ++ c1 = towlower(*s1); ++ c2 = towlower(*s2); ++ if (c1 != c2) ++ return ((int)c1 - c2); ++ if (--n == 0) ++ return (0); ++ } ++ return (-*s2); ++} ++#endif ++ + /* Perform a comparison of two entries. */ + static signed int + rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) +diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc +index ff5a8ac..45140e0 100644 +--- binutils-2.25.orig/gold/gold-threads.cc ++++ binutils-2.25/gold/gold-threads.cc +@@ -284,9 +284,18 @@ Condvar::~Condvar() + class Once_initialize + { + public: +- Once_initialize() +- : once_(PTHREAD_ONCE_INIT) +- { } ++ Once_initialize() ++#if !defined(__APPLE__) ++ : once_(PTHREAD_ONCE_INIT) ++ { } ++#else ++// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support ++// extended initializer list as above */ ++ { ++ pthread_once_t once_2 = PTHREAD_ONCE_INIT; ++ once_ = once_2; ++ } ++#endif + + // Return a pointer to the pthread_once_t variable. + pthread_once_t* +-- +2.1.3 + diff --git a/packages/binutils/2.26/500-sysroot.patch b/packages/binutils/2.26/500-sysroot.patch new file mode 100644 index 0000000..e49c795 --- /dev/null +++ b/packages/binutils/2.26/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -308,18 +308,25 @@ + directory first. */ + if (! entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.26/600-poison-system-directories.patch b/packages/binutils/2.26/600-poison-system-directories.patch new file mode 100644 index 0000000..aa04082 --- /dev/null +++ b/packages/binutils/2.26/600-poison-system-directories.patch @@ -0,0 +1,285 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +[Gustavo: adapt to binutils 2.25] +Signed-off-by: Thomas Petazzoni +Signed-off-by: Gustavo Zacarias + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.ac (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +diff --git a/ld/config.in b/ld/config.in +index 276fb77..35c58eb 100644 +--- a/ld/config.in ++++ b/ld/config.in +@@ -14,6 +14,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +diff --git a/ld/configure b/ld/configure +index a446283..d1f9504 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -786,6 +786,7 @@ with_lib_path + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_compressed_debug_sections +@@ -1442,6 +1443,8 @@ Optional Features: + --disable-largefile omit support for large files + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -15491,7 +15494,18 @@ else + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..2cd8443 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +diff --git a/ld/ld.h b/ld/ld.h +index d84ec4e..3476b26 100644 +--- a/ld/ld.h ++++ b/ld/ld.h +@@ -164,6 +164,14 @@ typedef struct { + /* If set, display the target memory usage (per memory region). */ + bfd_boolean print_memory_usage; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +diff --git a/ld/ld.texinfo b/ld/ld.texinfo +index 1dd7492..fb1438e 100644 +--- a/ld/ld.texinfo ++++ b/ld/ld.texinfo +@@ -2332,6 +2332,18 @@ string identifying the original linked file does not change. + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +diff --git a/ld/ldfile.c b/ld/ldfile.c +index 96f9ecc..af231c0 100644 +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +diff --git a/ld/ldlex.h b/ld/ldlex.h +index 6f11e7b..0ca3110 100644 +--- a/ld/ldlex.h ++++ b/ld/ldlex.h +@@ -144,6 +144,8 @@ enum option_values + OPTION_PRINT_MEMORY_USAGE, + OPTION_REQUIRE_DEFINED_SYMBOL, + OPTION_ORPHAN_HANDLING, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ +diff --git a/ld/ldmain.c b/ld/ldmain.c +index bb0b9cc..a23c56c 100644 +--- a/ld/ldmain.c ++++ b/ld/ldmain.c +@@ -257,6 +257,8 @@ main (int argc, char **argv) + command_line.warn_mismatch = TRUE; + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +diff --git a/ld/lexsup.c b/ld/lexsup.c +index 4cad209..be7d584 100644 +--- a/ld/lexsup.c ++++ b/ld/lexsup.c +@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = + { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, + '\0', N_("=MODE"), N_("Control how orphan sections are handled."), + TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) + } + break; + ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; ++ + case OPTION_PUSH_STATE: + input_flags.pushed = xmemdup (&input_flags, + sizeof (input_flags), +@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) + command_line.soname = NULL; + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); diff --git a/packages/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch b/packages/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch new file mode 100644 index 0000000..cea92f3 --- /dev/null +++ b/packages/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch @@ -0,0 +1,42 @@ +From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 +From: Alexey Neyman +Date: Sat, 11 Mar 2017 17:27:09 -0800 +Subject: [PATCH] Fix library paths on PowerPC + +First, need to match against just the CPU name, not the whole triplet. +Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin +triplet. + +Second, it should be testing for $target, not $host. Host may be +little endian by default, and the sysroot directory layout shouldn't +depend on whether it is built on LE or BE machine. + +Signed-off-by: Alexey Neyman +--- + ld/emulparams/elf32ppccommon.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh +index 1f54ef8..d00cf68 100644 +--- a/ld/emulparams/elf32ppccommon.sh ++++ b/ld/emulparams/elf32ppccommon.sh +@@ -44,11 +44,11 @@ fi + + # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. + # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. +-case "$host":"$EMULATION_NAME" in +- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; +- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; +- *le-*:*64*) LIBPATH_SUFFIX=64be ;; +- *le-*:*32*) LIBPATH_SUFFIX=32be ;; ++case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in ++ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; ++ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; ++ *le:*64*) LIBPATH_SUFFIX=64be ;; ++ *le:*32*) LIBPATH_SUFFIX=32be ;; + *:*64lppc*) LIBPATH_SUFFIX=64le ;; + *:*32lppc*) LIBPATH_SUFFIX=32le ;; + *:*64*) LIBPATH_SUFFIX=64 ;; +-- +2.9.3 + diff --git a/packages/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch b/packages/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch new file mode 100644 index 0000000..66d4e60 --- /dev/null +++ b/packages/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch @@ -0,0 +1,98 @@ +From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 2 Feb 2016 17:11:38 +0300 +Subject: [PATCH] xtensa: fix signedness of gas relocations + +Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation +offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations +substituted for BFD_RELOC_*. This made it impossible to encode arbitrary +8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc +directive. Revert this part and add test. + +gas/ +2016-02-03 Max Filippov + * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* + substitutions for BFD_RELOC_* as unsigned. + * gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa + tests. + * gas/testsuite/gas/xtensa/loc.d: New file: loc test result + patterns. + * gas/testsuite/gas/xtensa/loc.s: New file: loc test. + +Signed-off-by: Max Filippov +--- + gas/config/tc-xtensa.c | 6 +++--- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/loc.d | 10 ++++++++++ + gas/testsuite/gas/xtensa/loc.s | 7 +++++++ + 4 files changed, 21 insertions(+), 3 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/loc.d + create mode 100644 gas/testsuite/gas/xtensa/loc.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index a119871..36a06cc 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) + { + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; +- fixP->fx_signed = 1; ++ fixP->fx_signed = 0; + break; + default: + break; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 31b725b..7ff7bd7 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -101,6 +101,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "trampoline" + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" ++ run_dump_test "loc" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/loc.d b/gas/testsuite/gas/xtensa/loc.d +new file mode 100644 +index 0000000..71983cc +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/loc.d +@@ -0,0 +1,10 @@ ++#as: ++#objdump: -r ++#name: .loc directive relocs ++ ++.*: +file format .*xtensa.* ++ ++RELOCATION RECORDS FOR \[\.debug_line\]: ++#... ++.*R_XTENSA_DIFF16.*\.text\+0x00009c42 ++#... +diff --git a/gas/testsuite/gas/xtensa/loc.s b/gas/testsuite/gas/xtensa/loc.s +new file mode 100644 +index 0000000..029e14e +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/loc.s +@@ -0,0 +1,7 @@ ++ .text ++ .file 1 "loc.s" ++ .loc 1 3 ++ nop ++ .space 40000 ++ .loc 1 5 ++ nop +-- +2.1.4 + diff --git a/packages/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch b/packages/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch new file mode 100644 index 0000000..ead3e42 --- /dev/null +++ b/packages/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch @@ -0,0 +1,149 @@ +From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 16 Feb 2016 02:23:28 +0300 +Subject: [PATCH] xtensa: fix .init/.fini literals moving + +Despite the documentation and the comment in xtensa_move_literals, in +the presence of --text-section-literals and --auto-litpools literals are +moved from the separate literal sections into .init and .fini, because +the check in the xtensa_move_literals is incorrect. + +This moving was broken with introduction of auto litpools: some literals +now may be lost. This happens because literal frags emitted from .init +and .fini are not closed when new .literal_position marks new literal +pool. Then frag_align(2, 0, 0) changes type of the last literal frag to +rs_align. rs_align frags are skipped in the xtensa_move_literals. As a +result fixups against such literals are not moved out of .init.literal/ +.fini.literal sections producing the following assembler error: + + test.S: Warning: fixes not all moved from .init.literal + test.S: Internal error! + +Fix check for .init.literal/.fini.literal in the xtensa_move_literals +and don't let it move literals from there in the presence of +--text-section-literals or --auto-litpools. + +2016-02-17 Max Filippov +gas/ + * config/tc-xtensa.c (xtensa_move_literals): Fix check for + .init.literal/.fini.literal section name. + * testsuite/gas/xtensa/all.exp: Add init-fini-literals to the + list of xtensa tests. + * testsuite/gas/xtensa/init-fini-literals.d: New file: + init-fini-literals test result patterns. + * testsuite/gas/xtensa/init-fini-literals.s: New file: + init-fini-literals test. + +Signed-off-by: Max Filippov +--- +Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 + + gas/config/tc-xtensa.c | 12 ++++++++++-- + gas/testsuite/gas/xtensa/all.exp | 1 + + gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ + gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ + 4 files changed, 54 insertions(+), 2 deletions(-) + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d + create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s + +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index 36a06cc..5773634 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; + struct litpool_seg *lps; ++ const char *init_name = INIT_SECTION_NAME; ++ const char *fini_name = FINI_SECTION_NAME; ++ int init_name_len = strlen(init_name); ++ int fini_name_len = strlen(fini_name); + + mark_literal_frags (literal_head->next); + +@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) + + for (segment = literal_head->next; segment; segment = segment->next) + { ++ const char *seg_name = segment_name (segment->seg); ++ + /* Keep the literals for .init and .fini in separate sections. */ +- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) +- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) ++ if ((!memcmp (seg_name, init_name, init_name_len) && ++ !strcmp (seg_name + init_name_len, ".literal")) || ++ (!memcmp (seg_name, fini_name, fini_name_len) && ++ !strcmp (seg_name + fini_name_len, ".literal"))) + continue; + + frchain_from = seg_info (segment->seg)->frchainP; +diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp +index 7ff7bd7..6b67320 100644 +--- a/gas/testsuite/gas/xtensa/all.exp ++++ b/gas/testsuite/gas/xtensa/all.exp +@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { + run_dump_test "first_frag_align" + run_dump_test "auto-litpools" + run_dump_test "loc" ++ run_dump_test "init-fini-literals" + } + + if [info exists errorInfo] then { +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d +new file mode 100644 +index 0000000..19ed121 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.d +@@ -0,0 +1,24 @@ ++#as: --text-section-literals ++#objdump: -r ++#name: check that literals for .init and .fini always go to separate sections ++ ++.*: +file format .*xtensa.* ++#... ++RELOCATION RECORDS FOR \[\.init\.literal\]: ++#... ++00000000 R_XTENSA_PLT init ++#... ++RELOCATION RECORDS FOR \[\.fini\.literal\]: ++#... ++00000000 R_XTENSA_PLT fini ++#... ++RELOCATION RECORDS FOR \[\.init\]: ++#... ++.* R_XTENSA_SLOT0_OP \.init\.literal ++.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 ++#... ++RELOCATION RECORDS FOR \[\.fini\]: ++#... ++.* R_XTENSA_SLOT0_OP \.fini\.literal ++.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 ++#... +diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s +new file mode 100644 +index 0000000..7c9ec17 +--- /dev/null ++++ b/gas/testsuite/gas/xtensa/init-fini-literals.s +@@ -0,0 +1,19 @@ ++ .section .init,"ax",@progbits ++ .literal_position ++ .literal .LC0, init@PLT ++ .literal_position ++ .literal .LC1, 1 ++ .align 4 ++ ++ l32r a2, .LC0 ++ l32r a2, .LC1 ++ ++ .section .fini,"ax",@progbits ++ .literal_position ++ .literal .LC2, fini@PLT ++ .literal_position ++ .literal .LC3, 1 ++ .align 4 ++ ++ l32r a2, .LC2 ++ l32r a2, .LC3 +-- +2.1.4 + diff --git a/packages/binutils/2.26/version.desc b/packages/binutils/2.26/version.desc new file mode 100644 index 0000000..e69de29 diff --git a/packages/binutils/2.27/100-missing-break.patch b/packages/binutils/2.27/100-missing-break.patch new file mode 100644 index 0000000..6f9d67c --- /dev/null +++ b/packages/binutils/2.27/100-missing-break.patch @@ -0,0 +1,30 @@ +From 8941017bc0226b60ce306d5271df15820ce66a53 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 30 Aug 2016 20:57:32 +0930 +Subject: [PATCH] ppc apuinfo for spe parsed incorrectly + +apuinfo saying SPE resulted in mach = bfd_mach_ppc_vle due to a +missing break. + + PR 20531 + * elf32-ppc.c (_bfd_elf_ppc_set_arch): Add missing "break". +--- + bfd/ChangeLog | 5 +++++ + bfd/elf32-ppc.c | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c +index 92299bc..1dd6d78 100644 +--- a/bfd/elf32-ppc.c ++++ b/bfd/elf32-ppc.c +@@ -2246,6 +2246,7 @@ _bfd_elf_ppc_set_arch (bfd *abfd) + case PPC_APUINFO_BRLOCK: + if (mach != bfd_mach_ppc_vle) + mach = bfd_mach_ppc_e500; ++ break; + + case PPC_APUINFO_VLE: + mach = bfd_mach_ppc_vle; +-- +2.9.3 + diff --git a/packages/binutils/2.27/120-sh-conf.patch b/packages/binutils/2.27/120-sh-conf.patch new file mode 100644 index 0000000..c12a023 --- /dev/null +++ b/packages/binutils/2.27/120-sh-conf.patch @@ -0,0 +1,33 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +diff --git a/configure b/configure +index 87677bc..2d916f1 100755 +--- a/configure ++++ b/configure +@@ -3812,7 +3812,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +diff --git a/configure.ac b/configure.ac +index 8fe0eca..b10a99f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1140,7 +1140,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.27/300-001_ld_makefile_patch.patch b/packages/binutils/2.27/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..2a1320c --- /dev/null +++ b/packages/binutils/2.27/300-001_ld_makefile_patch.patch @@ -0,0 +1,26 @@ +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 9575f1f..84df0bf 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -54,7 +54,7 @@ endif + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 9f56ca1..272860f 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.27/300-012_check_ldrunpath_length.patch b/packages/binutils/2.27/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..f1f31af --- /dev/null +++ b/packages/binutils/2.27/300-012_check_ldrunpath_length.patch @@ -0,0 +1,22 @@ +diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em +index 137446f..bb8391a 100644 +--- a/ld/emultempl/elf32.em ++++ b/ld/emultempl/elf32.em +@@ -1195,6 +1195,8 @@ fragment <link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/packages/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch new file mode 100644 index 0000000..2956385 --- /dev/null +++ b/packages/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch @@ -0,0 +1,11 @@ +--- binutils-2.27/gold/gold-threads.cc.orig 2016-12-26 16:44:23.691075600 +1100 ++++ binutils-2.27/gold/gold-threads.cc 2016-12-26 16:46:21.071855200 +1100 +@@ -101,7 +101,7 @@ + int err = pthread_mutexattr_init(&attr); + if (err != 0) + gold_fatal(_("pthead_mutexattr_init failed: %s"), strerror(err)); +-#ifdef PTHREAD_MUTEX_ADAPTIVE_NP ++#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) + err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) + gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/packages/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch b/packages/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch new file mode 100644 index 0000000..c52af05 --- /dev/null +++ b/packages/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch @@ -0,0 +1,108 @@ +diff --git a/binutils/configure b/binutils/configure +index 6e1f21e..78bf4ae 100755 +--- a/binutils/configure ++++ b/binutils/configure +@@ -12106,6 +12106,7 @@ + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12267,6 +12268,8 @@ + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" + # If we haven't got the data from the intl directory, +diff --git a/binutils/configure.ac b/binutils/configure.ac +index defe781..8fd236a 100644 +--- a/binutils/configure.ac ++++ b/binutils/configure.ac +@@ -87,7 +87,10 @@ + fi + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/gas/configure b/gas/configure +index f959e95..9bb4043 100755 +--- a/gas/configure ++++ b/gas/configure +@@ -12819,6 +12819,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12980,6 +12981,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + # If we haven't got the data from the intl directory, +diff --git a/gas/configure.ac b/gas/configure.ac +index 07f825d..c552b7e 100644 +--- a/gas/configure.ac ++++ b/gas/configure.ac +@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) + AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/ld/configure b/ld/configure +index a446283..1a6bf81 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -16087,6 +16087,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -16248,6 +16249,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..45eec53 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -186,7 +186,10 @@ AM_PO_SUBDIRS + AC_EXEEXT + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + AM_MAINTAINER_MODE + AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/packages/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/packages/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch new file mode 100644 index 0000000..e4f235b --- /dev/null +++ b/packages/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch @@ -0,0 +1,13 @@ +diff --git a/gold/binary.cc b/gold/binary.cc +index 52df81a..03a8f20 100644 +--- a/gold/binary.cc ++++ b/gold/binary.cc +@@ -23,7 +23,7 @@ + #include "gold.h" + + #include +-#include ++#include + + #include "elfcpp.h" + #include "stringpool.h" diff --git a/packages/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/packages/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch new file mode 100644 index 0000000..6168b31 --- /dev/null +++ b/packages/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch @@ -0,0 +1,77 @@ +From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 +From: Andrew Hsieh +Date: Wed, 18 Mar 2015 10:57:24 +0800 +Subject: [PATCH] Fix darwin build + +1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 + doesn't support ended initializer list +2. wcsncasecmp doesn't exist in MacSDK10.6.x + +Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e +--- + binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ + binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c +index 13e39e4..7a98306 100644 +--- binutils-2.25.orig/bfd/peXXigen.c ++++ binutils-2.25/bfd/peXXigen.c +@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) + } + #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ + ++#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L ++/* wcsncasecmp isn't always defined in Mac SDK */ ++static int ++wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ ++ if (n == 0) ++ return (0); ++ for (; *s1; s1++, s2++) ++ { ++ c1 = towlower(*s1); ++ c2 = towlower(*s2); ++ if (c1 != c2) ++ return ((int)c1 - c2); ++ if (--n == 0) ++ return (0); ++ } ++ return (-*s2); ++} ++#endif ++ + /* Perform a comparison of two entries. */ + static signed int + rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) +diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc +index ff5a8ac..45140e0 100644 +--- binutils-2.25.orig/gold/gold-threads.cc ++++ binutils-2.25/gold/gold-threads.cc +@@ -284,9 +284,18 @@ Condvar::~Condvar() + class Once_initialize + { + public: +- Once_initialize() +- : once_(PTHREAD_ONCE_INIT) +- { } ++ Once_initialize() ++#if !defined(__APPLE__) ++ : once_(PTHREAD_ONCE_INIT) ++ { } ++#else ++// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support ++// extended initializer list as above */ ++ { ++ pthread_once_t once_2 = PTHREAD_ONCE_INIT; ++ once_ = once_2; ++ } ++#endif + + // Return a pointer to the pthread_once_t variable. + pthread_once_t* +-- +2.1.3 + diff --git a/packages/binutils/2.27/500-sysroot.patch b/packages/binutils/2.27/500-sysroot.patch new file mode 100644 index 0000000..4cb9bc7 --- /dev/null +++ b/packages/binutils/2.27/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -336,18 +336,25 @@ + directory first. */ + if (!entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.27/600-poison-system-directories.patch b/packages/binutils/2.27/600-poison-system-directories.patch new file mode 100644 index 0000000..ff235e3 --- /dev/null +++ b/packages/binutils/2.27/600-poison-system-directories.patch @@ -0,0 +1,285 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +[Gustavo: adapt to binutils 2.25] +Signed-off-by: Thomas Petazzoni +Signed-off-by: Gustavo Zacarias + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.ac (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +diff --git a/ld/config.in b/ld/config.in +index 276fb77..35c58eb 100644 +--- a/ld/config.in ++++ b/ld/config.in +@@ -17,6 +17,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +diff --git a/ld/configure b/ld/configure +index a446283..d1f9504 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -788,6 +788,7 @@ with_lib_path + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_compressed_debug_sections +@@ -1445,6 +1446,8 @@ Optional Features: + --disable-largefile omit support for large files + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -15498,7 +15501,18 @@ else + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..2cd8443 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +diff --git a/ld/ld.h b/ld/ld.h +index d84ec4e..3476b26 100644 +--- a/ld/ld.h ++++ b/ld/ld.h +@@ -169,6 +169,14 @@ typedef struct { + /* If set, display the target memory usage (per memory region). */ + bfd_boolean print_memory_usage; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +diff --git a/ld/ld.texinfo b/ld/ld.texinfo +index 1dd7492..fb1438e 100644 +--- a/ld/ld.texinfo ++++ b/ld/ld.texinfo +@@ -2357,6 +2357,18 @@ string identifying the original linked file does not change. + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +diff --git a/ld/ldfile.c b/ld/ldfile.c +index 96f9ecc..af231c0 100644 +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +diff --git a/ld/ldlex.h b/ld/ldlex.h +index 6f11e7b..0ca3110 100644 +--- a/ld/ldlex.h ++++ b/ld/ldlex.h +@@ -144,6 +144,8 @@ enum option_values + OPTION_PRINT_MEMORY_USAGE, + OPTION_REQUIRE_DEFINED_SYMBOL, + OPTION_ORPHAN_HANDLING, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ +diff --git a/ld/ldmain.c b/ld/ldmain.c +index bb0b9cc..a23c56c 100644 +--- a/ld/ldmain.c ++++ b/ld/ldmain.c +@@ -257,6 +257,8 @@ main (int argc, char **argv) + command_line.warn_mismatch = TRUE; + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +diff --git a/ld/lexsup.c b/ld/lexsup.c +index 4cad209..be7d584 100644 +--- a/ld/lexsup.c ++++ b/ld/lexsup.c +@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = + { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, + '\0', N_("=MODE"), N_("Control how orphan sections are handled."), + TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) + } + break; + ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; ++ + case OPTION_PUSH_STATE: + input_flags.pushed = xmemdup (&input_flags, + sizeof (input_flags), +@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) + command_line.soname = NULL; + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); diff --git a/packages/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch b/packages/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch new file mode 100644 index 0000000..cea92f3 --- /dev/null +++ b/packages/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch @@ -0,0 +1,42 @@ +From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 +From: Alexey Neyman +Date: Sat, 11 Mar 2017 17:27:09 -0800 +Subject: [PATCH] Fix library paths on PowerPC + +First, need to match against just the CPU name, not the whole triplet. +Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin +triplet. + +Second, it should be testing for $target, not $host. Host may be +little endian by default, and the sysroot directory layout shouldn't +depend on whether it is built on LE or BE machine. + +Signed-off-by: Alexey Neyman +--- + ld/emulparams/elf32ppccommon.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh +index 1f54ef8..d00cf68 100644 +--- a/ld/emulparams/elf32ppccommon.sh ++++ b/ld/emulparams/elf32ppccommon.sh +@@ -44,11 +44,11 @@ fi + + # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. + # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. +-case "$host":"$EMULATION_NAME" in +- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; +- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; +- *le-*:*64*) LIBPATH_SUFFIX=64be ;; +- *le-*:*32*) LIBPATH_SUFFIX=32be ;; ++case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in ++ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; ++ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; ++ *le:*64*) LIBPATH_SUFFIX=64be ;; ++ *le:*32*) LIBPATH_SUFFIX=32be ;; + *:*64lppc*) LIBPATH_SUFFIX=64le ;; + *:*32lppc*) LIBPATH_SUFFIX=32le ;; + *:*64*) LIBPATH_SUFFIX=64 ;; +-- +2.9.3 + diff --git a/packages/binutils/2.27/999-xtensa-reverse-shift-count.patch b/packages/binutils/2.27/999-xtensa-reverse-shift-count.patch new file mode 100644 index 0000000..f8bb9c1 --- /dev/null +++ b/packages/binutils/2.27/999-xtensa-reverse-shift-count.patch @@ -0,0 +1,33 @@ +From 78fb7e37eb8bb08ae537d6c487996ff17c810332 Mon Sep 17 00:00:00 2001 +From: Trevor Saunders +Date: Mon, 26 Sep 2016 12:42:11 -0400 +Subject: [PATCH] tc-xtensa.c: fixup xg_reverse_shift_count typo + +gas/ChangeLog: + +2016-09-26 Trevor Saunders + + * config/tc-xtensa.c (xg_reverse_shift_count): Pass cnt_arg instead of + cnt_argp to concat. +--- + gas/ChangeLog | 5 +++++ + gas/config/tc-xtensa.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +[[ ChangeLog skipped, fails to apply on 2.27 ]] +diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c +index d062044..ca261ae 100644 +--- a/gas/config/tc-xtensa.c ++++ b/gas/config/tc-xtensa.c +@@ -2228,7 +2228,7 @@ xg_reverse_shift_count (char **cnt_argp) + cnt_arg = *cnt_argp; + + /* replace the argument with "31-(argument)" */ +- new_arg = concat ("31-(", cnt_argp, ")", (char *) NULL); ++ new_arg = concat ("31-(", cnt_arg, ")", (char *) NULL); + + free (cnt_arg); + *cnt_argp = new_arg; +-- +2.9.3 + diff --git a/packages/binutils/2.27/version.desc b/packages/binutils/2.27/version.desc new file mode 100644 index 0000000..e69de29 diff --git a/packages/binutils/2.28/120-sh-conf.patch b/packages/binutils/2.28/120-sh-conf.patch new file mode 100644 index 0000000..c12a023 --- /dev/null +++ b/packages/binutils/2.28/120-sh-conf.patch @@ -0,0 +1,33 @@ +r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines + +Likewise, binutils has no idea about any of these new targets either, so we +fix that up too.. now we're able to actually build a real toolchain for +sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more +inept targets than that one, really. Go look, I promise). + +diff --git a/configure b/configure +index 87677bc..2d916f1 100755 +--- a/configure ++++ b/configure +@@ -3812,7 +3812,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; +diff --git a/configure.ac b/configure.ac +index 8fe0eca..b10a99f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1140,7 +1140,7 @@ case "${target}" in + or1k*-*-*) + noconfigdirs="$noconfigdirs gdb" + ;; +- sh-*-* | sh64-*-*) ++ sh*-*-* | sh64-*-*) + case "${target}" in + sh*-*-elf) + ;; diff --git a/packages/binutils/2.28/300-001_ld_makefile_patch.patch b/packages/binutils/2.28/300-001_ld_makefile_patch.patch new file mode 100644 index 0000000..2a1320c --- /dev/null +++ b/packages/binutils/2.28/300-001_ld_makefile_patch.patch @@ -0,0 +1,26 @@ +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 9575f1f..84df0bf 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -54,7 +54,7 @@ endif + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 9f56ca1..272860f 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/packages/binutils/2.28/300-012_check_ldrunpath_length.patch b/packages/binutils/2.28/300-012_check_ldrunpath_length.patch new file mode 100644 index 0000000..f1f31af --- /dev/null +++ b/packages/binutils/2.28/300-012_check_ldrunpath_length.patch @@ -0,0 +1,22 @@ +diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em +index 137446f..bb8391a 100644 +--- a/ld/emultempl/elf32.em ++++ b/ld/emultempl/elf32.em +@@ -1195,6 +1195,8 @@ fragment <link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/packages/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/packages/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch new file mode 100644 index 0000000..2956385 --- /dev/null +++ b/packages/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch @@ -0,0 +1,11 @@ +--- binutils-2.27/gold/gold-threads.cc.orig 2016-12-26 16:44:23.691075600 +1100 ++++ binutils-2.27/gold/gold-threads.cc 2016-12-26 16:46:21.071855200 +1100 +@@ -101,7 +101,7 @@ + int err = pthread_mutexattr_init(&attr); + if (err != 0) + gold_fatal(_("pthead_mutexattr_init failed: %s"), strerror(err)); +-#ifdef PTHREAD_MUTEX_ADAPTIVE_NP ++#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) + err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + if (err != 0) + gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/packages/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch b/packages/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch new file mode 100644 index 0000000..c52af05 --- /dev/null +++ b/packages/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch @@ -0,0 +1,108 @@ +diff --git a/binutils/configure b/binutils/configure +index 6e1f21e..78bf4ae 100755 +--- a/binutils/configure ++++ b/binutils/configure +@@ -12106,6 +12106,7 @@ + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12267,6 +12268,8 @@ + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" + # If we haven't got the data from the intl directory, +diff --git a/binutils/configure.ac b/binutils/configure.ac +index defe781..8fd236a 100644 +--- a/binutils/configure.ac ++++ b/binutils/configure.ac +@@ -87,7 +87,10 @@ + fi + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/gas/configure b/gas/configure +index f959e95..9bb4043 100755 +--- a/gas/configure ++++ b/gas/configure +@@ -12819,6 +12819,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -12980,6 +12981,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + # If we haven't got the data from the intl directory, +diff --git a/gas/configure.ac b/gas/configure.ac +index 07f825d..c552b7e 100644 +--- a/gas/configure.ac ++++ b/gas/configure.ac +@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) + AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" + ZW_GNU_GETTEXT_SISTER_DIR +diff --git a/ld/configure b/ld/configure +index a446283..1a6bf81 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -16087,6 +16087,7 @@ fi + done + test -n "$YACC" || YACC="yacc" + ++save_LIBS=$LIBS + for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. +@@ -16248,6 +16249,8 @@ esac + if test "$LEX" = :; then + LEX=${am_missing_run}flex + fi ++LIBS=$save_LIBS ++LEXLIB= + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..45eec53 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -186,7 +186,10 @@ AM_PO_SUBDIRS + AC_EXEEXT + + AC_PROG_YACC ++save_LIBS=$LIBS + AM_PROG_LEX ++LIBS=$save_LIBS ++LEXLIB= + + AM_MAINTAINER_MODE + AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/packages/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/packages/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch new file mode 100644 index 0000000..e4f235b --- /dev/null +++ b/packages/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch @@ -0,0 +1,13 @@ +diff --git a/gold/binary.cc b/gold/binary.cc +index 52df81a..03a8f20 100644 +--- a/gold/binary.cc ++++ b/gold/binary.cc +@@ -23,7 +23,7 @@ + #include "gold.h" + + #include +-#include ++#include + + #include "elfcpp.h" + #include "stringpool.h" diff --git a/packages/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/packages/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch new file mode 100644 index 0000000..6168b31 --- /dev/null +++ b/packages/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch @@ -0,0 +1,77 @@ +From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 +From: Andrew Hsieh +Date: Wed, 18 Mar 2015 10:57:24 +0800 +Subject: [PATCH] Fix darwin build + +1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 + doesn't support ended initializer list +2. wcsncasecmp doesn't exist in MacSDK10.6.x + +Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e +--- + binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ + binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c +index 13e39e4..7a98306 100644 +--- binutils-2.25.orig/bfd/peXXigen.c ++++ binutils-2.25/bfd/peXXigen.c +@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) + } + #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ + ++#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L ++/* wcsncasecmp isn't always defined in Mac SDK */ ++static int ++wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ ++ if (n == 0) ++ return (0); ++ for (; *s1; s1++, s2++) ++ { ++ c1 = towlower(*s1); ++ c2 = towlower(*s2); ++ if (c1 != c2) ++ return ((int)c1 - c2); ++ if (--n == 0) ++ return (0); ++ } ++ return (-*s2); ++} ++#endif ++ + /* Perform a comparison of two entries. */ + static signed int + rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) +diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc +index ff5a8ac..45140e0 100644 +--- binutils-2.25.orig/gold/gold-threads.cc ++++ binutils-2.25/gold/gold-threads.cc +@@ -284,9 +284,18 @@ Condvar::~Condvar() + class Once_initialize + { + public: +- Once_initialize() +- : once_(PTHREAD_ONCE_INIT) +- { } ++ Once_initialize() ++#if !defined(__APPLE__) ++ : once_(PTHREAD_ONCE_INIT) ++ { } ++#else ++// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support ++// extended initializer list as above */ ++ { ++ pthread_once_t once_2 = PTHREAD_ONCE_INIT; ++ once_ = once_2; ++ } ++#endif + + // Return a pointer to the pthread_once_t variable. + pthread_once_t* +-- +2.1.3 + diff --git a/packages/binutils/2.28/500-sysroot.patch b/packages/binutils/2.28/500-sysroot.patch new file mode 100644 index 0000000..4cb9bc7 --- /dev/null +++ b/packages/binutils/2.28/500-sysroot.patch @@ -0,0 +1,37 @@ +Signed-off-by: Sven Rebhan + +Always try to prepend the sysroot prefix to absolute filenames first. + +http://bugs.gentoo.org/275666 +http://sourceware.org/bugzilla/show_bug.cgi?id=10340 + +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -336,18 +336,25 @@ + directory first. */ + if (!entry->flags.maybe_archive) + { +- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ /* For absolute pathnames, try to always open the file in the ++ sysroot first. If this fails, try to open the file at the ++ given location. */ ++ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); ++ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) ++ && ld_sysroot) + { + char *name = concat (ld_sysroot, entry->filename, + (const char *) NULL); + if (ldfile_try_open_bfd (name, entry)) + { + entry->filename = name; ++ entry->flags.sysrooted = TRUE; + return TRUE; + } + free (name); + } +- else if (ldfile_try_open_bfd (entry->filename, entry)) ++ ++ if (ldfile_try_open_bfd (entry->filename, entry)) + return TRUE; + + if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/packages/binutils/2.28/600-poison-system-directories.patch b/packages/binutils/2.28/600-poison-system-directories.patch new file mode 100644 index 0000000..ff235e3 --- /dev/null +++ b/packages/binutils/2.28/600-poison-system-directories.patch @@ -0,0 +1,285 @@ +Patch adapted to binutils 2.23.2 and extended to use +BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. + +[Gustavo: adapt to binutils 2.25] +Signed-off-by: Thomas Petazzoni +Signed-off-by: Gustavo Zacarias + +Upstream-Status: Inappropriate [distribution: codesourcery] + +Patch originally created by Mark Hatle, forward-ported to +binutils 2.21 by Scott Garman. + +purpose: warn for uses of system directories when cross linking + +Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 + +2008-07-02 Joseph Myers + + ld/ + * ld.h (args_type): Add error_poison_system_directories. + * ld.texinfo (--error-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.error_poison_system_directories. + * ldmain.c (main): Initialize + command_line.error_poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --error-poison-system-directories. + (parse_args): Handle new option. + +2007-06-13 Joseph Myers + + ld/ + * config.in: Regenerate. + * ld.h (args_type): Add poison_system_directories. + * ld.texinfo (--no-poison-system-directories): Document. + * ldfile.c (ldfile_add_library_path): Check + command_line.poison_system_directories. + * ldmain.c (main): Initialize + command_line.poison_system_directories. + * lexsup.c (enum option_values): Add + OPTION_NO_POISON_SYSTEM_DIRECTORIES. + (ld_options): Add --no-poison-system-directories. + (parse_args): Handle new option. + +2007-04-20 Joseph Myers + + Merge from Sourcery G++ binutils 2.17: + + 2007-03-20 Joseph Myers + Based on patch by Mark Hatle . + ld/ + * configure.ac (--enable-poison-system-directories): New option. + * configure, config.in: Regenerate. + * ldfile.c (ldfile_add_library_path): If + ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, + /usr/lib, /usr/local/lib or /usr/X11R6/lib. + +Signed-off-by: Mark Hatle +Signed-off-by: Scott Garman + +diff --git a/ld/config.in b/ld/config.in +index 276fb77..35c58eb 100644 +--- a/ld/config.in ++++ b/ld/config.in +@@ -17,6 +17,9 @@ + language is requested. */ + #undef ENABLE_NLS + ++/* Define to warn for use of native system library directories */ ++#undef ENABLE_POISON_SYSTEM_DIRECTORIES ++ + /* Additional extension a shared object might have. */ + #undef EXTRA_SHLIB_EXTENSION + +diff --git a/ld/configure b/ld/configure +index a446283..d1f9504 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -788,6 +788,7 @@ with_lib_path + enable_targets + enable_64_bit_bfd + with_sysroot ++enable_poison_system_directories + enable_gold + enable_got + enable_compressed_debug_sections +@@ -1445,6 +1446,8 @@ Optional Features: + --disable-largefile omit support for large files + --enable-targets alternative target configurations + --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) ++ --enable-poison-system-directories ++ warn for use of native system library directories + --enable-gold[=ARG] build gold [ARG={default,yes,no}] + --enable-got= GOT handling scheme (target, single, negative, + multigot) +@@ -15498,7 +15501,18 @@ else + fi + + ++# Check whether --enable-poison-system-directories was given. ++if test "${enable_poison_system_directories+set}" = set; then : ++ enableval=$enable_poison_system_directories; ++else ++ enable_poison_system_directories=no ++fi ++ ++if test "x${enable_poison_system_directories}" = "xyes"; then + ++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h ++ ++fi + + # Check whether --enable-got was given. + if test "${enable_got+set}" = set; then : +diff --git a/ld/configure.ac b/ld/configure.ac +index 188172d..2cd8443 100644 +--- a/ld/configure.ac ++++ b/ld/configure.ac +@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) + AC_SUBST(TARGET_SYSTEM_ROOT) + AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) + ++AC_ARG_ENABLE([poison-system-directories], ++ AS_HELP_STRING([--enable-poison-system-directories], ++ [warn for use of native system library directories]),, ++ [enable_poison_system_directories=no]) ++if test "x${enable_poison_system_directories}" = "xyes"; then ++ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], ++ [1], ++ [Define to warn for use of native system library directories]) ++fi ++ + dnl Use --enable-gold to decide if this linker should be the default. + dnl "install_as_default" is set to false if gold is the default linker. + dnl "installed_linker" is the installed BFD linker name. +diff --git a/ld/ld.h b/ld/ld.h +index d84ec4e..3476b26 100644 +--- a/ld/ld.h ++++ b/ld/ld.h +@@ -169,6 +169,14 @@ typedef struct { + /* If set, display the target memory usage (per memory region). */ + bfd_boolean print_memory_usage; + ++ /* If TRUE (the default) warn for uses of system directories when ++ cross linking. */ ++ bfd_boolean poison_system_directories; ++ ++ /* If TRUE (default FALSE) give an error for uses of system ++ directories when cross linking instead of a warning. */ ++ bfd_boolean error_poison_system_directories; ++ + /* Big or little endian as set on command line. */ + enum endian_enum endian; + +diff --git a/ld/ld.texinfo b/ld/ld.texinfo +index 1dd7492..fb1438e 100644 +--- a/ld/ld.texinfo ++++ b/ld/ld.texinfo +@@ -2357,6 +2357,18 @@ string identifying the original linked file does not change. + + Passing @code{none} for @var{style} disables the setting from any + @code{--build-id} options earlier on the command line. ++ ++@kindex --no-poison-system-directories ++@item --no-poison-system-directories ++Do not warn for @option{-L} options using system directories such as ++@file{/usr/lib} when cross linking. This option is intended for use ++in chroot environments when such directories contain the correct ++libraries for the target system rather than the host. ++ ++@kindex --error-poison-system-directories ++@item --error-poison-system-directories ++Give an error instead of a warning for @option{-L} options using ++system directories when cross linking. + @end table + + @c man end +diff --git a/ld/ldfile.c b/ld/ldfile.c +index 96f9ecc..af231c0 100644 +--- a/ld/ldfile.c ++++ b/ld/ldfile.c +@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) + new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); + else + new_dirs->name = xstrdup (name); ++ ++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES ++ if (command_line.poison_system_directories ++ && ((!strncmp (name, "/lib", 4)) ++ || (!strncmp (name, "/usr/lib", 8)) ++ || (!strncmp (name, "/usr/local/lib", 14)) ++ || (!strncmp (name, "/usr/X11R6/lib", 14)))) ++ { ++ if (command_line.error_poison_system_directories) ++ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ else ++ einfo (_("%P: warning: library search path \"%s\" is unsafe for " ++ "cross-compilation\n"), name); ++ } ++#endif ++ + } + + /* Try to open a BFD for a lang_input_statement. */ +diff --git a/ld/ldlex.h b/ld/ldlex.h +index 6f11e7b..0ca3110 100644 +--- a/ld/ldlex.h ++++ b/ld/ldlex.h +@@ -144,6 +144,8 @@ enum option_values + OPTION_PRINT_MEMORY_USAGE, + OPTION_REQUIRE_DEFINED_SYMBOL, + OPTION_ORPHAN_HANDLING, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, + }; + + /* The initial parser states. */ +diff --git a/ld/ldmain.c b/ld/ldmain.c +index bb0b9cc..a23c56c 100644 +--- a/ld/ldmain.c ++++ b/ld/ldmain.c +@@ -257,6 +257,8 @@ main (int argc, char **argv) + command_line.warn_mismatch = TRUE; + command_line.warn_search_mismatch = TRUE; + command_line.check_section_addresses = -1; ++ command_line.poison_system_directories = TRUE; ++ command_line.error_poison_system_directories = FALSE; + + /* We initialize DEMANGLING based on the environment variable + COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the +diff --git a/ld/lexsup.c b/ld/lexsup.c +index 4cad209..be7d584 100644 +--- a/ld/lexsup.c ++++ b/ld/lexsup.c +@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = + { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, + '\0', N_("=MODE"), N_("Control how orphan sections are handled."), + TWO_DASHES }, ++ { {"no-poison-system-directories", no_argument, NULL, ++ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Do not warn for -L options using system directories"), ++ TWO_DASHES }, ++ { {"error-poison-system-directories", no_argument, NULL, ++ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, ++ '\0', NULL, N_("Give an error for -L options using system directories"), ++ TWO_DASHES }, + }; + + #define OPTION_COUNT ARRAY_SIZE (ld_options) +@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) + int ingroup = 0; + char *default_dirlist = NULL; + char *shortopts; ++ char *BR_paranoid_env; + struct option *longopts; + struct option *really_longopts; + int last_optind; +@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) + } + break; + ++ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: ++ command_line.poison_system_directories = FALSE; ++ break; ++ ++ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: ++ command_line.error_poison_system_directories = TRUE; ++ break; ++ + case OPTION_PUSH_STATE: + input_flags.pushed = xmemdup (&input_flags, + sizeof (input_flags), +@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) + command_line.soname = NULL; + } + ++ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); ++ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) ++ command_line.error_poison_system_directories = TRUE; ++ + while (ingroup) + { + lang_leave_group (); diff --git a/packages/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch b/packages/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch new file mode 100644 index 0000000..cea92f3 --- /dev/null +++ b/packages/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch @@ -0,0 +1,42 @@ +From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 +From: Alexey Neyman +Date: Sat, 11 Mar 2017 17:27:09 -0800 +Subject: [PATCH] Fix library paths on PowerPC + +First, need to match against just the CPU name, not the whole triplet. +Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin +triplet. + +Second, it should be testing for $target, not $host. Host may be +little endian by default, and the sysroot directory layout shouldn't +depend on whether it is built on LE or BE machine. + +Signed-off-by: Alexey Neyman +--- + ld/emulparams/elf32ppccommon.sh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh +index 1f54ef8..d00cf68 100644 +--- a/ld/emulparams/elf32ppccommon.sh ++++ b/ld/emulparams/elf32ppccommon.sh +@@ -44,11 +44,11 @@ fi + + # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. + # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. +-case "$host":"$EMULATION_NAME" in +- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; +- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; +- *le-*:*64*) LIBPATH_SUFFIX=64be ;; +- *le-*:*32*) LIBPATH_SUFFIX=32be ;; ++case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in ++ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; ++ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; ++ *le:*64*) LIBPATH_SUFFIX=64be ;; ++ *le:*32*) LIBPATH_SUFFIX=32be ;; + *:*64lppc*) LIBPATH_SUFFIX=64le ;; + *:*32lppc*) LIBPATH_SUFFIX=32le ;; + *:*64*) LIBPATH_SUFFIX=64 ;; +-- +2.9.3 + diff --git a/packages/binutils/2.28/version.desc b/packages/binutils/2.28/version.desc new file mode 100644 index 0000000..e69de29 diff --git a/packages/binutils/package.desc b/packages/binutils/package.desc new file mode 100644 index 0000000..926d124 --- /dev/null +++ b/packages/binutils/package.desc @@ -0,0 +1,4 @@ +vcs="git" +repository="git://sourceware.org/git/binutils-gdb.git" +download="https://ftp.gnu.org/gnu/binutils/" +origin="GNU" diff --git a/patches/binutils/2.23.2/120-sh-conf.patch b/patches/binutils/2.23.2/120-sh-conf.patch deleted file mode 100644 index ea3d1b6..0000000 --- a/patches/binutils/2.23.2/120-sh-conf.patch +++ /dev/null @@ -1,29 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - ---- a/configure -+++ b/configure -@@ -1495,7 +1495,7 @@ - mips*-*-*) - noconfigdirs="$noconfigdirs gprof" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; ---- a/configure.ac -+++ b/configure.ac -@@ -712,7 +712,7 @@ - mips*-*-*) - noconfigdirs="$noconfigdirs gprof" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.23.2/300-001_ld_makefile_patch.patch b/patches/binutils/2.23.2/300-001_ld_makefile_patch.patch deleted file mode 100644 index 5cb0f61..0000000 --- a/patches/binutils/2.23.2/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.am binutils-2.17.50.0.17/ld/Makefile.am ---- binutils-2.17.50.0.17.oorig/ld/Makefile.am 2007-06-18 19:29:29.000000000 +0200 -+++ binutils-2.17.50.0.17/ld/Makefile.am 2007-06-25 10:00:36.000000000 +0200 -@@ -18,7 +18,7 @@ - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff -u binutils-2.17.50.0.17.oorig/ld/Makefile.in binutils-2.17.50.0.17/ld/Makefile.in ---- binutils-2.17.50.0.17.oorig/ld/Makefile.in 2007-06-18 19:29:29.000000000 +0200 -+++ binutils-2.17.50.0.17/ld/Makefile.in 2007-06-25 10:00:36.000000000 +0200 -@@ -287,7 +287,7 @@ - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.23.2/300-012_check_ldrunpath_length.patch b/patches/binutils/2.23.2/300-012_check_ldrunpath_length.patch deleted file mode 100644 index df78310..0000000 --- a/patches/binutils/2.23.2/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -Nura binutils-2.21.orig/ld/emultempl/elf32.em binutils-2.21/ld/emultempl/elf32.em ---- binutils-2.21.orig/ld/emultempl/elf32.em 2010-10-29 09:10:36.000000000 -0300 -+++ binutils-2.21/ld/emultempl/elf32.em 2010-12-10 09:26:56.746102724 -0300 -@@ -1270,6 +1270,8 @@ - && command_line.rpath == NULL) - { - lib_path = (const char *) getenv ("LD_RUN_PATH"); -+ if ((lib_path) && (strlen (lib_path) == 0)) -+ lib_path = NULL; - if (gld${EMULATION_NAME}_search_needed (lib_path, &n, - force)) - break; -@@ -1497,6 +1499,8 @@ - rpath = command_line.rpath; - if (rpath == NULL) - rpath = (const char *) getenv ("LD_RUN_PATH"); -+ if ((rpath) && (strlen (rpath) == 0)) -+ rpath = NULL; - - for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.23.2/310-fix-gold-pthreads-typo.patch b/patches/binutils/2.23.2/310-fix-gold-pthreads-typo.patch deleted file mode 100644 index f2e6ff2..0000000 --- a/patches/binutils/2.23.2/310-fix-gold-pthreads-typo.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 -@@ -102,9 +102,9 @@ - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); - #ifdef PTHREAD_MUTEX_ADAPTIVE_NP -- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); -+ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) -- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); -+ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); - #endif - - err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/patches/binutils/2.23.2/500-sysroot.patch b/patches/binutils/2.23.2/500-sysroot.patch deleted file mode 100644 index e49c795..0000000 --- a/patches/binutils/2.23.2/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -308,18 +308,25 @@ - directory first. */ - if (! entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.23.2/600-poison-system-directories.patch b/patches/binutils/2.23.2/600-poison-system-directories.patch deleted file mode 100644 index 780e48e..0000000 --- a/patches/binutils/2.23.2/600-poison-system-directories.patch +++ /dev/null @@ -1,279 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -Signed-off-by: Thomas Petazzoni - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.in (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -Index: b/ld/config.in -=================================================================== ---- a/ld/config.in -+++ b/ld/config.in -@@ -11,6 +11,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -Index: b/ld/configure -=================================================================== ---- a/ld/configure -+++ b/ld/configure -@@ -773,6 +773,7 @@ - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_werror -@@ -1428,6 +1429,8 @@ - (and sometimes confusing) to the casual installer - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -4338,7 +4341,18 @@ - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -Index: b/ld/configure.in -=================================================================== ---- a/ld/configure.in -+++ b/ld/configure.in -@@ -70,6 +70,16 @@ - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -Index: b/ld/ldfile.c -=================================================================== ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -116,6 +116,23 @@ - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -Index: b/ld/ld.h -=================================================================== ---- a/ld/ld.h -+++ b/ld/ld.h -@@ -203,6 +203,14 @@ - /* If TRUE we'll just print the default output on stdout. */ - bfd_boolean print_output_format; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -Index: b/ld/ldmain.c -=================================================================== ---- a/ld/ldmain.c -+++ b/ld/ldmain.c -@@ -265,6 +265,8 @@ - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; - command_line.disable_target_specific_optimizations = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -Index: b/ld/ld.texinfo -=================================================================== ---- a/ld/ld.texinfo -+++ b/ld/ld.texinfo -@@ -2154,6 +2154,18 @@ - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -Index: b/ld/lexsup.c -=================================================================== ---- a/ld/lexsup.c -+++ b/ld/lexsup.c -@@ -498,6 +498,14 @@ - TWO_DASHES }, - { {"wrap", required_argument, NULL, OPTION_WRAP}, - '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -510,6 +518,7 @@ - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1427,9 +1436,21 @@ - einfo (_("%P%X: --hash-size needs a numeric argument\n")); - } - break; -+ -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; - } - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); -Index: b/ld/ldlex.h -=================================================================== ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -136,6 +136,8 @@ - #endif /* ENABLE_PLUGINS */ - OPTION_DEFAULT_SCRIPT, - OPTION_PRINT_OUTPUT_FORMAT, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ diff --git a/patches/binutils/2.23.2/900-xtensa-trampolines.patch b/patches/binutils/2.23.2/900-xtensa-trampolines.patch deleted file mode 100644 index b5b934f..0000000 --- a/patches/binutils/2.23.2/900-xtensa-trampolines.patch +++ /dev/null @@ -1,846 +0,0 @@ -From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001 -From: David Weatherford -Date: Fri, 21 Mar 2014 11:53:42 +0000 -Subject: [PATCH] Add support to the Xtensa target for creating trampolines for - out-of-range branches. - - * tc-xtensa.c (xtensa_check_frag_count, xtensa_create_trampoline_frag) - (xtensa_maybe_create_trampoline_frag, init_trampoline_frag) - (find_trampoline_seg, search_trampolines, get_best_trampoline) - (check_and_update_trampolines, add_jump_to_trampoline) - (dump_trampolines): New function. - (md_parse_option): Add cases for --[no-]trampolines options. - (md_assemble, finish_vinsn, xtensa_end): Add call to - xtensa_check_frag_count. - (xg_assemble_vliw_tokens): Add call to - xtensa_maybe_create_trampoline_frag. - (xtensa_relax_frag): Relax fragments with RELAX_TRAMPOLINE state. - (relax_frag_immed): Relax jump instructions that cannot reach its - target. - * tc-xtensa.h (xtensa_relax_statesE::RELAX_TRAMPOLINE): New relax - state. - - * as.texinfo: Document --[no-]trampolines command-line options. - * c-xtensa.texi: Document trampolines relaxation and command line - options. - - * frags.c (get_frag_count, clear_frag_count): New function. - (frag_alloc): Increment totalfrags counter. - * frags.h (get_frag_count, clear_frag_count): New function. - - * all.exp: Add test for trampoline relaxation. - * trampoline.d: Trampoline relaxation expected dump. - * trampoline.s: Trampoline relaxation test source. ---- -Backported from: a82c7d9030b67a6a76a5403d0e1641f9e42141ac -Changes to Changelog files are dropped. - - gas/config/tc-xtensa.c | 558 +++++++++++++++++++++++++++++++++- - gas/config/tc-xtensa.h | 5 + - gas/frags.c | 15 + - gas/frags.h | 3 + - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/trampoline.d | 26 ++ - gas/testsuite/gas/xtensa/trampoline.s | 21 ++ - 11 files changed, 753 insertions(+), 2 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/trampoline.d - create mode 100644 gas/testsuite/gas/xtensa/trampoline.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index fe8ec0f..ea23c96 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -468,6 +468,12 @@ static void xtensa_set_frag_assembly_state (fragS *); - static void finish_vinsn (vliw_insn *); - static bfd_boolean emit_single_op (TInsn *); - static int total_frag_text_expansion (fragS *); -+static bfd_boolean use_trampolines = TRUE; -+static void xtensa_check_frag_count (void); -+static void xtensa_create_trampoline_frag (bfd_boolean); -+static void xtensa_maybe_create_trampoline_frag (void); -+struct trampoline_frag; -+static int init_trampoline_frag (struct trampoline_frag *); - - /* Alignment Functions. */ - -@@ -520,6 +526,7 @@ static void tinsn_from_chars (TInsn *, char *, int); - static void tinsn_immed_from_frag (TInsn *, fragS *, int); - static int get_num_stack_text_bytes (IStack *); - static int get_num_stack_literal_bytes (IStack *); -+static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf); - - /* vliw_insn functions. */ - -@@ -687,7 +694,10 @@ enum - option_prefer_l32r, - option_prefer_const16, - -- option_target_hardware -+ option_target_hardware, -+ -+ option_trampolines, -+ option_no_trampolines, - }; - - const char *md_shortopts = ""; -@@ -760,6 +770,9 @@ struct option md_longopts[] = - - { "target-hardware", required_argument, NULL, option_target_hardware }, - -+ { "trampolines", no_argument, NULL, option_trampolines }, -+ { "no-trampolines", no_argument, NULL, option_no_trampolines }, -+ - { NULL, no_argument, NULL, 0 } - }; - -@@ -940,6 +953,14 @@ md_parse_option (int c, char *arg) - directive_state[directive_transform] = FALSE; - return 1; - -+ case option_trampolines: -+ use_trampolines = TRUE; -+ return 1; -+ -+ case option_no_trampolines: -+ use_trampolines = FALSE; -+ return 1; -+ - default: - return 0; - } -@@ -963,7 +984,9 @@ Xtensa options:\n\ - flix bundles\n\ - --no-allow-flix neither allow hand-written nor generate\n\ - flix bundles\n\ -- --rename-section old=new Rename section 'old' to 'new'\n", stream); -+ --rename-section old=new Rename section 'old' to 'new'\n\ -+ --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ -+ when jumps do not reach their targets\n", stream); - } - - -@@ -5568,6 +5591,8 @@ md_assemble (char *str) - - /* We've just emitted a new instruction so clear the list of labels. */ - xtensa_clear_insn_labels (); -+ -+ xtensa_check_frag_count (); - } - - -@@ -6372,6 +6397,8 @@ finish_vinsn (vliw_insn *vinsn) - xg_assemble_vliw_tokens (vinsn); - - xg_clear_vinsn (vinsn); -+ -+ xtensa_check_frag_count (); - } - - -@@ -7140,6 +7167,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - RELAX_UNREACHABLE, - frag_now->fr_symbol, frag_now->fr_offset, NULL); - xtensa_set_frag_assembly_state (frag_now); -+ xtensa_maybe_create_trampoline_frag (); - } - else if (is_branch && do_align_targets ()) - { -@@ -7222,9 +7250,164 @@ xtensa_end (void) - xtensa_sanity_check (); - - xtensa_add_config_info (); -+ -+ xtensa_check_frag_count (); -+} -+ -+ -+struct trampoline_frag -+{ -+ struct trampoline_frag *next; -+ bfd_boolean needs_jump_around; -+ fragS *fragP; -+ fixS *fixP; -+}; -+ -+struct trampoline_seg -+{ -+ struct trampoline_seg *next; -+ asection *seg; -+ struct trampoline_frag trampoline_list; -+}; -+ -+static struct trampoline_seg trampoline_seg_list; -+#define J_RANGE (128 * 1024) -+ -+static int unreachable_count = 0; -+ -+ -+static void -+xtensa_maybe_create_trampoline_frag (void) -+{ -+ if (!use_trampolines) -+ return; -+ -+ /* We create an area for possible trampolines every 10 unreachable frags. -+ These are preferred over the ones not preceded by an unreachable frag, -+ because we don't have to jump around them. This function is called after -+ each RELAX_UNREACHABLE frag is created. */ -+ -+ if (++unreachable_count > 10) -+ { -+ xtensa_create_trampoline_frag (FALSE); -+ clear_frag_count (); -+ unreachable_count = 0; -+ } -+} -+ -+static void -+xtensa_check_frag_count (void) -+{ -+ if (!use_trampolines || frag_now->tc_frag_data.is_no_transform) -+ return; -+ -+ /* We create an area for possible trampolines every 8000 frags or so. This -+ is an estimate based on the max range of a "j" insn (+/-128K) divided -+ by a typical frag byte count (16), minus a few for safety. This function -+ is called after each source line is processed. */ -+ -+ if (get_frag_count () > 8000) -+ { -+ xtensa_create_trampoline_frag (TRUE); -+ clear_frag_count (); -+ unreachable_count = 0; -+ } -+} -+ -+static xtensa_insnbuf trampoline_buf = NULL; -+static xtensa_insnbuf trampoline_slotbuf = NULL; -+ -+#define TRAMPOLINE_FRAG_SIZE 3000 -+ -+static void -+xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) -+{ -+ /* Emit a frag where we can place intermediate jump instructions, -+ in case we need to jump farther than 128K bytes. -+ Each jump instruction takes three bytes. -+ We allocate enough for 1000 trampolines in each frag. -+ If that's not enough, oh well. */ -+ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ struct trampoline_frag *tf; -+ char *varP; -+ fragS *fragP; -+ int size = TRAMPOLINE_FRAG_SIZE; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ if (ts->seg == now_seg) -+ break; -+ } -+ -+ if (ts == NULL) -+ { -+ ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1); -+ ts->next = trampoline_seg_list.next; -+ trampoline_seg_list.next = ts; -+ ts->seg = now_seg; -+ } -+ -+ frag_wane (frag_now); -+ frag_new (0); -+ xtensa_set_frag_assembly_state (frag_now); -+ varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL); -+ fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG); -+ if (trampoline_buf == NULL) -+ { -+ trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa); -+ trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa); -+ } -+ tf = (struct trampoline_frag *)xmalloc(sizeof (struct trampoline_frag)); -+ tf->next = ts->trampoline_list.next; -+ ts->trampoline_list.next = tf; -+ tf->needs_jump_around = needs_jump_around; -+ tf->fragP = fragP; -+ tf->fixP = NULL; -+} -+ -+ -+static struct trampoline_seg * -+find_trampoline_seg (asection *seg) -+{ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ if (ts->seg == seg) -+ return ts; -+ } -+ -+ return NULL; - } - - -+void dump_trampolines (void); -+ -+void -+dump_trampolines (void) -+{ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ asection *seg = ts->seg; -+ -+ if (seg == NULL) -+ continue; -+ fprintf(stderr, "SECTION %s\n", seg->name); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ for ( ; tf; tf = tf->next) -+ { -+ if (tf->fragP == NULL) -+ continue; -+ fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n", -+ (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix, -+ tf->needs_jump_around ? "T" : "F"); -+ } -+ } -+} -+ - static void - xtensa_cleanup_align_frags (void) - { -@@ -8708,6 +8891,149 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - new_stretch += relax_frag_for_align (fragP, stretch); - break; - -+ case RELAX_TRAMPOLINE: -+ if (fragP->tc_frag_data.relax_seen) -+ { -+ segment_info_type *seginfo = seg_info (now_seg); -+ fragS *fP; /* The out-of-range jump. */ -+ fixS *fixP; -+ -+ /* Scan for jumps that will not reach. */ -+ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ { -+ symbolS *s = fixP->fx_addsy; -+ xtensa_opcode opcode; -+ int target; -+ int addr; -+ int delta; -+ -+ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -+ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -+ continue; -+ xtensa_insnbuf_from_chars (isa, trampoline_buf, -+ (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, -+ 0); -+ fmt = xtensa_format_decode (isa, trampoline_buf); -+ gas_assert (fmt != XTENSA_UNDEFINED); -+ slot = fixP->tc_fix_data.slot; -+ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -+ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -+ if (opcode != xtensa_j_opcode) -+ continue; -+ target = S_GET_VALUE (s); -+ addr = fixP->fx_frag->fr_address; -+ delta = target - addr + stretch; -+ if (delta > J_RANGE || delta < -1 * J_RANGE) -+ { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ struct trampoline_frag *prev = &ts->trampoline_list; -+ int lower = (target < addr) ? target : addr; -+ int upper = (target > addr) ? target : addr; -+ int midpoint = lower + (upper - lower) / 2; -+ -+ if ((upper - lower) > 2 * J_RANGE) -+ { -+ /* One trampoline won't suffice; we need multiple jumps. -+ Jump to the trampoline that's farthest, but still in -+ range relative to the original "j" instruction. */ -+ for ( ; tf; prev = tf, tf = tf->next ) -+ { -+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ; -+ -+ if (addr == lower) -+ { -+ /* Forward jump. */ -+ if (this_addr - addr < J_RANGE) -+ break; -+ } -+ else -+ { -+ /* Backward jump. */ -+ if (next_addr == 0 || addr - next_addr > J_RANGE) -+ break; -+ } -+ } -+ } -+ else -+ { -+ struct trampoline_frag *best_tf = NULL; -+ int best_delta = 0; -+ -+ for ( ; tf; prev = tf, tf = tf->next ) -+ { -+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ int this_delta = abs (this_addr - midpoint); -+ -+ if (!best_tf || this_delta < best_delta) -+ { -+ best_tf = tf; -+ best_delta = this_delta; -+ } -+ } -+ tf = best_tf; -+ } -+ if (tf->fragP == fragP) -+ { -+ int trampaddr = fragP->fr_address + fragP->fr_fix; -+ -+ if (abs (addr - trampaddr) < J_RANGE) -+ { /* The trampoline is in range of original; fix it! */ -+ fixS *newfixP; -+ int offset; -+ TInsn insn; -+ symbolS *lsym; -+ -+ new_stretch += init_trampoline_frag (tf); -+ offset = fragP->fr_fix; /* Where to assemble the j insn. */ -+ lsym = fragP->fr_symbol; -+ fP = fixP->fx_frag; -+ /* Assemble a jump to the target label here. */ -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], lsym, offset); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3); -+ fragP->fr_fix += 3; -+ fragP->fr_var -= 3; -+ /* Add a fix-up for the original j insn. */ -+ newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type); -+ newfixP->fx_no_overflow = 1; -+ newfixP->tc_fix_data.X_add_symbol = lsym; -+ newfixP->tc_fix_data.X_add_number = offset; -+ newfixP->tc_fix_data.slot = slot; -+ /* Move the fix-up from the original j insn to this one. */ -+ fixP->fx_frag = fragP; -+ fixP->fx_where = fragP->fr_fix - 3; -+ fixP->tc_fix_data.slot = 0; -+ /* Adjust the jump around this trampoline (if present). */ -+ if (tf->fixP != NULL) -+ { -+ tf->fixP->fx_offset += 3; -+ } -+ new_stretch += 3; -+ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ -+ /* Do we have room for more? */ -+ if (fragP->fr_var < 3) -+ { /* No, convert to fill. */ -+ frag_wane (fragP); -+ fragP->fr_subtype = 0; -+ /* Remove from the trampoline_list. */ -+ prev->next = tf->next; -+ break; -+ } -+ } -+ } -+ } -+ } -+ } -+ break; -+ - default: - as_bad (_("bad relaxation state")); - } -@@ -9146,6 +9472,200 @@ bytes_to_stretch (fragS *this_frag, - } - - -+static struct trampoline_frag * -+search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) -+{ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL; -+ struct trampoline_frag *best_tf = NULL; -+ int best_delta = 0; -+ int best_addr = 0; -+ symbolS *sym = tinsn->tok[0].X_add_symbol; -+ offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; -+ offsetT addr = fragP->fr_address; -+ offsetT lower = (addr < target) ? addr : target; -+ offsetT upper = (addr > target) ? addr : target; -+ int delta = upper - lower; -+ offsetT midpoint = lower + delta / 2; -+ int this_delta = -1; -+ int this_addr = -1; -+ -+ if (delta > 2 * J_RANGE) -+ { -+ /* One trampoline won't do; we need multiple. -+ Choose the farthest trampoline that's still in range of the original -+ and let a later pass finish the job. */ -+ for ( ; tf; tf = tf->next) -+ { -+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0; -+ -+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ if (lower == addr) -+ { -+ /* Forward jump. */ -+ if (this_addr - addr < J_RANGE) -+ break; -+ } -+ else -+ { -+ /* Backward jump. */ -+ if (next_addr == 0 || addr - next_addr > J_RANGE) -+ break; -+ } -+ if (abs (addr - this_addr) < J_RANGE) -+ return tf; -+ -+ return NULL; -+ } -+ } -+ for ( ; tf; tf = tf->next) -+ { -+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ this_delta = abs (this_addr - midpoint); -+ if (unreachable_only && tf->needs_jump_around) -+ continue; -+ if (!best_tf || this_delta < best_delta) -+ { -+ best_tf = tf; -+ best_delta = this_delta; -+ best_addr = this_addr; -+ } -+ } -+ -+ if (best_tf && -+ best_delta < J_RANGE && -+ abs(best_addr - lower) < J_RANGE && -+ abs(best_addr - upper) < J_RANGE) -+ return best_tf; -+ -+ return NULL; /* No suitable trampoline found. */ -+} -+ -+ -+static struct trampoline_frag * -+get_best_trampoline (TInsn *tinsn, fragS *fragP) -+{ -+ struct trampoline_frag *tf = NULL; -+ -+ tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ -+ -+ if (tf == NULL) -+ tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */ -+ -+ return tf; -+} -+ -+ -+static void -+check_and_update_trampolines (void) -+{ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ struct trampoline_frag *prev = &ts->trampoline_list; -+ -+ for ( ; tf; prev = tf, tf = tf->next) -+ { -+ if (tf->fragP->fr_var < 3) -+ { -+ frag_wane (tf->fragP); -+ prev->next = tf->next; -+ tf->fragP = NULL; -+ } -+ } -+} -+ -+ -+static int -+init_trampoline_frag (struct trampoline_frag *trampP) -+{ -+ fragS *fp = trampP->fragP; -+ int growth = 0; -+ -+ if (fp->fr_fix == 0) -+ { -+ symbolS *lsym; -+ char label[10 + 2 * sizeof(fp)]; -+ sprintf (label, ".L0_TR_%p", fp); -+ -+ lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); -+ fp->fr_symbol = lsym; -+ if (trampP->needs_jump_around) -+ { -+ /* Add a jump around this block of jumps, in case -+ control flows into this block. */ -+ fixS *fixP; -+ TInsn insn; -+ xtensa_format fmt; -+ xtensa_isa isa = xtensa_default_isa; -+ -+ fp->tc_frag_data.is_insn = 1; -+ /* Assemble a jump insn. */ -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], lsym, 3); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3); -+ fp->fr_fix += 3; -+ fp->fr_var -= 3; -+ growth = 3; -+ fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); -+ trampP->fixP = fixP; -+ } -+ } -+ return growth; -+} -+ -+ -+static int -+add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) -+{ -+ fragS *tramp = trampP->fragP; -+ fixS *fixP; -+ int offset = tramp->fr_fix; /* Where to assemble the j insn. */ -+ TInsn insn; -+ symbolS *lsym; -+ symbolS *tsym; -+ int toffset; -+ xtensa_format fmt; -+ xtensa_isa isa = xtensa_default_isa; -+ int growth = 0; -+ -+ lsym = tramp->fr_symbol; -+ /* Assemble a jump to the target label in the trampoline frag. */ -+ tsym = origfrag->tc_frag_data.slot_symbols[0]; -+ toffset = origfrag-> tc_frag_data.slot_offsets[0]; -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], tsym, toffset); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3); -+ tramp->fr_fix += 3; -+ tramp->fr_var -= 3; -+ growth = 3; -+ /* add a fix-up for the trampoline jump. */ -+ fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); -+ /* Modify the jump at the start of this trampoline to point past the newly-added jump. */ -+ fixP = trampP->fixP; -+ if (fixP) -+ fixP->fx_offset += 3; -+ /* Modify the original j to point here. */ -+ origfrag->tc_frag_data.slot_symbols[0] = lsym; -+ origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3; -+ /* If trampoline is full, remove it from the list. */ -+ check_and_update_trampolines (); -+ -+ return growth; -+} -+ -+ - static long - relax_frag_immed (segT segP, - fragS *fragP, -@@ -9284,6 +9804,37 @@ relax_frag_immed (segT segP, - if (negatable_branch && istack.ninsn > 1) - update_next_frag_state (fragP); - -+ /* If last insn is a jump, and it cannot reach its target, try to find a trampoline. */ -+ if (istack.ninsn > 2 && -+ istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL && -+ istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN && -+ istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode) -+ { -+ TInsn *jinsn = &istack.insn[istack.ninsn - 2]; -+ -+ if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) -+ { -+ struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP); -+ -+ if (tf) -+ { -+ this_text_diff += init_trampoline_frag (tf); -+ this_text_diff += add_jump_to_trampoline (tf, fragP); -+ } -+ else -+ { -+ /* If target symbol is undefined, assume it will reach once linked. */ -+ expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0]; -+ -+ if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol)) -+ { -+ as_bad_where (fragP->fr_file, fragP->fr_line, -+ _("jump target out of range; no usable trampoline found")); -+ } -+ } -+ } -+ } -+ - return this_text_diff; - } - -@@ -9404,6 +9955,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp) - else - as_bad (_("invalid relaxation fragment result")); - break; -+ -+ case RELAX_TRAMPOLINE: -+ break; - } - - fragp->fr_var = 0; -diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h -index 0bf1240..4672bc6 100644 ---- a/gas/config/tc-xtensa.h -+++ b/gas/config/tc-xtensa.h -@@ -180,6 +180,11 @@ enum xtensa_relax_statesE - prevent the linker from changing the size of any frag between the - section start and the org frag. */ - -+ RELAX_TRAMPOLINE, -+ /* Every few thousand frags, we insert one of these, just in case we may -+ need some space for a trampoline (jump to a jump) because the function -+ has gotten too big. If not needed, it disappears. */ -+ - RELAX_NONE - }; - -diff --git a/gas/frags.c b/gas/frags.c -index 5f68480..e14099d 100644 ---- a/gas/frags.c -+++ b/gas/frags.c -@@ -24,6 +24,20 @@ - - extern fragS zero_address_frag; - extern fragS predefined_address_frag; -+ -+static int totalfrags; -+ -+int -+get_frag_count (void) -+{ -+ return totalfrags; -+} -+ -+void -+clear_frag_count (void) -+{ -+ totalfrags = 0; -+} - - /* Initialization for frag routines. */ - -@@ -70,6 +84,7 @@ frag_alloc (struct obstack *ob) - ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG); - obstack_alignment_mask (ob) = oalign; - memset (ptr, 0, SIZEOF_STRUCT_FRAG); -+ totalfrags++; - return ptr; - } - -diff --git a/gas/frags.h b/gas/frags.h -index 319898f..2f9e1b5 100644 ---- a/gas/frags.h -+++ b/gas/frags.h -@@ -155,4 +155,7 @@ char *frag_var (relax_stateT type, - - bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); - -+int get_frag_count (void); -+void clear_frag_count (void); -+ - #endif /* FRAGS_H */ -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 2b2c294..3683b78 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -98,6 +98,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "pcrel" - run_dump_test "weak-call" - run_dump_test "jlong" -+ run_dump_test "trampoline" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d -new file mode 100644 -index 0000000..b4f65dc ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/trampoline.d -@@ -0,0 +1,26 @@ -+#as: -+#objdump: -d -+#name: trampolines relaxation -+ -+.*: +file format .*xtensa.* -+#... -+.*0:.*j.0x1194c -+.*3:.*j.0x1194f -+.*6:.*j.0x11952 -+.*9:.*j.0x1d4e4 -+#... -+.*11949:.*j.0x11955 -+.*1194c:.*j.0x24a0e -+.*1194f:.*j.0x24a0e -+.*11952:.*j.0x24a11 -+#... -+.*1d4e1:.*j.0x1d4e7 -+.*1d4e4:.*j.0x33462 -+#... -+.*24a0e:.*j.0x24a0e -+.*24a11:.*j.0x24a11 -+#... -+.*3345f:.*ret -+.*33462:.*j.0x49407 -+#... -+.*49407:.*j.0x49407 -diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s -new file mode 100644 -index 0000000..259a3bb ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/trampoline.s -@@ -0,0 +1,21 @@ -+ .text -+ j 1f -+ j 1f -+ j 2f -+ j 3f -+ .rep 25000 -+99: -+ and a2, a2, a3 -+ bne a2, a3, 99b -+ .endr -+1: -+ j 1b -+2: -+ j 2b -+ -+ .rep 25000 -+ and a2, a2, a3 -+ _ret -+ .endr -+3: -+ j 3b --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch b/patches/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch deleted file mode 100644 index e1c2d85..0000000 --- a/patches/binutils/2.23.2/901-xtensa-gas-first-frag-alignment.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 15 Apr 2014 19:12:46 +0400 -Subject: [PATCH] Fix alignment for the first section frag on xtensa - -Linking object files produced by partial linking with link-time -relaxation enabled sometimes fails with the following error message: - -dangerous relocation: call8: misaligned call target: (.text.unlikely+0x63) - -This happens because no basic block with an XTENSA_PROP_ALIGN flag in the -property table is generated for the first basic block, even if the -.align directive is present. -It was believed that the first frag alignment could be derived from the -section alignment, but this was not implemented for the partial linking -case: after partial linking first frag of a section may become not -first, but no additional alignment frag is inserted before it. -Basic block for such frag may be merged with previous basic block into -extended basic block during relaxation pass losing its alignment -restrictions. - -Fix this by always recording alignment for the first section frag. - -2014-04-22 Max Filippov - -gas/ - * config/tc-xtensa.c (xtensa_handle_align): record alignment for the - first section frag. - ---- -Backported from: a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 -Changes to Changelog files and tests are dropped. - - gas/config/tc-xtensa.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index ea23c96..58ace38 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5609,7 +5609,6 @@ xtensa_handle_align (fragS *fragP) - && ! fragP->tc_frag_data.is_literal - && (fragP->fr_type == rs_align - || fragP->fr_type == rs_align_code) -- && fragP->fr_address + fragP->fr_fix > 0 - && fragP->fr_offset > 0 - && now_seg != bss_section) - { --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch b/patches/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch deleted file mode 100644 index ba24f4e..0000000 --- a/patches/binutils/2.23.2/902-xtensa-gas-ld-diff-relocation-signed.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001 -From: Volodymyr Arbatov -Date: Mon, 6 May 2013 09:43:21 -0800 -Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets. - -R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such. -Add testcase that examines ld behaviour on R_XTENSA_DIFF relocation -changing sign during relaxation. - -2014-05-02 Volodymyr Arbatov - David Weatherford - Max Filippov - -bfd/ - * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as - signed. - -gas/ - * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF* - fixups as signed. ---- -Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6 -Changes to Changelog files and tests are dropped. - - bfd/elf32-xtensa.c | 32 ++++++++++++----------- - gas/config/tc-xtensa.c | 3 +++ - 2 files changed, 20 insertions(+), 15 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index edb04b4..8818d67 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] = - FALSE, 0, 0, FALSE), - - /* Relocations for supporting difference of symbols. */ -- HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE), -- HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE), -- HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE), - - /* General immediate operand relocations. */ -@@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - || r_type == R_XTENSA_DIFF16 - || r_type == R_XTENSA_DIFF32) - { -- bfd_vma diff_value = 0, new_end_offset, diff_mask = 0; -+ bfd_signed_vma diff_value = 0; -+ bfd_vma new_end_offset, diff_mask = 0; - - if (bfd_get_section_limit (abfd, sec) < old_source_offset) - { -@@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - { - case R_XTENSA_DIFF8: - diff_value = -- bfd_get_8 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_8 (abfd, &contents[old_source_offset]); - break; - case R_XTENSA_DIFF16: - diff_value = -- bfd_get_16 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_16 (abfd, &contents[old_source_offset]); - break; - case R_XTENSA_DIFF32: - diff_value = -- bfd_get_32 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_32 (abfd, &contents[old_source_offset]); - break; - } - -@@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - switch (r_type) - { - case R_XTENSA_DIFF8: -- diff_mask = 0xff; -- bfd_put_8 (abfd, diff_value, -+ diff_mask = 0x7f; -+ bfd_put_signed_8 (abfd, diff_value, - &contents[old_source_offset]); - break; - case R_XTENSA_DIFF16: -- diff_mask = 0xffff; -- bfd_put_16 (abfd, diff_value, -+ diff_mask = 0x7fff; -+ bfd_put_signed_16 (abfd, diff_value, - &contents[old_source_offset]); - break; - case R_XTENSA_DIFF32: -- diff_mask = 0xffffffff; -- bfd_put_32 (abfd, diff_value, -+ diff_mask = 0x7fffffff; -+ bfd_put_signed_32 (abfd, diff_value, - &contents[old_source_offset]); - break; - } - -- /* Check for overflow. */ -- if ((diff_value & ~diff_mask) != 0) -+ /* Check for overflow. Sign bits must be all zeroes or all ones */ -+ if ((diff_value & ~diff_mask) != 0 && -+ (diff_value & ~diff_mask) != (-1 & ~diff_mask)) - { - (*link_info->callbacks->reloc_dangerous) - (link_info, _("overflow after relaxation"), -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 58ace38..7547c0a0 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -+ fixP->fx_signed = 1; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -+ fixP->fx_signed = 1; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -+ fixP->fx_signed = 1; - break; - default: - break; --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch b/patches/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch deleted file mode 100644 index 6a0846e..0000000 --- a/patches/binutils/2.23.2/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Thu, 10 Jul 2014 01:47:33 +0400 -Subject: [PATCH] Fix xtensa ld segfault when linking linux modules - -is_inconsistent_linkonce_section makes an assumption that section name -that starts with ".gnu.linkonce.prop." has one more dot in its suffix. -However gas generates such section name by insertion of "prop." right -after ".gnu.linkonce." part of the name of the original section. So, for -section named ".gnu.linkonce.this_module" corresponding property section -name does not satisfy the assumption. Such section names are common in -linux modules. This bug was exposed by the patch "a35d5e8 Fix alignment -for the first section frag on xtensa", that makes gas produce property -section for each section that has ".align" directive in it. - -Use suffix that immediately follows ".gnu.linkonce.prop." when there are -no more dots following it. - -2014-07-10 Max Filippov - -ld/ - * emultempl/xtensaelf.em (is_inconsistent_linkonce_section): - correctly handle missing dot in section name after - ".gnu.linkonce.prop.". ---- -Backported from: e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 -Changes to ld/ChangeLog file are dropped. - - ld/emultempl/xtensaelf.em | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em -index 151eea4..948d18d 100644 ---- a/ld/emultempl/xtensaelf.em -+++ b/ld/emultempl/xtensaelf.em -@@ -1310,7 +1310,7 @@ is_inconsistent_linkonce_section (asection *sec) - for Tensilica's XCC compiler. */ - name = sec_name + linkonce_len; - if (CONST_STRNEQ (name, "prop.")) -- name = strchr (name + 5, '.') + 1; -+ name = strchr (name + 5, '.') ? strchr (name + 5, '.') + 1 : name + 5; - else if (name[1] == '.' - && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h')) - name += 2; --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/patches/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch deleted file mode 100644 index dba7620..0000000 --- a/patches/binutils/2.23.2/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 -From: Sterling Augustine -Date: Tue, 25 Jan 2011 13:59:13 -0800 -Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation - bug - -During link-time relaxation distance between cross-section call site and -its target may grow, producing 'call target out of range' error for -relaxed calls. Be more conservative when calculating whether or not a -callx can be converted to a straight call. - -2014-09-23 Sterling Augustine - -bfd/ - * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section - call relaxation use furthermost addresses where call source and - destination can be to check whether it's in the range of a direct - call. - -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- - 1 file changed, 37 insertions(+), 4 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 09862e3..e32496a 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, - || is_reloc_sym_weak (abfd, irel))) - return FALSE; - -- self_address = (sec->output_section->vma -- + sec->output_offset + irel->r_offset + 3); -- dest_address = (target_sec->output_section->vma -- + target_sec->output_offset + target_offset); -+ if (target_sec->output_section != sec->output_section) -+ { -+ /* If the two sections are sufficiently far away that relaxation -+ might take the call out of range, we can't simplify. For -+ example, a positive displacement call into another memory -+ could get moved to a lower address due to literal removal, -+ but the destination won't move, and so the displacment might -+ get larger. -+ -+ If the displacement is negative, assume the destination could -+ move as far back as the start of the output section. The -+ self_address will be at least as far into the output section -+ as it is prior to relaxation. -+ -+ If the displacement is postive, assume the destination will be in -+ it's pre-relaxed location (because relaxation only makes sections -+ smaller). The self_address could go all the way to the beginning -+ of the output section. */ -+ -+ dest_address = target_sec->output_section->vma; -+ self_address = sec->output_section->vma; -+ -+ if (sec->output_section->vma > target_sec->output_section->vma) -+ self_address += sec->output_offset + irel->r_offset + 3; -+ else -+ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); -+ /* Call targets should be four-byte aligned. */ -+ dest_address = (dest_address + 3) & ~3; -+ } -+ else -+ { -+ -+ self_address = (sec->output_section->vma -+ + sec->output_offset + irel->r_offset + 3); -+ dest_address = (target_sec->output_section->vma -+ + target_sec->output_offset + target_offset); -+ } - - *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, - self_address, dest_address); --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch b/patches/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch deleted file mode 100644 index 8aeb064..0000000 --- a/patches/binutils/2.23.2/905-Fix-trampolines-search-code-for-conditional-branches.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 25 Nov 2014 21:33:21 +0300 -Subject: [PATCH] Fix trampolines search code for conditional branches - -For conditional branches that need more than one trampoline to reach its -target assembler couldn't always find suitable trampoline because -post-loop condition check was placed inside the loop, resulting in -premature loop termination. Move check outside the loop. - -This fixes the following build errors seen when assembling huge files -produced by gcc: - Error: jump target out of range; no usable trampoline found - Error: operand 1 of 'j' has out of range value '307307' - -2014-11-25 Max Filippov - -gas/ - * config/tc-xtensa.c (search_trampolines): Move post-loop - condition check outside the search loop. - -gas/testsuite/ - * gas/xtensa/trampoline.d: Add expected output for branches. - * gas/xtensa/trampoline.s: Add test case for branches. - -Signed-off-by: Max Filippov ---- -Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 -Changes to ChangeLogs are dropped. - - gas/config/tc-xtensa.c | 8 ++++---- - gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ - gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ - 3 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index d11b0c7..f23ccf8 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) - if (next_addr == 0 || addr - next_addr > J_RANGE) - break; - } -- if (abs (addr - this_addr) < J_RANGE) -- return tf; -- -- return NULL; - } -+ if (abs (addr - this_addr) < J_RANGE) -+ return tf; -+ -+ return NULL; - } - for ( ; tf; tf = tf->next) - { -diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d -index b4f65dc..5ae32a6 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.d -+++ b/gas/testsuite/gas/xtensa/trampoline.d -@@ -24,3 +24,12 @@ - .*33462:.*j.0x49407 - #... - .*49407:.*j.0x49407 -+.*4940a:.*beqz.n.a2,.0x4940f -+.*4940c:.*j.0x693d1 -+#... -+.*693d1:.*j.0x7ddd4 -+#... -+.*7ddd4:.*j.0x927f5 -+#... -+.*927f5:.*j.0x927f5 -+#... -diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s -index 259a3bb..4465786 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.s -+++ b/gas/testsuite/gas/xtensa/trampoline.s -@@ -19,3 +19,10 @@ - .endr - 3: - j 3b -+ bnez a2, 4f -+ .rep 50000 -+ and a2, a2, a3 -+ _ret -+ .endr -+4: -+ j 4b --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/patches/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch deleted file mode 100644 index 9ad6b3b..0000000 --- a/patches/binutils/2.23.2/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Thu, 14 May 2015 05:22:55 +0300 -Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections - -elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were -made local, that results in link failure with the following message: - - BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line - 3372 in elf_xtensa_finish_dynamic_sections - -elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by -relocation type. Relocation types are not changed when symbol becomes -local, but its PLT references are added to GOT references and -plt.refcount is set to 0. Such symbol cannot be unreferences in the -elf_xtensa_gc_sweep_hook and its extra references make calculated GOT -relocations section size not match number of GOT relocations. - -Fix it by treating PLT reference as GOT reference when plt.refcount is -not positive. - -2015-05-14 Max Filippov -bfd/ - * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference - as GOT reference when plt.refcount is not positive. - -Signed-off-by: Max Filippov ---- -Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 -Changes to ChangeLog are dropped. - - bfd/elf32-xtensa.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 53af1c6..2523670 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, - { - if (is_plt) - { -+ /* If the symbol has been localized its plt.refcount got moved -+ to got.refcount. Handle it as GOT. */ - if (h->plt.refcount > 0) - h->plt.refcount--; -+ else -+ is_got = TRUE; - } -- else if (is_got) -+ if (is_got) - { - if (h->got.refcount > 0) - h->got.refcount--; --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/patches/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch deleted file mode 100644 index 4a3de2c..0000000 --- a/patches/binutils/2.23.2/912-xtensa-fix-gas-segfault-with-text-section-literals.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sun, 17 May 2015 06:46:15 +0300 -Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals - -When --text-section-literals is used and code in the .init or .fini -emits literal in the absence of .literal_position, xtensa_move_literals -segfaults. - -Check that search_frag is non-NULL in the xtensa_move_literals and -report error otherwise. - -2015-05-26 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Check that - search_frag is non-NULL. Report error if literal frag is not - found. - -Signed-off-by: Max Filippov ---- -Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 -Changes to ChangeLog are dropped. - - gas/config/tc-xtensa.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 31c0b6b..18307c1 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) - frchain_to = NULL; - frag_splice = &(frchain_from->frch_root); - -- while (!search_frag->tc_frag_data.literal_frag) -+ while (search_frag && !search_frag->tc_frag_data.literal_frag) - { - gas_assert (search_frag->fr_fix == 0 - || search_frag->fr_type == rs_align); - search_frag = search_frag->fr_next; - } - -+ if (!search_frag) -+ { -+ search_frag = frchain_from->frch_root; -+ as_bad_where (search_frag->fr_file, search_frag->fr_line, -+ _("literal pool location required for text-section-literals; specify with .literal_position")); -+ continue; -+ } -+ - gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype - == RELAX_LITERAL_POOL_BEGIN); - xtensa_switch_section_emit_state (&state, segment->seg, 0); --- -1.8.1.4 - diff --git a/patches/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch b/patches/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch deleted file mode 100644 index 2955e11..0000000 --- a/patches/binutils/2.23.2/914-xtensa-fix-signedness-of-gas-relocations.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 2 Feb 2016 17:11:38 +0300 -Subject: [PATCH] xtensa: fix signedness of gas relocations - -Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation -offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations -substituted for BFD_RELOC_*. This made it impossible to encode arbitrary -8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc -directive. Revert this part and add test. - -gas/ -2016-02-03 Max Filippov - * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* - substitutions for BFD_RELOC_* as unsigned. - -Signed-off-by: Max Filippov ---- - gas/config/tc-xtensa.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index a119871..36a06cc 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - default: - break; --- -2.1.4 - diff --git a/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch deleted file mode 100644 index 62bc4b5..0000000 --- a/patches/binutils/2.23.2/915-xtensa-fix-.init-.fini-literals-moving.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 16 Feb 2016 02:23:28 +0300 -Subject: [PATCH] xtensa: fix .init/.fini literals moving - -Despite the documentation and the comment in xtensa_move_literals, in -the presence of --text-section-literals and --auto-litpools literals are -moved from the separate literal sections into .init and .fini, because -the check in the xtensa_move_literals is incorrect. - -This moving was broken with introduction of auto litpools: some literals -now may be lost. This happens because literal frags emitted from .init -and .fini are not closed when new .literal_position marks new literal -pool. Then frag_align(2, 0, 0) changes type of the last literal frag to -rs_align. rs_align frags are skipped in the xtensa_move_literals. As a -result fixups against such literals are not moved out of .init.literal/ -.fini.literal sections producing the following assembler error: - - test.S: Warning: fixes not all moved from .init.literal - test.S: Internal error! - -Fix check for .init.literal/.fini.literal in the xtensa_move_literals -and don't let it move literals from there in the presence of ---text-section-literals or --auto-litpools. - -2016-02-17 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Fix check for - .init.literal/.fini.literal section name. - -Signed-off-by: Max Filippov ---- -Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 - - gas/config/tc-xtensa.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 36a06cc..5773634 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -10625,5 +10625,9 @@ xtensa_move_literals (void) - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; -+ const char *init_name = INIT_SECTION_NAME; -+ const char *fini_name = FINI_SECTION_NAME; -+ int init_name_len = strlen(init_name); -+ int fini_name_len = strlen(fini_name); - - mark_literal_frags (literal_head->next); - -@@ -10632,9 +10636,13 @@ xtensa_move_literals (void) - - for (segment = literal_head->next; segment; segment = segment->next) - { -+ const char *seg_name = segment_name (segment->seg); -+ - /* Keep the literals for .init and .fini in separate sections. */ -- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) -- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) -+ if ((!memcmp (seg_name, init_name, init_name_len) && -+ !strcmp (seg_name + init_name_len, ".literal")) || -+ (!memcmp (seg_name, fini_name, fini_name_len) && -+ !strcmp (seg_name + fini_name_len, ".literal"))) - continue; - - frchain_from = seg_info (segment->seg)->frchainP; --- -2.1.4 - diff --git a/patches/binutils/2.24/001-fix-enable-install-libiberty-flag.patch b/patches/binutils/2.24/001-fix-enable-install-libiberty-flag.patch deleted file mode 100644 index e408401..0000000 --- a/patches/binutils/2.24/001-fix-enable-install-libiberty-flag.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 369be6981b26787b2685e3b8c6da779dae8ce35f Mon Sep 17 00:00:00 2001 -From: Mike Frysinger -Date: Mon, 6 Jan 2014 18:15:31 +0000 -Subject: [PATCH] libiberty: fix --enable-install-libiberty flag [PR 56780] - -Commit 199570 fixed the --disable-install-libiberty behavior, but it also -added a bug where the enable path never works because the initial clear -of target_header_dir wasn't deleted. So we end up initializing properly -at the top only to reset it at the end all the time. - -[Arnout: adapt to match 2.24 tarball] -Signed-off-by: Arnout Vandecappelle (Essensium/Mind) - -git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206367 138bc75d-0d04-0410-961f-82ee72b054a4 ---- - libiberty/configure | 1 - - libiberty/configure.ac | 1 - - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libiberty/configure b/libiberty/configure -index 8ea54da..7bde9b3 100755 ---- a/libiberty/configure -+++ b/libiberty/configure -@@ -5507,7 +5507,6 @@ fi - - setobjs= - CHECK= --target_header_dir= - if test -n "${with_target_subdir}"; then - - # We are being configured as a target library. AC_REPLACE_FUNCS -diff --git a/libiberty/configure.ac b/libiberty/configure.ac -index 4ad88a9..d6180bc 100644 ---- a/libiberty/configure.ac -+++ b/libiberty/configure.ac -@@ -405,7 +405,6 @@ fi - - setobjs= - CHECK= --target_header_dir= - if test -n "${with_target_subdir}"; then - - # We are being configured as a target library. AC_REPLACE_FUNCS --- -1.7.1 - diff --git a/patches/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch b/patches/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch deleted file mode 100644 index 7881646..0000000 --- a/patches/binutils/2.24/002-dont-segv-on-initial-instructions-overflow.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: Alan Modra -Date: Fri, 20 Dec 2013 13:27:52 +0000 (+1030) -Subject: Don't segv on cie.initial_instructions[] overflow. -X-Git-Tag: gdb-7.7-release~148 -X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff_plain;h=99d190fac4d2aab238cfc798dc5c28ab41456882 - -Don't segv on cie.initial_instructions[] overflow. - -Don't attempt to merge CIEs with a larger number of insns than will -fit in the buffer. - - * elf-eh-frame.c (cie_eq): Return false when initial_insn_length - is too large. - (cie_compute_hash): Don't exceed bounds of initial_instructions. - (_bfd_elf_parse_eh_frame): Always set initial_insn_length, and - save as much of insns to initial_instructions[] as will fit. ---- - -diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c -index 832a991..4b6e8ea 100644 ---- a/bfd/elf-eh-frame.c -+++ b/bfd/elf-eh-frame.c -@@ -235,6 +235,7 @@ cie_eq (const void *e1, const void *e2) - && c1->lsda_encoding == c2->lsda_encoding - && c1->fde_encoding == c2->fde_encoding - && c1->initial_insn_length == c2->initial_insn_length -+ && c1->initial_insn_length <= sizeof (c1->initial_instructions) - && memcmp (c1->initial_instructions, - c2->initial_instructions, - c1->initial_insn_length) == 0) -@@ -254,6 +255,7 @@ static hashval_t - cie_compute_hash (struct cie *c) - { - hashval_t h = 0; -+ size_t len; - h = iterative_hash_object (c->length, h); - h = iterative_hash_object (c->version, h); - h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h); -@@ -267,7 +269,10 @@ cie_compute_hash (struct cie *c) - h = iterative_hash_object (c->lsda_encoding, h); - h = iterative_hash_object (c->fde_encoding, h); - h = iterative_hash_object (c->initial_insn_length, h); -- h = iterative_hash (c->initial_instructions, c->initial_insn_length, h); -+ len = c->initial_insn_length; -+ if (len > sizeof (c->initial_instructions)) -+ len = sizeof (c->initial_instructions); -+ h = iterative_hash (c->initial_instructions, len, h); - c->hash = h; - return h; - } -@@ -762,11 +767,10 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, - cie->fde_encoding = DW_EH_PE_absptr; - - initial_insn_length = end - buf; -- if (initial_insn_length <= sizeof (cie->initial_instructions)) -- { -- cie->initial_insn_length = initial_insn_length; -- memcpy (cie->initial_instructions, buf, initial_insn_length); -- } -+ cie->initial_insn_length = initial_insn_length; -+ memcpy (cie->initial_instructions, buf, -+ initial_insn_length <= sizeof (cie->initial_instructions) -+ ? initial_insn_length : sizeof (cie->initial_instructions)); - insns = buf; - buf += initial_insn_length; - ENSURE_NO_RELOCS (buf); diff --git a/patches/binutils/2.24/120-sh-conf.patch b/patches/binutils/2.24/120-sh-conf.patch deleted file mode 100644 index d5913e8..0000000 --- a/patches/binutils/2.24/120-sh-conf.patch +++ /dev/null @@ -1,31 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - -diff -durN binutils-2.22.orig/configure binutils-2.22/configure ---- binutils-2.22.orig/configure 2011-08-14 14:28:15.000000000 +0200 -+++ binutils-2.22/configure 2011-12-14 19:49:40.284777434 +0100 -@@ -3570,7 +3570,7 @@ - mips*-*-*) - noconfigdirs="$noconfigdirs gprof" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; -diff -durN binutils-2.22.orig/configure.ac binutils-2.22/configure.ac ---- binutils-2.22.orig/configure.ac 2011-11-21 12:58:27.000000000 +0100 -+++ binutils-2.22/configure.ac 2011-12-14 19:49:40.316777436 +0100 -@@ -1006,7 +1006,7 @@ - mips*-*-*) - noconfigdirs="$noconfigdirs gprof" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.24/300-001_ld_makefile_patch.patch b/patches/binutils/2.24/300-001_ld_makefile_patch.patch deleted file mode 100644 index 4b5888a..0000000 --- a/patches/binutils/2.24/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -durN binutils-2.22.orig/ld/Makefile.am binutils-2.22/ld/Makefile.am ---- binutils-2.22.orig/ld/Makefile.am 2011-07-22 22:22:37.000000000 +0200 -+++ binutils-2.22/ld/Makefile.am 2011-12-14 19:50:25.760779164 +0100 -@@ -37,7 +37,7 @@ - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff -durN binutils-2.22.orig/ld/Makefile.in binutils-2.22/ld/Makefile.in ---- binutils-2.22.orig/ld/Makefile.in 2011-07-22 22:22:37.000000000 +0200 -+++ binutils-2.22/ld/Makefile.in 2011-12-14 19:50:25.784779163 +0100 -@@ -366,7 +366,7 @@ - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.24/300-012_check_ldrunpath_length.patch b/patches/binutils/2.24/300-012_check_ldrunpath_length.patch deleted file mode 100644 index b49cc04..0000000 --- a/patches/binutils/2.24/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -durN binutils-2.22.orig/ld/emultempl/elf32.em binutils-2.22/ld/emultempl/elf32.em ---- binutils-2.22.orig/ld/emultempl/elf32.em 2011-11-21 10:29:39.000000000 +0100 -+++ binutils-2.22/ld/emultempl/elf32.em 2011-12-14 19:52:12.880783238 +0100 -@@ -1273,6 +1273,8 @@ - && command_line.rpath == NULL) - { - lib_path = (const char *) getenv ("LD_RUN_PATH"); -+ if ((lib_path) && (strlen (lib_path) == 0)) -+ lib_path = NULL; - if (gld${EMULATION_NAME}_search_needed (lib_path, &n, - force)) - break; -@@ -1500,6 +1502,8 @@ - rpath = command_line.rpath; - if (rpath == NULL) - rpath = (const char *) getenv ("LD_RUN_PATH"); -+ if ((rpath) && (strlen (rpath) == 0)) -+ rpath = NULL; - - for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.24/310-fix-gold-pthreads-typo.patch b/patches/binutils/2.24/310-fix-gold-pthreads-typo.patch deleted file mode 100644 index f2e6ff2..0000000 --- a/patches/binutils/2.24/310-fix-gold-pthreads-typo.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 -@@ -102,9 +102,9 @@ - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); - #ifdef PTHREAD_MUTEX_ADAPTIVE_NP -- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); -+ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) -- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); -+ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); - #endif - - err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/patches/binutils/2.24/500-sysroot.patch b/patches/binutils/2.24/500-sysroot.patch deleted file mode 100644 index e49c795..0000000 --- a/patches/binutils/2.24/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -308,18 +308,25 @@ - directory first. */ - if (! entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.24/600-poison-system-directories.patch b/patches/binutils/2.24/600-poison-system-directories.patch deleted file mode 100644 index 6a3bf6b..0000000 --- a/patches/binutils/2.24/600-poison-system-directories.patch +++ /dev/null @@ -1,279 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -Signed-off-by: Thomas Petazzoni - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.in (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -Index: b/ld/config.in -=================================================================== ---- a/ld/config.in -+++ b/ld/config.in -@@ -11,6 +11,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -Index: b/ld/configure -=================================================================== ---- a/ld/configure -+++ b/ld/configure -@@ -774,6 +774,7 @@ - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_werror -@@ -1429,6 +1430,8 @@ - (and sometimes confusing) to the casual installer - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -4339,7 +4342,18 @@ - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -Index: b/ld/configure.in -=================================================================== ---- a/ld/configure.in -+++ b/ld/configure.in -@@ -87,6 +87,16 @@ - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -Index: b/ld/ldfile.c -=================================================================== ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -116,6 +116,23 @@ - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -Index: b/ld/ld.h -=================================================================== ---- a/ld/ld.h -+++ b/ld/ld.h -@@ -180,6 +180,14 @@ - /* If TRUE we'll just print the default output on stdout. */ - bfd_boolean print_output_format; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -Index: b/ld/ldmain.c -=================================================================== ---- a/ld/ldmain.c -+++ b/ld/ldmain.c -@@ -266,6 +266,8 @@ - command_line.warn_mismatch = TRUE; - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -Index: b/ld/ld.texinfo -=================================================================== ---- a/ld/ld.texinfo -+++ b/ld/ld.texinfo -@@ -2175,6 +2175,18 @@ - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -Index: b/ld/lexsup.c -=================================================================== ---- a/ld/lexsup.c -+++ b/ld/lexsup.c -@@ -507,6 +507,14 @@ - OPTION_IGNORE_UNRESOLVED_SYMBOL}, - '\0', N_("SYMBOL"), - N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ + OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -519,6 +527,7 @@ - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1442,9 +1451,21 @@ - einfo (_("%P%X: --hash-size needs a numeric argument\n")); - } - break; -+ -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; - } - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); -Index: b/ld/ldlex.h -=================================================================== ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -138,6 +138,8 @@ - OPTION_DEFAULT_SCRIPT, - OPTION_PRINT_OUTPUT_FORMAT, - OPTION_IGNORE_UNRESOLVED_SYMBOL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ diff --git a/patches/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch b/patches/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch deleted file mode 100644 index cea92f3..0000000 --- a/patches/binutils/2.24/700-Fix-library-paths-on-PowerPC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 -From: Alexey Neyman -Date: Sat, 11 Mar 2017 17:27:09 -0800 -Subject: [PATCH] Fix library paths on PowerPC - -First, need to match against just the CPU name, not the whole triplet. -Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin -triplet. - -Second, it should be testing for $target, not $host. Host may be -little endian by default, and the sysroot directory layout shouldn't -depend on whether it is built on LE or BE machine. - -Signed-off-by: Alexey Neyman ---- - ld/emulparams/elf32ppccommon.sh | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh -index 1f54ef8..d00cf68 100644 ---- a/ld/emulparams/elf32ppccommon.sh -+++ b/ld/emulparams/elf32ppccommon.sh -@@ -44,11 +44,11 @@ fi - - # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. - # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. --case "$host":"$EMULATION_NAME" in -- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; -- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; -- *le-*:*64*) LIBPATH_SUFFIX=64be ;; -- *le-*:*32*) LIBPATH_SUFFIX=32be ;; -+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in -+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; -+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; -+ *le:*64*) LIBPATH_SUFFIX=64be ;; -+ *le:*32*) LIBPATH_SUFFIX=32be ;; - *:*64lppc*) LIBPATH_SUFFIX=64le ;; - *:*32lppc*) LIBPATH_SUFFIX=32le ;; - *:*64*) LIBPATH_SUFFIX=64 ;; --- -2.9.3 - diff --git a/patches/binutils/2.24/900-xtensa-trampolines.patch b/patches/binutils/2.24/900-xtensa-trampolines.patch deleted file mode 100644 index b5b934f..0000000 --- a/patches/binutils/2.24/900-xtensa-trampolines.patch +++ /dev/null @@ -1,846 +0,0 @@ -From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001 -From: David Weatherford -Date: Fri, 21 Mar 2014 11:53:42 +0000 -Subject: [PATCH] Add support to the Xtensa target for creating trampolines for - out-of-range branches. - - * tc-xtensa.c (xtensa_check_frag_count, xtensa_create_trampoline_frag) - (xtensa_maybe_create_trampoline_frag, init_trampoline_frag) - (find_trampoline_seg, search_trampolines, get_best_trampoline) - (check_and_update_trampolines, add_jump_to_trampoline) - (dump_trampolines): New function. - (md_parse_option): Add cases for --[no-]trampolines options. - (md_assemble, finish_vinsn, xtensa_end): Add call to - xtensa_check_frag_count. - (xg_assemble_vliw_tokens): Add call to - xtensa_maybe_create_trampoline_frag. - (xtensa_relax_frag): Relax fragments with RELAX_TRAMPOLINE state. - (relax_frag_immed): Relax jump instructions that cannot reach its - target. - * tc-xtensa.h (xtensa_relax_statesE::RELAX_TRAMPOLINE): New relax - state. - - * as.texinfo: Document --[no-]trampolines command-line options. - * c-xtensa.texi: Document trampolines relaxation and command line - options. - - * frags.c (get_frag_count, clear_frag_count): New function. - (frag_alloc): Increment totalfrags counter. - * frags.h (get_frag_count, clear_frag_count): New function. - - * all.exp: Add test for trampoline relaxation. - * trampoline.d: Trampoline relaxation expected dump. - * trampoline.s: Trampoline relaxation test source. ---- -Backported from: a82c7d9030b67a6a76a5403d0e1641f9e42141ac -Changes to Changelog files are dropped. - - gas/config/tc-xtensa.c | 558 +++++++++++++++++++++++++++++++++- - gas/config/tc-xtensa.h | 5 + - gas/frags.c | 15 + - gas/frags.h | 3 + - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/trampoline.d | 26 ++ - gas/testsuite/gas/xtensa/trampoline.s | 21 ++ - 11 files changed, 753 insertions(+), 2 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/trampoline.d - create mode 100644 gas/testsuite/gas/xtensa/trampoline.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index fe8ec0f..ea23c96 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -468,6 +468,12 @@ static void xtensa_set_frag_assembly_state (fragS *); - static void finish_vinsn (vliw_insn *); - static bfd_boolean emit_single_op (TInsn *); - static int total_frag_text_expansion (fragS *); -+static bfd_boolean use_trampolines = TRUE; -+static void xtensa_check_frag_count (void); -+static void xtensa_create_trampoline_frag (bfd_boolean); -+static void xtensa_maybe_create_trampoline_frag (void); -+struct trampoline_frag; -+static int init_trampoline_frag (struct trampoline_frag *); - - /* Alignment Functions. */ - -@@ -520,6 +526,7 @@ static void tinsn_from_chars (TInsn *, char *, int); - static void tinsn_immed_from_frag (TInsn *, fragS *, int); - static int get_num_stack_text_bytes (IStack *); - static int get_num_stack_literal_bytes (IStack *); -+static bfd_boolean tinsn_to_slotbuf (xtensa_format, int, TInsn *, xtensa_insnbuf); - - /* vliw_insn functions. */ - -@@ -687,7 +694,10 @@ enum - option_prefer_l32r, - option_prefer_const16, - -- option_target_hardware -+ option_target_hardware, -+ -+ option_trampolines, -+ option_no_trampolines, - }; - - const char *md_shortopts = ""; -@@ -760,6 +770,9 @@ struct option md_longopts[] = - - { "target-hardware", required_argument, NULL, option_target_hardware }, - -+ { "trampolines", no_argument, NULL, option_trampolines }, -+ { "no-trampolines", no_argument, NULL, option_no_trampolines }, -+ - { NULL, no_argument, NULL, 0 } - }; - -@@ -940,6 +953,14 @@ md_parse_option (int c, char *arg) - directive_state[directive_transform] = FALSE; - return 1; - -+ case option_trampolines: -+ use_trampolines = TRUE; -+ return 1; -+ -+ case option_no_trampolines: -+ use_trampolines = FALSE; -+ return 1; -+ - default: - return 0; - } -@@ -963,7 +984,9 @@ Xtensa options:\n\ - flix bundles\n\ - --no-allow-flix neither allow hand-written nor generate\n\ - flix bundles\n\ -- --rename-section old=new Rename section 'old' to 'new'\n", stream); -+ --rename-section old=new Rename section 'old' to 'new'\n\ -+ --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ -+ when jumps do not reach their targets\n", stream); - } - - -@@ -5568,6 +5591,8 @@ md_assemble (char *str) - - /* We've just emitted a new instruction so clear the list of labels. */ - xtensa_clear_insn_labels (); -+ -+ xtensa_check_frag_count (); - } - - -@@ -6372,6 +6397,8 @@ finish_vinsn (vliw_insn *vinsn) - xg_assemble_vliw_tokens (vinsn); - - xg_clear_vinsn (vinsn); -+ -+ xtensa_check_frag_count (); - } - - -@@ -7140,6 +7167,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - RELAX_UNREACHABLE, - frag_now->fr_symbol, frag_now->fr_offset, NULL); - xtensa_set_frag_assembly_state (frag_now); -+ xtensa_maybe_create_trampoline_frag (); - } - else if (is_branch && do_align_targets ()) - { -@@ -7222,9 +7250,164 @@ xtensa_end (void) - xtensa_sanity_check (); - - xtensa_add_config_info (); -+ -+ xtensa_check_frag_count (); -+} -+ -+ -+struct trampoline_frag -+{ -+ struct trampoline_frag *next; -+ bfd_boolean needs_jump_around; -+ fragS *fragP; -+ fixS *fixP; -+}; -+ -+struct trampoline_seg -+{ -+ struct trampoline_seg *next; -+ asection *seg; -+ struct trampoline_frag trampoline_list; -+}; -+ -+static struct trampoline_seg trampoline_seg_list; -+#define J_RANGE (128 * 1024) -+ -+static int unreachable_count = 0; -+ -+ -+static void -+xtensa_maybe_create_trampoline_frag (void) -+{ -+ if (!use_trampolines) -+ return; -+ -+ /* We create an area for possible trampolines every 10 unreachable frags. -+ These are preferred over the ones not preceded by an unreachable frag, -+ because we don't have to jump around them. This function is called after -+ each RELAX_UNREACHABLE frag is created. */ -+ -+ if (++unreachable_count > 10) -+ { -+ xtensa_create_trampoline_frag (FALSE); -+ clear_frag_count (); -+ unreachable_count = 0; -+ } -+} -+ -+static void -+xtensa_check_frag_count (void) -+{ -+ if (!use_trampolines || frag_now->tc_frag_data.is_no_transform) -+ return; -+ -+ /* We create an area for possible trampolines every 8000 frags or so. This -+ is an estimate based on the max range of a "j" insn (+/-128K) divided -+ by a typical frag byte count (16), minus a few for safety. This function -+ is called after each source line is processed. */ -+ -+ if (get_frag_count () > 8000) -+ { -+ xtensa_create_trampoline_frag (TRUE); -+ clear_frag_count (); -+ unreachable_count = 0; -+ } -+} -+ -+static xtensa_insnbuf trampoline_buf = NULL; -+static xtensa_insnbuf trampoline_slotbuf = NULL; -+ -+#define TRAMPOLINE_FRAG_SIZE 3000 -+ -+static void -+xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) -+{ -+ /* Emit a frag where we can place intermediate jump instructions, -+ in case we need to jump farther than 128K bytes. -+ Each jump instruction takes three bytes. -+ We allocate enough for 1000 trampolines in each frag. -+ If that's not enough, oh well. */ -+ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ struct trampoline_frag *tf; -+ char *varP; -+ fragS *fragP; -+ int size = TRAMPOLINE_FRAG_SIZE; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ if (ts->seg == now_seg) -+ break; -+ } -+ -+ if (ts == NULL) -+ { -+ ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1); -+ ts->next = trampoline_seg_list.next; -+ trampoline_seg_list.next = ts; -+ ts->seg = now_seg; -+ } -+ -+ frag_wane (frag_now); -+ frag_new (0); -+ xtensa_set_frag_assembly_state (frag_now); -+ varP = frag_var (rs_machine_dependent, size, size, RELAX_TRAMPOLINE, NULL, 0, NULL); -+ fragP = (fragS *)(varP - SIZEOF_STRUCT_FRAG); -+ if (trampoline_buf == NULL) -+ { -+ trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa); -+ trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa); -+ } -+ tf = (struct trampoline_frag *)xmalloc(sizeof (struct trampoline_frag)); -+ tf->next = ts->trampoline_list.next; -+ ts->trampoline_list.next = tf; -+ tf->needs_jump_around = needs_jump_around; -+ tf->fragP = fragP; -+ tf->fixP = NULL; -+} -+ -+ -+static struct trampoline_seg * -+find_trampoline_seg (asection *seg) -+{ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ if (ts->seg == seg) -+ return ts; -+ } -+ -+ return NULL; - } - - -+void dump_trampolines (void); -+ -+void -+dump_trampolines (void) -+{ -+ struct trampoline_seg *ts = trampoline_seg_list.next; -+ -+ for ( ; ts; ts = ts->next) -+ { -+ asection *seg = ts->seg; -+ -+ if (seg == NULL) -+ continue; -+ fprintf(stderr, "SECTION %s\n", seg->name); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ for ( ; tf; tf = tf->next) -+ { -+ if (tf->fragP == NULL) -+ continue; -+ fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n", -+ (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix, -+ tf->needs_jump_around ? "T" : "F"); -+ } -+ } -+} -+ - static void - xtensa_cleanup_align_frags (void) - { -@@ -8708,6 +8891,149 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - new_stretch += relax_frag_for_align (fragP, stretch); - break; - -+ case RELAX_TRAMPOLINE: -+ if (fragP->tc_frag_data.relax_seen) -+ { -+ segment_info_type *seginfo = seg_info (now_seg); -+ fragS *fP; /* The out-of-range jump. */ -+ fixS *fixP; -+ -+ /* Scan for jumps that will not reach. */ -+ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ { -+ symbolS *s = fixP->fx_addsy; -+ xtensa_opcode opcode; -+ int target; -+ int addr; -+ int delta; -+ -+ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -+ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -+ continue; -+ xtensa_insnbuf_from_chars (isa, trampoline_buf, -+ (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, -+ 0); -+ fmt = xtensa_format_decode (isa, trampoline_buf); -+ gas_assert (fmt != XTENSA_UNDEFINED); -+ slot = fixP->tc_fix_data.slot; -+ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -+ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -+ if (opcode != xtensa_j_opcode) -+ continue; -+ target = S_GET_VALUE (s); -+ addr = fixP->fx_frag->fr_address; -+ delta = target - addr + stretch; -+ if (delta > J_RANGE || delta < -1 * J_RANGE) -+ { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ struct trampoline_frag *prev = &ts->trampoline_list; -+ int lower = (target < addr) ? target : addr; -+ int upper = (target > addr) ? target : addr; -+ int midpoint = lower + (upper - lower) / 2; -+ -+ if ((upper - lower) > 2 * J_RANGE) -+ { -+ /* One trampoline won't suffice; we need multiple jumps. -+ Jump to the trampoline that's farthest, but still in -+ range relative to the original "j" instruction. */ -+ for ( ; tf; prev = tf, tf = tf->next ) -+ { -+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ; -+ -+ if (addr == lower) -+ { -+ /* Forward jump. */ -+ if (this_addr - addr < J_RANGE) -+ break; -+ } -+ else -+ { -+ /* Backward jump. */ -+ if (next_addr == 0 || addr - next_addr > J_RANGE) -+ break; -+ } -+ } -+ } -+ else -+ { -+ struct trampoline_frag *best_tf = NULL; -+ int best_delta = 0; -+ -+ for ( ; tf; prev = tf, tf = tf->next ) -+ { -+ int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ int this_delta = abs (this_addr - midpoint); -+ -+ if (!best_tf || this_delta < best_delta) -+ { -+ best_tf = tf; -+ best_delta = this_delta; -+ } -+ } -+ tf = best_tf; -+ } -+ if (tf->fragP == fragP) -+ { -+ int trampaddr = fragP->fr_address + fragP->fr_fix; -+ -+ if (abs (addr - trampaddr) < J_RANGE) -+ { /* The trampoline is in range of original; fix it! */ -+ fixS *newfixP; -+ int offset; -+ TInsn insn; -+ symbolS *lsym; -+ -+ new_stretch += init_trampoline_frag (tf); -+ offset = fragP->fr_fix; /* Where to assemble the j insn. */ -+ lsym = fragP->fr_symbol; -+ fP = fixP->fx_frag; -+ /* Assemble a jump to the target label here. */ -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], lsym, offset); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fragP->fr_literal + offset, 3); -+ fragP->fr_fix += 3; -+ fragP->fr_var -= 3; -+ /* Add a fix-up for the original j insn. */ -+ newfixP = fix_new (fP, fixP->fx_where, fixP->fx_size, lsym, fragP->fr_fix - 3, TRUE, fixP->fx_r_type); -+ newfixP->fx_no_overflow = 1; -+ newfixP->tc_fix_data.X_add_symbol = lsym; -+ newfixP->tc_fix_data.X_add_number = offset; -+ newfixP->tc_fix_data.slot = slot; -+ /* Move the fix-up from the original j insn to this one. */ -+ fixP->fx_frag = fragP; -+ fixP->fx_where = fragP->fr_fix - 3; -+ fixP->tc_fix_data.slot = 0; -+ /* Adjust the jump around this trampoline (if present). */ -+ if (tf->fixP != NULL) -+ { -+ tf->fixP->fx_offset += 3; -+ } -+ new_stretch += 3; -+ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ -+ /* Do we have room for more? */ -+ if (fragP->fr_var < 3) -+ { /* No, convert to fill. */ -+ frag_wane (fragP); -+ fragP->fr_subtype = 0; -+ /* Remove from the trampoline_list. */ -+ prev->next = tf->next; -+ break; -+ } -+ } -+ } -+ } -+ } -+ } -+ break; -+ - default: - as_bad (_("bad relaxation state")); - } -@@ -9146,6 +9472,200 @@ bytes_to_stretch (fragS *this_frag, - } - - -+static struct trampoline_frag * -+search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) -+{ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL; -+ struct trampoline_frag *best_tf = NULL; -+ int best_delta = 0; -+ int best_addr = 0; -+ symbolS *sym = tinsn->tok[0].X_add_symbol; -+ offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; -+ offsetT addr = fragP->fr_address; -+ offsetT lower = (addr < target) ? addr : target; -+ offsetT upper = (addr > target) ? addr : target; -+ int delta = upper - lower; -+ offsetT midpoint = lower + delta / 2; -+ int this_delta = -1; -+ int this_addr = -1; -+ -+ if (delta > 2 * J_RANGE) -+ { -+ /* One trampoline won't do; we need multiple. -+ Choose the farthest trampoline that's still in range of the original -+ and let a later pass finish the job. */ -+ for ( ; tf; tf = tf->next) -+ { -+ int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0; -+ -+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ if (lower == addr) -+ { -+ /* Forward jump. */ -+ if (this_addr - addr < J_RANGE) -+ break; -+ } -+ else -+ { -+ /* Backward jump. */ -+ if (next_addr == 0 || addr - next_addr > J_RANGE) -+ break; -+ } -+ if (abs (addr - this_addr) < J_RANGE) -+ return tf; -+ -+ return NULL; -+ } -+ } -+ for ( ; tf; tf = tf->next) -+ { -+ this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; -+ this_delta = abs (this_addr - midpoint); -+ if (unreachable_only && tf->needs_jump_around) -+ continue; -+ if (!best_tf || this_delta < best_delta) -+ { -+ best_tf = tf; -+ best_delta = this_delta; -+ best_addr = this_addr; -+ } -+ } -+ -+ if (best_tf && -+ best_delta < J_RANGE && -+ abs(best_addr - lower) < J_RANGE && -+ abs(best_addr - upper) < J_RANGE) -+ return best_tf; -+ -+ return NULL; /* No suitable trampoline found. */ -+} -+ -+ -+static struct trampoline_frag * -+get_best_trampoline (TInsn *tinsn, fragS *fragP) -+{ -+ struct trampoline_frag *tf = NULL; -+ -+ tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ -+ -+ if (tf == NULL) -+ tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */ -+ -+ return tf; -+} -+ -+ -+static void -+check_and_update_trampolines (void) -+{ -+ struct trampoline_seg *ts = find_trampoline_seg (now_seg); -+ struct trampoline_frag *tf = ts->trampoline_list.next; -+ struct trampoline_frag *prev = &ts->trampoline_list; -+ -+ for ( ; tf; prev = tf, tf = tf->next) -+ { -+ if (tf->fragP->fr_var < 3) -+ { -+ frag_wane (tf->fragP); -+ prev->next = tf->next; -+ tf->fragP = NULL; -+ } -+ } -+} -+ -+ -+static int -+init_trampoline_frag (struct trampoline_frag *trampP) -+{ -+ fragS *fp = trampP->fragP; -+ int growth = 0; -+ -+ if (fp->fr_fix == 0) -+ { -+ symbolS *lsym; -+ char label[10 + 2 * sizeof(fp)]; -+ sprintf (label, ".L0_TR_%p", fp); -+ -+ lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); -+ fp->fr_symbol = lsym; -+ if (trampP->needs_jump_around) -+ { -+ /* Add a jump around this block of jumps, in case -+ control flows into this block. */ -+ fixS *fixP; -+ TInsn insn; -+ xtensa_format fmt; -+ xtensa_isa isa = xtensa_default_isa; -+ -+ fp->tc_frag_data.is_insn = 1; -+ /* Assemble a jump insn. */ -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], lsym, 3); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)fp->fr_literal, 3); -+ fp->fr_fix += 3; -+ fp->fr_var -= 3; -+ growth = 3; -+ fixP = fix_new (fp, 0, 3, lsym, 3, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); -+ trampP->fixP = fixP; -+ } -+ } -+ return growth; -+} -+ -+ -+static int -+add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) -+{ -+ fragS *tramp = trampP->fragP; -+ fixS *fixP; -+ int offset = tramp->fr_fix; /* Where to assemble the j insn. */ -+ TInsn insn; -+ symbolS *lsym; -+ symbolS *tsym; -+ int toffset; -+ xtensa_format fmt; -+ xtensa_isa isa = xtensa_default_isa; -+ int growth = 0; -+ -+ lsym = tramp->fr_symbol; -+ /* Assemble a jump to the target label in the trampoline frag. */ -+ tsym = origfrag->tc_frag_data.slot_symbols[0]; -+ toffset = origfrag-> tc_frag_data.slot_offsets[0]; -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], tsym, toffset); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, trampoline_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, trampoline_buf, trampoline_slotbuf); -+ xtensa_insnbuf_to_chars (isa, trampoline_buf, (unsigned char *)tramp->fr_literal + offset, 3); -+ tramp->fr_fix += 3; -+ tramp->fr_var -= 3; -+ growth = 3; -+ /* add a fix-up for the trampoline jump. */ -+ fixP = fix_new (tramp, tramp->fr_fix - 3, 3, tsym, toffset, TRUE, BFD_RELOC_XTENSA_SLOT0_OP); -+ /* Modify the jump at the start of this trampoline to point past the newly-added jump. */ -+ fixP = trampP->fixP; -+ if (fixP) -+ fixP->fx_offset += 3; -+ /* Modify the original j to point here. */ -+ origfrag->tc_frag_data.slot_symbols[0] = lsym; -+ origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3; -+ /* If trampoline is full, remove it from the list. */ -+ check_and_update_trampolines (); -+ -+ return growth; -+} -+ -+ - static long - relax_frag_immed (segT segP, - fragS *fragP, -@@ -9284,6 +9804,37 @@ relax_frag_immed (segT segP, - if (negatable_branch && istack.ninsn > 1) - update_next_frag_state (fragP); - -+ /* If last insn is a jump, and it cannot reach its target, try to find a trampoline. */ -+ if (istack.ninsn > 2 && -+ istack.insn[istack.ninsn - 1].insn_type == ITYPE_LABEL && -+ istack.insn[istack.ninsn - 2].insn_type == ITYPE_INSN && -+ istack.insn[istack.ninsn - 2].opcode == xtensa_j_opcode) -+ { -+ TInsn *jinsn = &istack.insn[istack.ninsn - 2]; -+ -+ if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) -+ { -+ struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP); -+ -+ if (tf) -+ { -+ this_text_diff += init_trampoline_frag (tf); -+ this_text_diff += add_jump_to_trampoline (tf, fragP); -+ } -+ else -+ { -+ /* If target symbol is undefined, assume it will reach once linked. */ -+ expressionS *exp = &istack.insn[istack.ninsn - 2].tok[0]; -+ -+ if (exp->X_op == O_symbol && S_IS_DEFINED (exp->X_add_symbol)) -+ { -+ as_bad_where (fragP->fr_file, fragP->fr_line, -+ _("jump target out of range; no usable trampoline found")); -+ } -+ } -+ } -+ } -+ - return this_text_diff; - } - -@@ -9404,6 +9955,9 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp) - else - as_bad (_("invalid relaxation fragment result")); - break; -+ -+ case RELAX_TRAMPOLINE: -+ break; - } - - fragp->fr_var = 0; -diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h -index 0bf1240..4672bc6 100644 ---- a/gas/config/tc-xtensa.h -+++ b/gas/config/tc-xtensa.h -@@ -180,6 +180,11 @@ enum xtensa_relax_statesE - prevent the linker from changing the size of any frag between the - section start and the org frag. */ - -+ RELAX_TRAMPOLINE, -+ /* Every few thousand frags, we insert one of these, just in case we may -+ need some space for a trampoline (jump to a jump) because the function -+ has gotten too big. If not needed, it disappears. */ -+ - RELAX_NONE - }; - -diff --git a/gas/frags.c b/gas/frags.c -index 5f68480..e14099d 100644 ---- a/gas/frags.c -+++ b/gas/frags.c -@@ -24,6 +24,20 @@ - - extern fragS zero_address_frag; - extern fragS predefined_address_frag; -+ -+static int totalfrags; -+ -+int -+get_frag_count (void) -+{ -+ return totalfrags; -+} -+ -+void -+clear_frag_count (void) -+{ -+ totalfrags = 0; -+} - - /* Initialization for frag routines. */ - -@@ -70,6 +84,7 @@ frag_alloc (struct obstack *ob) - ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG); - obstack_alignment_mask (ob) = oalign; - memset (ptr, 0, SIZEOF_STRUCT_FRAG); -+ totalfrags++; - return ptr; - } - -diff --git a/gas/frags.h b/gas/frags.h -index 319898f..2f9e1b5 100644 ---- a/gas/frags.h -+++ b/gas/frags.h -@@ -155,4 +155,7 @@ char *frag_var (relax_stateT type, - - bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); - -+int get_frag_count (void); -+void clear_frag_count (void); -+ - #endif /* FRAGS_H */ -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 2b2c294..3683b78 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -98,6 +98,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "pcrel" - run_dump_test "weak-call" - run_dump_test "jlong" -+ run_dump_test "trampoline" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d -new file mode 100644 -index 0000000..b4f65dc ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/trampoline.d -@@ -0,0 +1,26 @@ -+#as: -+#objdump: -d -+#name: trampolines relaxation -+ -+.*: +file format .*xtensa.* -+#... -+.*0:.*j.0x1194c -+.*3:.*j.0x1194f -+.*6:.*j.0x11952 -+.*9:.*j.0x1d4e4 -+#... -+.*11949:.*j.0x11955 -+.*1194c:.*j.0x24a0e -+.*1194f:.*j.0x24a0e -+.*11952:.*j.0x24a11 -+#... -+.*1d4e1:.*j.0x1d4e7 -+.*1d4e4:.*j.0x33462 -+#... -+.*24a0e:.*j.0x24a0e -+.*24a11:.*j.0x24a11 -+#... -+.*3345f:.*ret -+.*33462:.*j.0x49407 -+#... -+.*49407:.*j.0x49407 -diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s -new file mode 100644 -index 0000000..259a3bb ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/trampoline.s -@@ -0,0 +1,21 @@ -+ .text -+ j 1f -+ j 1f -+ j 2f -+ j 3f -+ .rep 25000 -+99: -+ and a2, a2, a3 -+ bne a2, a3, 99b -+ .endr -+1: -+ j 1b -+2: -+ j 2b -+ -+ .rep 25000 -+ and a2, a2, a3 -+ _ret -+ .endr -+3: -+ j 3b --- -1.8.1.4 - diff --git a/patches/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch b/patches/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch deleted file mode 100644 index e1c2d85..0000000 --- a/patches/binutils/2.24/901-xtensa-gas-first-frag-alignment.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 15 Apr 2014 19:12:46 +0400 -Subject: [PATCH] Fix alignment for the first section frag on xtensa - -Linking object files produced by partial linking with link-time -relaxation enabled sometimes fails with the following error message: - -dangerous relocation: call8: misaligned call target: (.text.unlikely+0x63) - -This happens because no basic block with an XTENSA_PROP_ALIGN flag in the -property table is generated for the first basic block, even if the -.align directive is present. -It was believed that the first frag alignment could be derived from the -section alignment, but this was not implemented for the partial linking -case: after partial linking first frag of a section may become not -first, but no additional alignment frag is inserted before it. -Basic block for such frag may be merged with previous basic block into -extended basic block during relaxation pass losing its alignment -restrictions. - -Fix this by always recording alignment for the first section frag. - -2014-04-22 Max Filippov - -gas/ - * config/tc-xtensa.c (xtensa_handle_align): record alignment for the - first section frag. - ---- -Backported from: a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 -Changes to Changelog files and tests are dropped. - - gas/config/tc-xtensa.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index ea23c96..58ace38 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5609,7 +5609,6 @@ xtensa_handle_align (fragS *fragP) - && ! fragP->tc_frag_data.is_literal - && (fragP->fr_type == rs_align - || fragP->fr_type == rs_align_code) -- && fragP->fr_address + fragP->fr_fix > 0 - && fragP->fr_offset > 0 - && now_seg != bss_section) - { --- -1.8.1.4 - diff --git a/patches/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch b/patches/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch deleted file mode 100644 index ba24f4e..0000000 --- a/patches/binutils/2.24/902-xtensa-gas-ld-diff-relocation-signed.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001 -From: Volodymyr Arbatov -Date: Mon, 6 May 2013 09:43:21 -0800 -Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets. - -R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such. -Add testcase that examines ld behaviour on R_XTENSA_DIFF relocation -changing sign during relaxation. - -2014-05-02 Volodymyr Arbatov - David Weatherford - Max Filippov - -bfd/ - * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as - signed. - -gas/ - * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF* - fixups as signed. ---- -Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6 -Changes to Changelog files and tests are dropped. - - bfd/elf32-xtensa.c | 32 ++++++++++++----------- - gas/config/tc-xtensa.c | 3 +++ - 2 files changed, 20 insertions(+), 15 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index edb04b4..8818d67 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] = - FALSE, 0, 0, FALSE), - - /* Relocations for supporting difference of symbols. */ -- HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE), -- HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE), -- HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, -+ HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE), - - /* General immediate operand relocations. */ -@@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - || r_type == R_XTENSA_DIFF16 - || r_type == R_XTENSA_DIFF32) - { -- bfd_vma diff_value = 0, new_end_offset, diff_mask = 0; -+ bfd_signed_vma diff_value = 0; -+ bfd_vma new_end_offset, diff_mask = 0; - - if (bfd_get_section_limit (abfd, sec) < old_source_offset) - { -@@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - { - case R_XTENSA_DIFF8: - diff_value = -- bfd_get_8 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_8 (abfd, &contents[old_source_offset]); - break; - case R_XTENSA_DIFF16: - diff_value = -- bfd_get_16 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_16 (abfd, &contents[old_source_offset]); - break; - case R_XTENSA_DIFF32: - diff_value = -- bfd_get_32 (abfd, &contents[old_source_offset]); -+ bfd_get_signed_32 (abfd, &contents[old_source_offset]); - break; - } - -@@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - switch (r_type) - { - case R_XTENSA_DIFF8: -- diff_mask = 0xff; -- bfd_put_8 (abfd, diff_value, -+ diff_mask = 0x7f; -+ bfd_put_signed_8 (abfd, diff_value, - &contents[old_source_offset]); - break; - case R_XTENSA_DIFF16: -- diff_mask = 0xffff; -- bfd_put_16 (abfd, diff_value, -+ diff_mask = 0x7fff; -+ bfd_put_signed_16 (abfd, diff_value, - &contents[old_source_offset]); - break; - case R_XTENSA_DIFF32: -- diff_mask = 0xffffffff; -- bfd_put_32 (abfd, diff_value, -+ diff_mask = 0x7fffffff; -+ bfd_put_signed_32 (abfd, diff_value, - &contents[old_source_offset]); - break; - } - -- /* Check for overflow. */ -- if ((diff_value & ~diff_mask) != 0) -+ /* Check for overflow. Sign bits must be all zeroes or all ones */ -+ if ((diff_value & ~diff_mask) != 0 && -+ (diff_value & ~diff_mask) != (-1 & ~diff_mask)) - { - (*link_info->callbacks->reloc_dangerous) - (link_info, _("overflow after relaxation"), -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 58ace38..7547c0a0 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -+ fixP->fx_signed = 1; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -+ fixP->fx_signed = 1; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -+ fixP->fx_signed = 1; - break; - default: - break; --- -1.8.1.4 - diff --git a/patches/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch b/patches/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch deleted file mode 100644 index 6a0846e..0000000 --- a/patches/binutils/2.24/903-xtensa-fix-ld-segfault-when-linking-linux-modules.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Thu, 10 Jul 2014 01:47:33 +0400 -Subject: [PATCH] Fix xtensa ld segfault when linking linux modules - -is_inconsistent_linkonce_section makes an assumption that section name -that starts with ".gnu.linkonce.prop." has one more dot in its suffix. -However gas generates such section name by insertion of "prop." right -after ".gnu.linkonce." part of the name of the original section. So, for -section named ".gnu.linkonce.this_module" corresponding property section -name does not satisfy the assumption. Such section names are common in -linux modules. This bug was exposed by the patch "a35d5e8 Fix alignment -for the first section frag on xtensa", that makes gas produce property -section for each section that has ".align" directive in it. - -Use suffix that immediately follows ".gnu.linkonce.prop." when there are -no more dots following it. - -2014-07-10 Max Filippov - -ld/ - * emultempl/xtensaelf.em (is_inconsistent_linkonce_section): - correctly handle missing dot in section name after - ".gnu.linkonce.prop.". ---- -Backported from: e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 -Changes to ld/ChangeLog file are dropped. - - ld/emultempl/xtensaelf.em | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em -index 151eea4..948d18d 100644 ---- a/ld/emultempl/xtensaelf.em -+++ b/ld/emultempl/xtensaelf.em -@@ -1310,7 +1310,7 @@ is_inconsistent_linkonce_section (asection *sec) - for Tensilica's XCC compiler. */ - name = sec_name + linkonce_len; - if (CONST_STRNEQ (name, "prop.")) -- name = strchr (name + 5, '.') + 1; -+ name = strchr (name + 5, '.') ? strchr (name + 5, '.') + 1 : name + 5; - else if (name[1] == '.' - && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h')) - name += 2; --- -1.8.1.4 - diff --git a/patches/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch b/patches/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch deleted file mode 100644 index e4c600e..0000000 --- a/patches/binutils/2.24/904-Fix-call8-call-target-out-of-range-xtensa-ld-relaxation.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001 -From: Sterling Augustine -Date: Tue, 25 Jan 2011 13:59:13 -0800 -Subject: [PATCH] Fix 'call8: call target out of range' xtensa ld relaxation - bug - -During link-time relaxation distance between cross-section call site and -its target may grow, producing 'call target out of range' error for -relaxed calls. Be more conservative when calculating whether or not a -callx can be converted to a straight call. - -2014-09-23 Sterling Augustine - -bfd/ - * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section - call relaxation use furthermost addresses where call source and - destination can be to check whether it's in the range of a direct - call. - -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 41 +++++++++++++++++++++++++++++++++++++---- - 1 file changed, 37 insertions(+), 4 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 09862e3..e32496a 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -7124,10 +7124,43 @@ is_resolvable_asm_expansion (bfd *abfd, - || is_reloc_sym_weak (abfd, irel))) - return FALSE; - -- self_address = (sec->output_section->vma -- + sec->output_offset + irel->r_offset + 3); -- dest_address = (target_sec->output_section->vma -- + target_sec->output_offset + target_offset); -+ if (target_sec->output_section != sec->output_section) -+ { -+ /* If the two sections are sufficiently far away that relaxation -+ might take the call out of range, we can't simplify. For -+ example, a positive displacement call into another memory -+ could get moved to a lower address due to literal removal, -+ but the destination won't move, and so the displacment might -+ get larger. -+ -+ If the displacement is negative, assume the destination could -+ move as far back as the start of the output section. The -+ self_address will be at least as far into the output section -+ as it is prior to relaxation. -+ -+ If the displacement is postive, assume the destination will be in -+ it's pre-relaxed location (because relaxation only makes sections -+ smaller). The self_address could go all the way to the beginning -+ of the output section. */ -+ -+ dest_address = target_sec->output_section->vma; -+ self_address = sec->output_section->vma; -+ -+ if (sec->output_section->vma > target_sec->output_section->vma) -+ self_address += sec->output_offset + irel->r_offset + 3; -+ else -+ dest_address += bfd_get_section_limit (abfd, target_sec->output_section); -+ /* Call targets should be four-byte aligned. */ -+ dest_address = (dest_address + 3) & ~3; -+ } -+ else -+ { -+ -+ self_address = (sec->output_section->vma -+ + sec->output_offset + irel->r_offset + 3); -+ dest_address = (target_sec->output_section->vma -+ + target_sec->output_offset + target_offset); -+ } - - *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, - self_address, dest_address); --- -1.8.1.4 - diff --git a/patches/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch b/patches/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch deleted file mode 100644 index 8aeb064..0000000 --- a/patches/binutils/2.24/905-Fix-trampolines-search-code-for-conditional-branches.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 25 Nov 2014 21:33:21 +0300 -Subject: [PATCH] Fix trampolines search code for conditional branches - -For conditional branches that need more than one trampoline to reach its -target assembler couldn't always find suitable trampoline because -post-loop condition check was placed inside the loop, resulting in -premature loop termination. Move check outside the loop. - -This fixes the following build errors seen when assembling huge files -produced by gcc: - Error: jump target out of range; no usable trampoline found - Error: operand 1 of 'j' has out of range value '307307' - -2014-11-25 Max Filippov - -gas/ - * config/tc-xtensa.c (search_trampolines): Move post-loop - condition check outside the search loop. - -gas/testsuite/ - * gas/xtensa/trampoline.d: Add expected output for branches. - * gas/xtensa/trampoline.s: Add test case for branches. - -Signed-off-by: Max Filippov ---- -Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 -Changes to ChangeLogs are dropped. - - gas/config/tc-xtensa.c | 8 ++++---- - gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ - gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ - 3 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index d11b0c7..f23ccf8 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) - if (next_addr == 0 || addr - next_addr > J_RANGE) - break; - } -- if (abs (addr - this_addr) < J_RANGE) -- return tf; -- -- return NULL; - } -+ if (abs (addr - this_addr) < J_RANGE) -+ return tf; -+ -+ return NULL; - } - for ( ; tf; tf = tf->next) - { -diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d -index b4f65dc..5ae32a6 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.d -+++ b/gas/testsuite/gas/xtensa/trampoline.d -@@ -24,3 +24,12 @@ - .*33462:.*j.0x49407 - #... - .*49407:.*j.0x49407 -+.*4940a:.*beqz.n.a2,.0x4940f -+.*4940c:.*j.0x693d1 -+#... -+.*693d1:.*j.0x7ddd4 -+#... -+.*7ddd4:.*j.0x927f5 -+#... -+.*927f5:.*j.0x927f5 -+#... -diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s -index 259a3bb..4465786 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.s -+++ b/gas/testsuite/gas/xtensa/trampoline.s -@@ -19,3 +19,10 @@ - .endr - 3: - j 3b -+ bnez a2, 4f -+ .rep 50000 -+ and a2, a2, a3 -+ _ret -+ .endr -+4: -+ j 4b --- -1.8.1.4 - diff --git a/patches/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch b/patches/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch deleted file mode 100644 index 8a21100..0000000 --- a/patches/binutils/2.24/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch +++ /dev/null @@ -1,502 +0,0 @@ -From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Fri, 27 Mar 2015 07:13:55 +0300 -Subject: [PATCH 1/4] xtensa: optimize check_section_ebb_pcrels_fit - -The original check_section_ebb_pcrels_fit algorithm checks that text -actions proposed for current EBB are OK for every relocation in a -section. There's no need to check every relocation, because text actions -for EBB can only change size of that EBB, thus only affecting -relocations that in any way cross that EBB. In addition EBBs are -iterated in ascending order of their VMA, making it easier to track -relevant relocations. - -Introduce a structure that can track relocations that cross the range of -VMAs of EBB and use it to only check relocations relevant to current EBB -in check_section_ebb_pcrels_fit. -It takes O(N log N) operations to build it and O(N) operations to move -current EBB VMA window through its entire range, where N is the number -of relocations in a section. The resulting complexity of -compute_text_actions is thus reduced from O(N^2) to O(N log N + N * M), -where M is the average number of relocations crossing each EBB. - -Original profile: - -% time self children called name ------------------------------------------ - 44.26 71.53 6429/6429 compute_text_actions - 50.2 44.26 71.53 6429 check_section_ebb_pcrels_fit - 1.16 20.12 347506666/347576152 pcrel_reloc_fits - 2.95 16.52 347506666/348104944 get_relocation_opnd - 2.01 9.74 347575100/361252208 r_reloc_init - 0.55 7.53 347575100/363381467 r_reloc_get_section - 5.76 0.02 695013332/695013332 xlate_offset_with_removed_text - 0.68 3.89 347575100/363483827 bfd_octets_per_byte - 0.32 0.00 347506666/349910253 is_alt_relocation - 0.18 0.11 6391/6391 build_xlate_map - 0.00 0.00 6429/19417168 get_xtensa_relax_info - 0.00 0.00 6391/6391 free_xlate_map ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 2.56 3.08 6429/6429 compute_text_actions - 8.2 2.56 3.08 6429 check_section_ebb_pcrels_fit - 0.08 0.91 17721075/17790561 pcrel_reloc_fits - 0.17 0.47 17721075/31685977 r_reloc_init - 0.43 0.00 35442150/35442150 xlate_offset_with_removed_text - 0.02 0.37 17721075/33815236 r_reloc_get_section - 0.22 0.11 6391/6391 build_xlate_map - 0.05 0.22 17721075/33917596 bfd_octets_per_byte - 0.03 0.00 17721075/20405299 is_alt_relocation - 0.01 0.00 6429/6429 reloc_range_list_update_range - 0.00 0.00 6429/19417168 get_xtensa_relax_info - 0.00 0.00 6391/6391 free_xlate_map ------------------------------------------ - -2015-04-01 Max Filippov -bfd/ - * elf32-xtensa.c (reloc_range_list, reloc_range_list_entry, - reloc_range): new typedef. - (reloc_range_list_struct, reloc_range_list_entry_struct, - reloc_range_struct): new structures. - (reloc_range_compare, build_reloc_ranges, - reloc_range_list_append, reloc_range_list_remove, - reloc_range_list_update_range, free_reloc_range_list): new - functions. - (compute_text_actions): precompute relocation opcodes before the - loop. Add relevant_relocs variable, initialize it before the - loop, pass it to the check_section_ebb_pcrels_fit. - (check_section_ebb_pcrels_fit): add new parameter: - relevant_relocs. Update address range in the relevant_relocs if - it's non-NULL and iterate only over relevant relocations. - -Backported from: b2b326d246f839ee218192ac88da2384d929a072 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 298 insertions(+), 23 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 0b6f584..872370b 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -6619,8 +6619,10 @@ static bfd_boolean compute_text_actions - (bfd *, asection *, struct bfd_link_info *); - static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *); - static bfd_boolean compute_ebb_actions (ebb_constraint *); -+typedef struct reloc_range_list_struct reloc_range_list; - static bfd_boolean check_section_ebb_pcrels_fit -- (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *, -+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, -+ reloc_range_list *, const ebb_constraint *, - const xtensa_opcode *); - static bfd_boolean check_section_ebb_reduces (const ebb_constraint *); - static void text_action_add_proposed -@@ -7219,6 +7221,221 @@ build_reloc_opcodes (bfd *abfd, - return reloc_opcodes; - } - -+struct reloc_range_struct -+{ -+ bfd_vma addr; -+ bfd_boolean add; /* TRUE if start of a range, FALSE otherwise. */ -+ /* Original irel index in the array of relocations for a section. */ -+ unsigned irel_index; -+}; -+typedef struct reloc_range_struct reloc_range; -+ -+typedef struct reloc_range_list_entry_struct reloc_range_list_entry; -+struct reloc_range_list_entry_struct -+{ -+ reloc_range_list_entry *next; -+ reloc_range_list_entry *prev; -+ Elf_Internal_Rela *irel; -+ xtensa_opcode opcode; -+ int opnum; -+}; -+ -+struct reloc_range_list_struct -+{ -+ /* The rest of the structure is only meaningful when ok is TRUE. */ -+ bfd_boolean ok; -+ -+ unsigned n_range; /* Number of range markers. */ -+ reloc_range *range; /* Sorted range markers. */ -+ -+ unsigned first; /* Index of a first range element in the list. */ -+ unsigned last; /* One past index of a last range element in the list. */ -+ -+ unsigned n_list; /* Number of list elements. */ -+ reloc_range_list_entry *reloc; /* */ -+ reloc_range_list_entry list_root; -+}; -+ -+static int -+reloc_range_compare (const void *a, const void *b) -+{ -+ const reloc_range *ra = a; -+ const reloc_range *rb = b; -+ -+ if (ra->addr != rb->addr) -+ return ra->addr < rb->addr ? -1 : 1; -+ if (ra->add != rb->add) -+ return ra->add ? -1 : 1; -+ return 0; -+} -+ -+static void -+build_reloc_ranges (bfd *abfd, asection *sec, -+ bfd_byte *contents, -+ Elf_Internal_Rela *internal_relocs, -+ xtensa_opcode *reloc_opcodes, -+ reloc_range_list *list) -+{ -+ unsigned i; -+ size_t n = 0; -+ size_t max_n = 0; -+ reloc_range *ranges = NULL; -+ reloc_range_list_entry *reloc = -+ bfd_malloc (sec->reloc_count * sizeof (*reloc)); -+ -+ memset (list, 0, sizeof (*list)); -+ list->ok = TRUE; -+ -+ for (i = 0; i < sec->reloc_count; i++) -+ { -+ Elf_Internal_Rela *irel = &internal_relocs[i]; -+ int r_type = ELF32_R_TYPE (irel->r_info); -+ reloc_howto_type *howto = &elf_howto_table[r_type]; -+ r_reloc r_rel; -+ -+ if (r_type == R_XTENSA_ASM_SIMPLIFY -+ || r_type == R_XTENSA_32_PCREL -+ || !howto->pc_relative) -+ continue; -+ -+ r_reloc_init (&r_rel, abfd, irel, contents, -+ bfd_get_section_limit (abfd, sec)); -+ -+ if (r_reloc_get_section (&r_rel) != sec) -+ continue; -+ -+ if (n + 2 > max_n) -+ { -+ max_n = (max_n + 2) * 2; -+ ranges = bfd_realloc (ranges, max_n * sizeof (*ranges)); -+ } -+ -+ ranges[n].addr = irel->r_offset; -+ ranges[n + 1].addr = r_rel.target_offset; -+ -+ ranges[n].add = ranges[n].addr < ranges[n + 1].addr; -+ ranges[n + 1].add = !ranges[n].add; -+ -+ ranges[n].irel_index = i; -+ ranges[n + 1].irel_index = i; -+ -+ n += 2; -+ -+ reloc[i].irel = irel; -+ -+ /* Every relocation won't possibly be checked in the optimized version of -+ check_section_ebb_pcrels_fit, so this needs to be done here. */ -+ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) -+ { -+ /* None of the current alternate relocs are PC-relative, -+ and only PC-relative relocs matter here. */ -+ } -+ else -+ { -+ xtensa_opcode opcode; -+ int opnum; -+ -+ if (reloc_opcodes) -+ opcode = reloc_opcodes[i]; -+ else -+ opcode = get_relocation_opcode (abfd, sec, contents, irel); -+ -+ if (opcode == XTENSA_UNDEFINED) -+ { -+ list->ok = FALSE; -+ break; -+ } -+ -+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -+ if (opnum == XTENSA_UNDEFINED) -+ { -+ list->ok = FALSE; -+ break; -+ } -+ -+ /* Record relocation opcode and opnum as we've calculated them -+ anyway and they won't change. */ -+ reloc[i].opcode = opcode; -+ reloc[i].opnum = opnum; -+ } -+ } -+ -+ if (list->ok) -+ { -+ ranges = bfd_realloc (ranges, n * sizeof (*ranges)); -+ qsort (ranges, n, sizeof (*ranges), reloc_range_compare); -+ -+ list->n_range = n; -+ list->range = ranges; -+ list->reloc = reloc; -+ list->list_root.prev = &list->list_root; -+ list->list_root.next = &list->list_root; -+ } -+ else -+ { -+ free (ranges); -+ free (reloc); -+ } -+} -+ -+static void reloc_range_list_append (reloc_range_list *list, -+ unsigned irel_index) -+{ -+ reloc_range_list_entry *entry = list->reloc + irel_index; -+ -+ entry->prev = list->list_root.prev; -+ entry->next = &list->list_root; -+ entry->prev->next = entry; -+ entry->next->prev = entry; -+ ++list->n_list; -+} -+ -+static void reloc_range_list_remove (reloc_range_list *list, -+ unsigned irel_index) -+{ -+ reloc_range_list_entry *entry = list->reloc + irel_index; -+ -+ entry->next->prev = entry->prev; -+ entry->prev->next = entry->next; -+ --list->n_list; -+} -+ -+/* Update relocation list object so that it lists all relocations that cross -+ [first; last] range. Range bounds should not decrease with successive -+ invocations. */ -+static void reloc_range_list_update_range (reloc_range_list *list, -+ bfd_vma first, bfd_vma last) -+{ -+ /* This should not happen: EBBs are iterated from lower addresses to higher. -+ But even if that happens there's no need to break: just flush current list -+ and start from scratch. */ -+ if ((list->last > 0 && list->range[list->last - 1].addr > last) || -+ (list->first > 0 && list->range[list->first - 1].addr >= first)) -+ { -+ list->first = 0; -+ list->last = 0; -+ list->n_list = 0; -+ list->list_root.next = &list->list_root; -+ list->list_root.prev = &list->list_root; -+ fprintf (stderr, "%s: move backwards requested\n", __func__); -+ } -+ -+ for (; list->last < list->n_range && -+ list->range[list->last].addr <= last; ++list->last) -+ if (list->range[list->last].add) -+ reloc_range_list_append (list, list->range[list->last].irel_index); -+ -+ for (; list->first < list->n_range && -+ list->range[list->first].addr < first; ++list->first) -+ if (!list->range[list->first].add) -+ reloc_range_list_remove (list, list->range[list->first].irel_index); -+} -+ -+static void free_reloc_range_list (reloc_range_list *list) -+{ -+ free (list->range); -+ free (list->reloc); -+} - - /* The compute_text_actions function will build a list of potential - transformation actions for code in the extended basic block of each -@@ -7245,6 +7462,7 @@ compute_text_actions (bfd *abfd, - property_table_entry *prop_table = 0; - int ptblsize = 0; - bfd_size_type sec_size; -+ reloc_range_list relevant_relocs; - - relax_info = get_xtensa_relax_info (sec); - BFD_ASSERT (relax_info); -@@ -7277,6 +7495,12 @@ compute_text_actions (bfd *abfd, - goto error_return; - } - -+ /* Precompute the opcode for each relocation. */ -+ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs); -+ -+ build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes, -+ &relevant_relocs); -+ - for (i = 0; i < sec->reloc_count; i++) - { - Elf_Internal_Rela *irel = &internal_relocs[i]; -@@ -7340,17 +7564,13 @@ compute_text_actions (bfd *abfd, - ebb->start_reloc_idx = i; - ebb->end_reloc_idx = i; - -- /* Precompute the opcode for each relocation. */ -- if (reloc_opcodes == NULL) -- reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, -- internal_relocs); -- - if (!extend_ebb_bounds (ebb) - || !compute_ebb_proposed_actions (&ebb_table) - || !compute_ebb_actions (&ebb_table) - || !check_section_ebb_pcrels_fit (abfd, sec, contents, -- internal_relocs, &ebb_table, -- reloc_opcodes) -+ internal_relocs, -+ &relevant_relocs, -+ &ebb_table, reloc_opcodes) - || !check_section_ebb_reduces (&ebb_table)) - { - /* If anything goes wrong or we get unlucky and something does -@@ -7372,6 +7592,8 @@ compute_text_actions (bfd *abfd, - free_ebb_constraint (&ebb_table); - } - -+ free_reloc_range_list (&relevant_relocs); -+ - #if DEBUG - if (relax_info->action_list.head) - print_action_list (stderr, &relax_info->action_list); -@@ -7974,14 +8196,17 @@ check_section_ebb_pcrels_fit (bfd *abfd, - asection *sec, - bfd_byte *contents, - Elf_Internal_Rela *internal_relocs, -+ reloc_range_list *relevant_relocs, - const ebb_constraint *constraint, - const xtensa_opcode *reloc_opcodes) - { - unsigned i, j; -+ unsigned n = sec->reloc_count; - Elf_Internal_Rela *irel; - xlate_map_t *xmap = NULL; - bfd_boolean ok = TRUE; - xtensa_relax_info *relax_info; -+ reloc_range_list_entry *entry = NULL; - - relax_info = get_xtensa_relax_info (sec); - -@@ -7992,7 +8217,40 @@ check_section_ebb_pcrels_fit (bfd *abfd, - can still be used. */ - } - -- for (i = 0; i < sec->reloc_count; i++) -+ if (relevant_relocs && constraint->action_count) -+ { -+ if (!relevant_relocs->ok) -+ { -+ ok = FALSE; -+ n = 0; -+ } -+ else -+ { -+ bfd_vma min_offset, max_offset; -+ min_offset = max_offset = constraint->actions[0].offset; -+ -+ for (i = 1; i < constraint->action_count; ++i) -+ { -+ proposed_action *action = &constraint->actions[i]; -+ bfd_vma offset = action->offset; -+ -+ if (offset < min_offset) -+ min_offset = offset; -+ if (offset > max_offset) -+ max_offset = offset; -+ } -+ reloc_range_list_update_range (relevant_relocs, min_offset, -+ max_offset); -+ n = relevant_relocs->n_list; -+ entry = &relevant_relocs->list_root; -+ } -+ } -+ else -+ { -+ relevant_relocs = NULL; -+ } -+ -+ for (i = 0; i < n; i++) - { - r_reloc r_rel; - bfd_vma orig_self_offset, orig_target_offset; -@@ -8001,7 +8259,15 @@ check_section_ebb_pcrels_fit (bfd *abfd, - reloc_howto_type *howto; - int self_removed_bytes, target_removed_bytes; - -- irel = &internal_relocs[i]; -+ if (relevant_relocs) -+ { -+ entry = entry->next; -+ irel = entry->irel; -+ } -+ else -+ { -+ irel = internal_relocs + i; -+ } - r_type = ELF32_R_TYPE (irel->r_info); - - howto = &elf_howto_table[r_type]; -@@ -8067,21 +8333,30 @@ check_section_ebb_pcrels_fit (bfd *abfd, - xtensa_opcode opcode; - int opnum; - -- if (reloc_opcodes) -- opcode = reloc_opcodes[i]; -- else -- opcode = get_relocation_opcode (abfd, sec, contents, irel); -- if (opcode == XTENSA_UNDEFINED) -+ if (relevant_relocs) - { -- ok = FALSE; -- break; -+ opcode = entry->opcode; -+ opnum = entry->opnum; - } -- -- opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -- if (opnum == XTENSA_UNDEFINED) -+ else - { -- ok = FALSE; -- break; -+ if (reloc_opcodes) -+ opcode = reloc_opcodes[relevant_relocs ? -+ (unsigned)(entry - relevant_relocs->reloc) : i]; -+ else -+ opcode = get_relocation_opcode (abfd, sec, contents, irel); -+ if (opcode == XTENSA_UNDEFINED) -+ { -+ ok = FALSE; -+ break; -+ } -+ -+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -+ if (opnum == XTENSA_UNDEFINED) -+ { -+ ok = FALSE; -+ break; -+ } - } - - if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset)) -@@ -8778,7 +9053,7 @@ move_shared_literal (asection *sec, - /* Check all of the PC-relative relocations to make sure they still fit. */ - relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, - target_sec_cache->contents, -- target_sec_cache->relocs, -+ target_sec_cache->relocs, NULL, - &ebb_table, NULL); - - if (!relocs_fit) --- -1.8.1.4 - diff --git a/patches/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch b/patches/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch deleted file mode 100644 index 9df8065..0000000 --- a/patches/binutils/2.24/907-xtensa-optimize-removed_by_actions.patch +++ /dev/null @@ -1,356 +0,0 @@ -From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sat, 28 Mar 2015 08:46:28 +0300 -Subject: [PATCH 2/4] xtensa: optimize removed_by_actions - -The function removed_by_actions iterates through text actions to -calculate an offset applied by text actions to a given VMA. Although it -has a parameter p_start_action that allows for incremental offset -calculation, in many places it's used with p_start_action explicitly set -to the first action. After the first relaxation pass when the list of -text actions is finalized, an array of offsets sorted by VMA may be used -to speed up this function. - -Original profile: - -% time self children called name ------------------------------------------ - 0.35 0.00 33872/4808961 relax_section_symbols - 3.32 0.00 326022/4808961 relax_property_section - 12.83 0.00 1259379/4808961 offset_with_removed_text - 32.50 0.00 3189688/4808961 translate_reloc - 71.5 49.00 0.00 4808961 removed_by_actions ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 33872/4808537 relax_section_symbols - 0.01 0.00 326022/4808537 relax_property_section - 0.05 0.00 1258955/4808537 offset_with_removed_text_map - 0.13 0.00 3189688/4808537 translate_reloc - 1.0 0.20 0.00 4808537 removed_by_actions_map - 0.00 0.00 120/120 map_removal_by_action ------------------------------------------ - -2015-04-01 Max Filippov -bfd/ - * elf32-xtensa.c (removal_by_action_entry_struct, - removal_by_action_map_struct): new structures. - (removal_by_action_entry, removal_by_action_map): new typedefs. - (text_action_list_struct): add new field: map. - (map_removal_by_action, removed_by_actions_map, - offset_with_removed_text_map): new functions. - (relax_section): replace offset_with_removed_text with - offset_with_removed_text_map. - (translate_reloc, relax_property_section, relax_section_symbols): - replace removed_by_actions with removed_by_actions_map. - -Backported from: 071aa5c98a31c966f5fbfc573fcee61350fd1936 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 181 +++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 156 insertions(+), 25 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 872370b..21b2871 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -5420,11 +5420,28 @@ struct text_action_struct - text_action *next; - }; - -+struct removal_by_action_entry_struct -+{ -+ bfd_vma offset; -+ int removed; -+ int eq_removed; -+ int eq_removed_before_fill; -+}; -+typedef struct removal_by_action_entry_struct removal_by_action_entry; -+ -+struct removal_by_action_map_struct -+{ -+ unsigned n_entries; -+ removal_by_action_entry *entry; -+}; -+typedef struct removal_by_action_map_struct removal_by_action_map; -+ - - /* List of all of the actions taken on a text section. */ - struct text_action_list_struct - { - text_action *head; -+ removal_by_action_map map; - }; - - -@@ -5636,6 +5653,101 @@ action_list_count (text_action_list *action_list) - return count; - } - -+static void -+map_removal_by_action (text_action_list *action_list) -+{ -+ text_action *r; -+ int removed = 0; -+ removal_by_action_map map; -+ bfd_boolean eq_complete; -+ -+ map.n_entries = 0; -+ map.entry = bfd_malloc (action_list_count (action_list) * -+ sizeof (removal_by_action_entry)); -+ eq_complete = FALSE; -+ -+ for (r = action_list->head; r;) -+ { -+ removal_by_action_entry *ientry = map.entry + map.n_entries; -+ -+ if (map.n_entries && (ientry - 1)->offset == r->offset) -+ { -+ --ientry; -+ } -+ else -+ { -+ ++map.n_entries; -+ eq_complete = FALSE; -+ ientry->offset = r->offset; -+ ientry->eq_removed_before_fill = removed; -+ } -+ -+ if (!eq_complete) -+ { -+ if (r->action != ta_fill || r->removed_bytes >= 0) -+ { -+ ientry->eq_removed = removed; -+ eq_complete = TRUE; -+ } -+ else -+ ientry->eq_removed = removed + r->removed_bytes; -+ } -+ -+ removed += r->removed_bytes; -+ ientry->removed = removed; -+ r = r->next; -+ } -+ action_list->map = map; -+} -+ -+static int -+removed_by_actions_map (text_action_list *action_list, bfd_vma offset, -+ bfd_boolean before_fill) -+{ -+ unsigned a, b; -+ -+ if (!action_list->map.entry) -+ map_removal_by_action (action_list); -+ -+ if (!action_list->map.n_entries) -+ return 0; -+ -+ a = 0; -+ b = action_list->map.n_entries; -+ -+ while (b - a > 1) -+ { -+ unsigned c = (a + b) / 2; -+ -+ if (action_list->map.entry[c].offset <= offset) -+ a = c; -+ else -+ b = c; -+ } -+ -+ if (action_list->map.entry[a].offset < offset) -+ { -+ return action_list->map.entry[a].removed; -+ } -+ else if (action_list->map.entry[a].offset == offset) -+ { -+ return before_fill ? -+ action_list->map.entry[a].eq_removed_before_fill : -+ action_list->map.entry[a].eq_removed; -+ } -+ else -+ { -+ return 0; -+ } -+} -+ -+static bfd_vma -+offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) -+{ -+ int removed = removed_by_actions_map (action_list, offset, FALSE); -+ return offset - removed; -+} -+ - - /* The find_insn_action routine will only find non-fill actions. */ - -@@ -5909,6 +6021,9 @@ init_xtensa_relax_info (asection *sec) - - relax_info->action_list.head = NULL; - -+ relax_info->action_list.map.n_entries = 0; -+ relax_info->action_list.map.entry = NULL; -+ - relax_info->fix_list = NULL; - relax_info->fix_array = NULL; - relax_info->fix_array_count = 0; -@@ -9218,7 +9333,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - if (elf_hash_table (link_info)->dynamic_sections_created) - shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); - irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); -- irel->r_offset = offset_with_removed_text -+ irel->r_offset = offset_with_removed_text_map - (&relax_info->action_list, irel->r_offset); - continue; - } -@@ -9255,7 +9370,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - } - } - -- source_offset = offset_with_removed_text -+ source_offset = offset_with_removed_text_map - (&relax_info->action_list, irel->r_offset); - irel->r_offset = source_offset; - } -@@ -9352,7 +9467,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - break; - } - -- new_end_offset = offset_with_removed_text -+ new_end_offset = offset_with_removed_text_map - (&target_relax_info->action_list, - r_rel.target_offset + diff_value); - diff_value = new_end_offset - new_reloc.target_offset; -@@ -9750,7 +9865,6 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) - xtensa_relax_info *relax_info; - removed_literal *removed; - bfd_vma target_offset, base_offset; -- text_action *act; - - *new_rel = *orig_rel; - -@@ -9803,19 +9917,26 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) - offset. */ - - base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend; -- act = relax_info->action_list.head; - if (base_offset <= target_offset) - { -- int base_removed = removed_by_actions (&act, base_offset, FALSE); -- int addend_removed = removed_by_actions (&act, target_offset, FALSE); -+ int base_removed = removed_by_actions_map (&relax_info->action_list, -+ base_offset, FALSE); -+ int addend_removed = removed_by_actions_map (&relax_info->action_list, -+ target_offset, FALSE) - -+ base_removed; -+ - new_rel->target_offset = target_offset - base_removed - addend_removed; - new_rel->rela.r_addend -= addend_removed; - } - else - { - /* Handle a negative addend. The base offset comes first. */ -- int tgt_removed = removed_by_actions (&act, target_offset, FALSE); -- int addend_removed = removed_by_actions (&act, base_offset, FALSE); -+ int tgt_removed = removed_by_actions_map (&relax_info->action_list, -+ target_offset, FALSE); -+ int addend_removed = removed_by_actions_map (&relax_info->action_list, -+ base_offset, FALSE) - -+ tgt_removed; -+ - new_rel->target_offset = target_offset - tgt_removed; - new_rel->rela.r_addend += addend_removed; - } -@@ -10138,9 +10259,10 @@ relax_property_section (bfd *abfd, - bfd_vma old_offset = val.r_rel.target_offset; - bfd_vma new_offset; - long old_size, new_size; -- text_action *act = target_relax_info->action_list.head; -- new_offset = old_offset - -- removed_by_actions (&act, old_offset, FALSE); -+ int removed_by_old_offset = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset, FALSE); -+ new_offset = old_offset - removed_by_old_offset; - - /* Assert that we are not out of bounds. */ - old_size = bfd_get_32 (abfd, size_p); -@@ -10164,9 +10286,10 @@ relax_property_section (bfd *abfd, - - /* Recompute the new_offset, but this time don't - include any fill inserted by relaxation. */ -- act = target_relax_info->action_list.head; -- new_offset = old_offset - -- removed_by_actions (&act, old_offset, TRUE); -+ removed_by_old_offset = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset, TRUE); -+ new_offset = old_offset - removed_by_old_offset; - - /* If it is not unreachable and we have not yet - seen an unreachable at this address, place it -@@ -10182,8 +10305,12 @@ relax_property_section (bfd *abfd, - } - } - else -- new_size -= -- removed_by_actions (&act, old_offset + old_size, TRUE); -+ { -+ int removed_by_old_offset_size = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset + old_size, TRUE); -+ new_size -= removed_by_old_offset_size - removed_by_old_offset; -+ } - - if (new_size != old_size) - { -@@ -10441,14 +10568,16 @@ relax_section_symbols (bfd *abfd, asection *sec) - - if (isym->st_shndx == sec_shndx) - { -- text_action *act = relax_info->action_list.head; - bfd_vma orig_addr = isym->st_value; -+ int removed = removed_by_actions_map (&relax_info->action_list, -+ orig_addr, FALSE); - -- isym->st_value -= removed_by_actions (&act, orig_addr, FALSE); -- -+ isym->st_value -= removed; - if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) - isym->st_size -= -- removed_by_actions (&act, orig_addr + isym->st_size, FALSE); -+ removed_by_actions_map (&relax_info->action_list, -+ orig_addr + isym->st_size, FALSE) - -+ removed; - } - } - -@@ -10466,15 +10595,17 @@ relax_section_symbols (bfd *abfd, asection *sec) - || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec) - { -- text_action *act = relax_info->action_list.head; - bfd_vma orig_addr = sym_hash->root.u.def.value; -+ int removed = removed_by_actions_map (&relax_info->action_list, -+ orig_addr, FALSE); - -- sym_hash->root.u.def.value -= -- removed_by_actions (&act, orig_addr, FALSE); -+ sym_hash->root.u.def.value -= removed; - - if (sym_hash->type == STT_FUNC) - sym_hash->size -= -- removed_by_actions (&act, orig_addr + sym_hash->size, FALSE); -+ removed_by_actions_map (&relax_info->action_list, -+ orig_addr + sym_hash->size, FALSE) - -+ removed; - } - } - --- -1.8.1.4 - diff --git a/patches/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch b/patches/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch deleted file mode 100644 index 96d526f..0000000 --- a/patches/binutils/2.24/908-xtensa-optimize-find_removed_literal.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 288c2b709e5e6841484e1a129eaccd299db36877 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sat, 4 Apr 2015 14:49:42 +0300 -Subject: [PATCH 3/4] xtensa: optimize find_removed_literal - -find_removed_literal uses linear search to find removed literal by its -VMA. The list of literals is fixed at that point, build an ordered index -array and use binary search instead. - -Original profile: - -% time self children called name ------------------------------------------ - 56.72 0.00 297578/669392 translate_reloc - 70.86 0.00 371814/669392 relax_section - 67.9 127.58 0.00 669392 find_removed_literal ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 297578/669392 translate_reloc - 0.00 0.00 371814/669392 relax_section - 0.0 0.00 0.00 669392 find_removed_literal - 0.00 0.00 23838/23838 map_removed_literal ------------------------------------------ - -2015-04-03 Max Filippov -bfd/ - * elf32-xtensa.c (removed_literal_map_entry): new typedef. - (removed_literal_map_entry_struct): new structure. - (removed_literal_list_struct): add new fields: n_map and map. - (map_removed_literal, removed_literal_compare): new functions. - (find_removed_literal): build index array for literals ordered - by VMA, use binary search to find removed literal. - -Backported from: 3439c466273378021821473d3fc84990e089ae34 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 58 insertions(+), 6 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 21b2871..51733ad 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -5832,6 +5832,7 @@ print_action_list (FILE *fp, text_action_list *action_list) - by the "from" offset field. */ - - typedef struct removed_literal_struct removed_literal; -+typedef struct removed_literal_map_entry_struct removed_literal_map_entry; - typedef struct removed_literal_list_struct removed_literal_list; - - struct removed_literal_struct -@@ -5841,10 +5842,19 @@ struct removed_literal_struct - removed_literal *next; - }; - -+struct removed_literal_map_entry_struct -+{ -+ bfd_vma addr; -+ removed_literal *literal; -+}; -+ - struct removed_literal_list_struct - { - removed_literal *head; - removed_literal *tail; -+ -+ unsigned n_map; -+ removed_literal_map_entry *map; - }; - - -@@ -5893,6 +5903,39 @@ add_removed_literal (removed_literal_list *removed_list, - } - } - -+static void -+map_removed_literal (removed_literal_list *removed_list) -+{ -+ unsigned n_map = 0; -+ unsigned i; -+ removed_literal_map_entry *map = NULL; -+ removed_literal *r = removed_list->head; -+ -+ for (i = 0; r; ++i, r = r->next) -+ { -+ if (i == n_map) -+ { -+ n_map = (n_map * 2) + 2; -+ map = bfd_realloc (map, n_map * sizeof (*map)); -+ } -+ map[i].addr = r->from.target_offset; -+ map[i].literal = r; -+ } -+ removed_list->map = map; -+ removed_list->n_map = i; -+} -+ -+static int -+removed_literal_compare (const void *a, const void *b) -+{ -+ const removed_literal_map_entry *pa = a; -+ const removed_literal_map_entry *pb = b; -+ -+ if (pa->addr == pb->addr) -+ return 0; -+ else -+ return pa->addr < pb->addr ? -1 : 1; -+} - - /* Check if the list of removed literals contains an entry for the - given address. Return the entry if found. */ -@@ -5900,12 +5943,21 @@ add_removed_literal (removed_literal_list *removed_list, - static removed_literal * - find_removed_literal (removed_literal_list *removed_list, bfd_vma addr) - { -- removed_literal *r = removed_list->head; -- while (r && r->from.target_offset < addr) -- r = r->next; -- if (r && r->from.target_offset == addr) -- return r; -- return NULL; -+ removed_literal_map_entry *p; -+ removed_literal *r = NULL; -+ -+ if (removed_list->map == NULL) -+ map_removed_literal (removed_list); -+ -+ p = bsearch (&addr, removed_list->map, removed_list->n_map, -+ sizeof (*removed_list->map), removed_literal_compare); -+ if (p) -+ { -+ while (p != removed_list->map && (p - 1)->addr == addr) -+ --p; -+ r = p->literal; -+ } -+ return r; - } - - --- -1.8.1.4 - diff --git a/patches/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch b/patches/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch deleted file mode 100644 index 3090cc2..0000000 --- a/patches/binutils/2.24/909-xtensa-replace-action-list-with-splay-tree.patch +++ /dev/null @@ -1,826 +0,0 @@ -From e5409aedd3ee2192855018a564650ffb75c26e60 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sun, 5 Apr 2015 17:04:22 +0300 -Subject: [PATCH 4/4] xtensa: replace action list with splay tree - -text_action_add uses linear list search to order text actions list by -action VMA. The list is used at the first relaxation pass, when it's not -fixed yet. -Replace the list with splay tree from libiberty. - -Original profile: - -% time self children called name ------------------------------------------ - 0.00 0.00 14/158225 compute_text_actions - 3.62 0.00 25211/158225 remove_dead_literal - 8.42 0.00 58645/158225 coalesce_shared_literal - 10.68 0.00 74355/158225 text_action_add_proposed - 38.8 22.73 0.00 158225 text_action_add - 0.00 0.00 144527/293246 bfd_zmalloc ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 14/158225 compute_text_actions - 0.00 0.00 25211/158225 remove_dead_literal - 0.00 0.01 58645/158225 coalesce_shared_literal - 0.00 0.01 74355/158225 text_action_add_proposed - 0.1 0.00 0.02 158225 text_action_add - 0.01 0.00 144527/144527 splay_tree_insert - 0.00 0.00 144527/195130 splay_tree_lookup - 0.00 0.00 144527/293246 bfd_zmalloc ------------------------------------------ - -2015-04-03 Max Filippov -bfd/ - * elf32-xtensa.c (splay-tree.h): include header. - (text_action_struct): drop next pointer. - (text_action_list_struct): drop head pointer, add count and - tree fields. - (find_fill_action): instead of linear search in text_action_list - search in the tree. - (text_action_compare, action_first, action_next): new functions. - (text_action_add, text_action_add_literal): instead of linear - search and insertion insert new node into the tree. - (removed_by_actions): pass additional parameter: action_list, - use it to traverse the tree. - (offset_with_removed_text): pass additional action_list parameter - to removed_by_actions. - (map_action_fn_context): new typedef. - (map_action_fn_context_struct): new structure. - (map_action_fn): new function. - (map_removal_by_action): use splay_tree_foreach to build map. - (find_insn_action): replace linear search in text_action_list - with series of splay_tree_lookups. - (print_action, print_action_list_fn): new functions. - (print_action_list): use splay_tree_foreach. - (init_xtensa_relax_info): drop action_list.head initialization. - Initialize the tree. - (compute_text_actions): use non-zero action_list_count instead of - non-NULL action list. - (xlate_map_context): new typedef. - (xlate_map_context_struct): new structure. - (xlate_map_fn): new function. - (build_xlate_map): use splay_tree_foreach to build map. - (action_remove_bytes_fn): new function. - (relax_section): use zero action_list_count instead of NULL - action list. Use splay_tree_foreach to count final section size. - Drop unused variable 'removed'. - -Backported from: 4c2af04fe8b4452bf51d2debf1bb467fafcd0f08 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 488 +++++++++++++++++++++++++++++++---------------------- - 1 file changed, 282 insertions(+), 206 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 51733ad..53af1c6 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -28,6 +28,7 @@ - #include "libbfd.h" - #include "elf-bfd.h" - #include "elf/xtensa.h" -+#include "splay-tree.h" - #include "xtensa-isa.h" - #include "xtensa-config.h" - -@@ -5416,8 +5417,6 @@ struct text_action_struct - bfd_vma virtual_offset; /* Zero except for adding literals. */ - int removed_bytes; - literal_value value; /* Only valid when adding literals. */ -- -- text_action *next; - }; - - struct removal_by_action_entry_struct -@@ -5440,7 +5439,8 @@ typedef struct removal_by_action_map_struct removal_by_action_map; - /* List of all of the actions taken on a text section. */ - struct text_action_list_struct - { -- text_action *head; -+ unsigned count; -+ splay_tree tree; - removal_by_action_map map; - }; - -@@ -5448,20 +5448,18 @@ struct text_action_list_struct - static text_action * - find_fill_action (text_action_list *l, asection *sec, bfd_vma offset) - { -- text_action **m_p; -+ text_action a; - - /* It is not necessary to fill at the end of a section. */ - if (sec->size == offset) - return NULL; - -- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) -- { -- text_action *t = *m_p; -- /* When the action is another fill at the same address, -- just increase the size. */ -- if (t->offset == offset && t->action == ta_fill) -- return t; -- } -+ a.offset = offset; -+ a.action = ta_fill; -+ -+ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); -+ if (node) -+ return (text_action *)node->value; - return NULL; - } - -@@ -5509,6 +5507,49 @@ adjust_fill_action (text_action *ta, int fill_diff) - } - - -+static int -+text_action_compare (splay_tree_key a, splay_tree_key b) -+{ -+ text_action *pa = (text_action *)a; -+ text_action *pb = (text_action *)b; -+ static const int action_priority[] = -+ { -+ [ta_fill] = 0, -+ [ta_none] = 1, -+ [ta_convert_longcall] = 2, -+ [ta_narrow_insn] = 3, -+ [ta_remove_insn] = 4, -+ [ta_remove_longcall] = 5, -+ [ta_remove_literal] = 6, -+ [ta_widen_insn] = 7, -+ [ta_add_literal] = 8, -+ }; -+ -+ if (pa->offset == pb->offset) -+ { -+ if (pa->action == pb->action) -+ return 0; -+ return action_priority[pa->action] - action_priority[pb->action]; -+ } -+ else -+ return pa->offset < pb->offset ? -1 : 1; -+} -+ -+static text_action * -+action_first (text_action_list *action_list) -+{ -+ splay_tree_node node = splay_tree_min (action_list->tree); -+ return node ? (text_action *)node->value : NULL; -+} -+ -+static text_action * -+action_next (text_action_list *action_list, text_action *action) -+{ -+ splay_tree_node node = splay_tree_successor (action_list->tree, -+ (splay_tree_key)action); -+ return node ? (text_action *)node->value : NULL; -+} -+ - /* Add a modification action to the text. For the case of adding or - removing space, modify any current fill and assume that - "unreachable_space" bytes can be freely contracted. Note that a -@@ -5521,8 +5562,8 @@ text_action_add (text_action_list *l, - bfd_vma offset, - int removed) - { -- text_action **m_p; - text_action *ta; -+ text_action a; - - /* It is not necessary to fill at the end of a section. */ - if (action == ta_fill && sec->size == offset) -@@ -5532,34 +5573,30 @@ text_action_add (text_action_list *l, - if (action == ta_fill && removed == 0) - return; - -- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) -+ a.action = action; -+ a.offset = offset; -+ -+ if (action == ta_fill) - { -- text_action *t = *m_p; -+ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); - -- if (action == ta_fill) -+ if (node) - { -- /* When the action is another fill at the same address, -- just increase the size. */ -- if (t->offset == offset && t->action == ta_fill) -- { -- t->removed_bytes += removed; -- return; -- } -- /* Fills need to happen before widens so that we don't -- insert fill bytes into the instruction stream. */ -- if (t->offset == offset && t->action == ta_widen_insn) -- break; -+ ta = (text_action *)node->value; -+ ta->removed_bytes += removed; -+ return; - } - } -+ else -+ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&a) == NULL); - -- /* Create a new record and fill it up. */ - ta = (text_action *) bfd_zmalloc (sizeof (text_action)); - ta->action = action; - ta->sec = sec; - ta->offset = offset; - ta->removed_bytes = removed; -- ta->next = (*m_p); -- *m_p = ta; -+ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); -+ ++l->count; - } - - -@@ -5570,7 +5607,6 @@ text_action_add_literal (text_action_list *l, - const literal_value *value, - int removed) - { -- text_action **m_p; - text_action *ta; - asection *sec = r_reloc_get_section (loc); - bfd_vma offset = loc->target_offset; -@@ -5578,14 +5614,6 @@ text_action_add_literal (text_action_list *l, - - BFD_ASSERT (action == ta_add_literal); - -- for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next) -- { -- if ((*m_p)->offset > offset -- && ((*m_p)->offset != offset -- || (*m_p)->virtual_offset > virtual_offset)) -- break; -- } -- - /* Create a new record and fill it up. */ - ta = (text_action *) bfd_zmalloc (sizeof (text_action)); - ta->action = action; -@@ -5594,8 +5622,10 @@ text_action_add_literal (text_action_list *l, - ta->virtual_offset = virtual_offset; - ta->value = *value; - ta->removed_bytes = removed; -- ta->next = (*m_p); -- *m_p = ta; -+ -+ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) == NULL); -+ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); -+ ++l->count; - } - - -@@ -5606,7 +5636,8 @@ text_action_add_literal (text_action_list *l, - so that each search may begin where the previous one left off. */ - - static int --removed_by_actions (text_action **p_start_action, -+removed_by_actions (text_action_list *action_list, -+ text_action **p_start_action, - bfd_vma offset, - bfd_boolean before_fill) - { -@@ -5614,6 +5645,13 @@ removed_by_actions (text_action **p_start_action, - int removed = 0; - - r = *p_start_action; -+ if (r) -+ { -+ splay_tree_node node = splay_tree_lookup (action_list->tree, -+ (splay_tree_key)r); -+ BFD_ASSERT (node != NULL && r == (text_action *)node->value); -+ } -+ - while (r) - { - if (r->offset > offset) -@@ -5625,7 +5663,7 @@ removed_by_actions (text_action **p_start_action, - - removed += r->removed_bytes; - -- r = r->next; -+ r = action_next (action_list, r); - } - - *p_start_action = r; -@@ -5636,68 +5674,74 @@ removed_by_actions (text_action **p_start_action, - static bfd_vma - offset_with_removed_text (text_action_list *action_list, bfd_vma offset) - { -- text_action *r = action_list->head; -- return offset - removed_by_actions (&r, offset, FALSE); -+ text_action *r = action_first (action_list); -+ -+ return offset - removed_by_actions (action_list, &r, offset, FALSE); - } - - - static unsigned - action_list_count (text_action_list *action_list) - { -- text_action *r = action_list->head; -- unsigned count = 0; -- for (r = action_list->head; r != NULL; r = r->next) -- { -- count++; -- } -- return count; -+ return action_list->count; - } - --static void --map_removal_by_action (text_action_list *action_list) -+typedef struct map_action_fn_context_struct map_action_fn_context; -+struct map_action_fn_context_struct - { -- text_action *r; -- int removed = 0; -+ int removed; - removal_by_action_map map; - bfd_boolean eq_complete; -+}; - -- map.n_entries = 0; -- map.entry = bfd_malloc (action_list_count (action_list) * -- sizeof (removal_by_action_entry)); -- eq_complete = FALSE; -+static int -+map_action_fn (splay_tree_node node, void *p) -+{ -+ map_action_fn_context *ctx = p; -+ text_action *r = (text_action *)node->value; -+ removal_by_action_entry *ientry = ctx->map.entry + ctx->map.n_entries; - -- for (r = action_list->head; r;) -+ if (ctx->map.n_entries && (ientry - 1)->offset == r->offset) - { -- removal_by_action_entry *ientry = map.entry + map.n_entries; -+ --ientry; -+ } -+ else -+ { -+ ++ctx->map.n_entries; -+ ctx->eq_complete = FALSE; -+ ientry->offset = r->offset; -+ ientry->eq_removed_before_fill = ctx->removed; -+ } - -- if (map.n_entries && (ientry - 1)->offset == r->offset) -+ if (!ctx->eq_complete) -+ { -+ if (r->action != ta_fill || r->removed_bytes >= 0) - { -- --ientry; -+ ientry->eq_removed = ctx->removed; -+ ctx->eq_complete = TRUE; - } - else -- { -- ++map.n_entries; -- eq_complete = FALSE; -- ientry->offset = r->offset; -- ientry->eq_removed_before_fill = removed; -- } -+ ientry->eq_removed = ctx->removed + r->removed_bytes; -+ } - -- if (!eq_complete) -- { -- if (r->action != ta_fill || r->removed_bytes >= 0) -- { -- ientry->eq_removed = removed; -- eq_complete = TRUE; -- } -- else -- ientry->eq_removed = removed + r->removed_bytes; -- } -+ ctx->removed += r->removed_bytes; -+ ientry->removed = ctx->removed; -+ return 0; -+} - -- removed += r->removed_bytes; -- ientry->removed = removed; -- r = r->next; -- } -- action_list->map = map; -+static void -+map_removal_by_action (text_action_list *action_list) -+{ -+ map_action_fn_context ctx; -+ -+ ctx.removed = 0; -+ ctx.map.n_entries = 0; -+ ctx.map.entry = bfd_malloc (action_list_count (action_list) * -+ sizeof (removal_by_action_entry)); -+ ctx.eq_complete = FALSE; -+ -+ splay_tree_foreach (action_list->tree, map_action_fn, &ctx); -+ action_list->map = ctx.map; - } - - static int -@@ -5754,28 +5798,26 @@ offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) - static text_action * - find_insn_action (text_action_list *action_list, bfd_vma offset) - { -- text_action *t; -- for (t = action_list->head; t; t = t->next) -+ static const text_action_t action[] = - { -- if (t->offset == offset) -- { -- switch (t->action) -- { -- case ta_none: -- case ta_fill: -- break; -- case ta_remove_insn: -- case ta_remove_longcall: -- case ta_convert_longcall: -- case ta_narrow_insn: -- case ta_widen_insn: -- return t; -- case ta_remove_literal: -- case ta_add_literal: -- BFD_ASSERT (0); -- break; -- } -- } -+ ta_convert_longcall, -+ ta_remove_longcall, -+ ta_widen_insn, -+ ta_narrow_insn, -+ ta_remove_insn, -+ }; -+ text_action a; -+ unsigned i; -+ -+ a.offset = offset; -+ for (i = 0; i < sizeof (action) / sizeof (*action); ++i) -+ { -+ splay_tree_node node; -+ -+ a.action = action[i]; -+ node = splay_tree_lookup (action_list->tree, (splay_tree_key)&a); -+ if (node) -+ return (text_action *)node->value; - } - return NULL; - } -@@ -5784,40 +5826,50 @@ find_insn_action (text_action_list *action_list, bfd_vma offset) - #if DEBUG - - static void --print_action_list (FILE *fp, text_action_list *action_list) -+print_action (FILE *fp, text_action *r) -+{ -+ const char *t = "unknown"; -+ switch (r->action) -+ { -+ case ta_remove_insn: -+ t = "remove_insn"; break; -+ case ta_remove_longcall: -+ t = "remove_longcall"; break; -+ case ta_convert_longcall: -+ t = "convert_longcall"; break; -+ case ta_narrow_insn: -+ t = "narrow_insn"; break; -+ case ta_widen_insn: -+ t = "widen_insn"; break; -+ case ta_fill: -+ t = "fill"; break; -+ case ta_none: -+ t = "none"; break; -+ case ta_remove_literal: -+ t = "remove_literal"; break; -+ case ta_add_literal: -+ t = "add_literal"; break; -+ } -+ -+ fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", -+ r->sec->owner->filename, -+ r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); -+} -+ -+static int -+print_action_list_fn (splay_tree_node node, void *p) - { -- text_action *r; -+ text_action *r = (text_action *)node->value; - -- fprintf (fp, "Text Action\n"); -- for (r = action_list->head; r != NULL; r = r->next) -- { -- const char *t = "unknown"; -- switch (r->action) -- { -- case ta_remove_insn: -- t = "remove_insn"; break; -- case ta_remove_longcall: -- t = "remove_longcall"; break; -- case ta_convert_longcall: -- t = "convert_longcall"; break; -- case ta_narrow_insn: -- t = "narrow_insn"; break; -- case ta_widen_insn: -- t = "widen_insn"; break; -- case ta_fill: -- t = "fill"; break; -- case ta_none: -- t = "none"; break; -- case ta_remove_literal: -- t = "remove_literal"; break; -- case ta_add_literal: -- t = "add_literal"; break; -- } -+ print_action (p, r); -+ return 0; -+} - -- fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", -- r->sec->owner->filename, -- r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); -- } -+static void -+print_action_list (FILE *fp, text_action_list *action_list) -+{ -+ fprintf (fp, "Text Action\n"); -+ splay_tree_foreach (action_list->tree, print_action_list_fn, fp); - } - - #endif /* DEBUG */ -@@ -6071,8 +6123,8 @@ init_xtensa_relax_info (asection *sec) - relax_info->removed_list.head = NULL; - relax_info->removed_list.tail = NULL; - -- relax_info->action_list.head = NULL; -- -+ relax_info->action_list.tree = splay_tree_new (text_action_compare, -+ NULL, NULL); - relax_info->action_list.map.n_entries = 0; - relax_info->action_list.map.entry = NULL; - -@@ -7762,7 +7814,7 @@ compute_text_actions (bfd *abfd, - free_reloc_range_list (&relevant_relocs); - - #if DEBUG -- if (relax_info->action_list.head) -+ if (action_list_count (&relax_info->action_list)) - print_action_list (stderr, &relax_info->action_list); - #endif - -@@ -8263,6 +8315,54 @@ xlate_offset_with_removed_text (const xlate_map_t *map, - return e->new_address - e->orig_address + offset; - } - -+typedef struct xlate_map_context_struct xlate_map_context; -+struct xlate_map_context_struct -+{ -+ xlate_map_t *map; -+ xlate_map_entry_t *current_entry; -+ int removed; -+}; -+ -+static int -+xlate_map_fn (splay_tree_node node, void *p) -+{ -+ text_action *r = (text_action *)node->value; -+ xlate_map_context *ctx = p; -+ unsigned orig_size = 0; -+ -+ switch (r->action) -+ { -+ case ta_none: -+ case ta_remove_insn: -+ case ta_convert_longcall: -+ case ta_remove_literal: -+ case ta_add_literal: -+ break; -+ case ta_remove_longcall: -+ orig_size = 6; -+ break; -+ case ta_narrow_insn: -+ orig_size = 3; -+ break; -+ case ta_widen_insn: -+ orig_size = 2; -+ break; -+ case ta_fill: -+ break; -+ } -+ ctx->current_entry->size = -+ r->offset + orig_size - ctx->current_entry->orig_address; -+ if (ctx->current_entry->size != 0) -+ { -+ ctx->current_entry++; -+ ctx->map->entry_count++; -+ } -+ ctx->current_entry->orig_address = r->offset + orig_size; -+ ctx->removed += r->removed_bytes; -+ ctx->current_entry->new_address = r->offset + orig_size - ctx->removed; -+ ctx->current_entry->size = 0; -+ return 0; -+} - - /* Build a binary searchable offset translation map from a section's - action list. */ -@@ -8270,75 +8370,40 @@ xlate_offset_with_removed_text (const xlate_map_t *map, - static xlate_map_t * - build_xlate_map (asection *sec, xtensa_relax_info *relax_info) - { -- xlate_map_t *map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); - text_action_list *action_list = &relax_info->action_list; - unsigned num_actions = 0; -- text_action *r; -- int removed; -- xlate_map_entry_t *current_entry; -+ xlate_map_context ctx; - -- if (map == NULL) -+ ctx.map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); -+ -+ if (ctx.map == NULL) - return NULL; - - num_actions = action_list_count (action_list); -- map->entry = (xlate_map_entry_t *) -+ ctx.map->entry = (xlate_map_entry_t *) - bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1)); -- if (map->entry == NULL) -+ if (ctx.map->entry == NULL) - { -- free (map); -+ free (ctx.map); - return NULL; - } -- map->entry_count = 0; -+ ctx.map->entry_count = 0; - -- removed = 0; -- current_entry = &map->entry[0]; -+ ctx.removed = 0; -+ ctx.current_entry = &ctx.map->entry[0]; - -- current_entry->orig_address = 0; -- current_entry->new_address = 0; -- current_entry->size = 0; -+ ctx.current_entry->orig_address = 0; -+ ctx.current_entry->new_address = 0; -+ ctx.current_entry->size = 0; - -- for (r = action_list->head; r != NULL; r = r->next) -- { -- unsigned orig_size = 0; -- switch (r->action) -- { -- case ta_none: -- case ta_remove_insn: -- case ta_convert_longcall: -- case ta_remove_literal: -- case ta_add_literal: -- break; -- case ta_remove_longcall: -- orig_size = 6; -- break; -- case ta_narrow_insn: -- orig_size = 3; -- break; -- case ta_widen_insn: -- orig_size = 2; -- break; -- case ta_fill: -- break; -- } -- current_entry->size = -- r->offset + orig_size - current_entry->orig_address; -- if (current_entry->size != 0) -- { -- current_entry++; -- map->entry_count++; -- } -- current_entry->orig_address = r->offset + orig_size; -- removed += r->removed_bytes; -- current_entry->new_address = r->offset + orig_size - removed; -- current_entry->size = 0; -- } -+ splay_tree_foreach (action_list->tree, xlate_map_fn, &ctx); - -- current_entry->size = (bfd_get_section_limit (sec->owner, sec) -- - current_entry->orig_address); -- if (current_entry->size != 0) -- map->entry_count++; -+ ctx.current_entry->size = (bfd_get_section_limit (sec->owner, sec) -+ - ctx.current_entry->orig_address); -+ if (ctx.current_entry->size != 0) -+ ctx.map->entry_count++; - -- return map; -+ return ctx.map; - } - - -@@ -9302,6 +9367,16 @@ move_shared_literal (asection *sec, - - /* Second relaxation pass. */ - -+static int -+action_remove_bytes_fn (splay_tree_node node, void *p) -+{ -+ bfd_size_type *final_size = p; -+ text_action *action = (text_action *)node->value; -+ -+ *final_size -= action->removed_bytes; -+ return 0; -+} -+ - /* Modify all of the relocations to point to the right spot, and if this - is a relaxable section, delete the unwanted literals and fix the - section size. */ -@@ -9334,7 +9409,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - - internal_relocs = retrieve_internal_relocs (abfd, sec, - link_info->keep_memory); -- if (!internal_relocs && !relax_info->action_list.head) -+ if (!internal_relocs && !action_list_count (&relax_info->action_list)) - return TRUE; - - contents = retrieve_contents (abfd, sec, link_info->keep_memory); -@@ -9412,6 +9487,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - } - /* Update the action so that the code that moves - the contents will do the right thing. */ -+ /* ta_remove_longcall and ta_remove_insn actions are -+ grouped together in the tree as well as -+ ta_convert_longcall and ta_none, so that changes below -+ can be done w/o removing and reinserting action into -+ the tree. */ -+ - if (action->action == ta_remove_longcall) - action->action = ta_remove_insn; - else -@@ -9584,13 +9665,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - - if ((relax_info->is_relaxable_literal_section - || relax_info->is_relaxable_asm_section) -- && relax_info->action_list.head) -+ && action_list_count (&relax_info->action_list)) - { - /* Walk through the planned actions and build up a table - of move, copy and fill records. Use the move, copy and - fill records to perform the actions once. */ - -- int removed = 0; - bfd_size_type final_size, copy_size, orig_insn_size; - bfd_byte *scratch = NULL; - bfd_byte *dup_contents = NULL; -@@ -9601,15 +9681,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */ - bfd_vma dup_dot = 0; - -- text_action *action = relax_info->action_list.head; -+ text_action *action; - - final_size = sec->size; -- for (action = relax_info->action_list.head; action; -- action = action->next) -- { -- final_size -= action->removed_bytes; -- } - -+ splay_tree_foreach (relax_info->action_list.tree, -+ action_remove_bytes_fn, &final_size); - scratch = (bfd_byte *) bfd_zmalloc (final_size); - dup_contents = (bfd_byte *) bfd_zmalloc (final_size); - -@@ -9618,8 +9695,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - print_action_list (stderr, &relax_info->action_list); - #endif - -- for (action = relax_info->action_list.head; action; -- action = action->next) -+ for (action = action_first (&relax_info->action_list); action; -+ action = action_next (&relax_info->action_list, action)) - { - virtual_action = FALSE; - if (action->offset > orig_dot) -@@ -9748,7 +9825,6 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - break; - } - -- removed += action->removed_bytes; - BFD_ASSERT (dup_dot <= final_size); - BFD_ASSERT (orig_dot <= orig_size); - } --- -1.8.1.4 - diff --git a/patches/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch b/patches/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch deleted file mode 100644 index 043ff4d..0000000 --- a/patches/binutils/2.24/910-xtensa-optimize-trampolines-relaxation.patch +++ /dev/null @@ -1,345 +0,0 @@ -From cbe53e134d4c3a656880a906738ce19fdcd38e8b Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Fri, 1 May 2015 11:39:12 +0300 -Subject: [PATCH] xtensa: optimize trampolines relaxation - -Currently every fixup in the current segment is checked when relaxing -trampoline frag. This is very expensive. Make a searchable array of -fixups pointing at potentially oversized jumps at the beginning of every -relaxation pass and only check subset of this cache in the reach of -single jump from the trampoline frag currently being relaxed. - -Original profile: - -% time self children called name ------------------------------------------ - 370.16 593.38 12283048/12283048 relax_segment - 98.4 370.16 593.38 12283048 xtensa_relax_frag - 58.91 269.26 2691463834/2699602236 xtensa_insnbuf_from_chars - 68.35 68.17 811266668/813338977 S_GET_VALUE - 36.85 29.51 2684369246/2685538060 xtensa_opcode_decode - 28.34 8.84 2684369246/2685538060 xtensa_format_get_slot - 12.39 5.94 2691463834/2699775044 xtensa_format_decode - 0.03 4.60 4101109/4101109 relax_frag_for_align - 0.18 1.76 994617/994617 relax_frag_immed - 0.07 0.09 24556277/24851220 new_logical_line - 0.06 0.00 12283048/14067410 as_where - 0.04 0.00 7094588/15460506 xtensa_format_num_slots - 0.00 0.00 1/712477 xtensa_insnbuf_alloc ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.51 7.47 12283048/12283048 relax_segment - 58.0 0.51 7.47 12283048 xtensa_relax_frag - 0.02 4.08 4101109/4101109 relax_frag_for_align - 0.18 1.39 994617/994617 relax_frag_immed - 0.01 0.98 555/555 xtensa_cache_relaxable_fixups - 0.21 0.25 7094588/16693271 xtensa_insnbuf_from_chars - 0.06 0.12 24556277/24851220 new_logical_line - 0.06 0.00 7094588/15460506 xtensa_format_num_slots - 0.02 0.04 7094588/16866079 xtensa_format_decode - 0.05 0.00 12283048/14067410 as_where - 0.00 0.00 1/712477 xtensa_insnbuf_alloc - 0.00 0.00 93808/93808 xtensa_find_first_cached_fixup ------------------------------------------ - -2015-05-02 Max Filippov -gas/ - * config/tc-xtensa.c (cached_fixupS, fixup_cacheS): New typedefs. - (struct cached_fixup, struct fixup_cache): New structures. - (fixup_order, xtensa_make_cached_fixup), - (xtensa_realloc_fixup_cache, xtensa_cache_relaxable_fixups), - (xtensa_find_first_cached_fixup, xtensa_delete_cached_fixup), - (xtensa_add_cached_fixup): New functions. - (xtensa_relax_frag): Cache fixups pointing at potentially - oversized jumps at the beginning of every relaxation pass. Only - check subset of this cache in the reach of single jump from the - trampoline frag currently being relaxed. - -Signed-off-by: Max Filippov ---- -Backported from: b76f99d702c3501ac320396ea06bc7f9237173c3 -Changes to ChangeLog are dropped. - - gas/config/tc-xtensa.c | 220 +++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 194 insertions(+), 26 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 3e85b69..31c0b6b 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -8785,6 +8785,154 @@ static long relax_frag_for_align (fragS *, long); - static long relax_frag_immed - (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean); - -+typedef struct cached_fixup cached_fixupS; -+struct cached_fixup -+{ -+ int addr; -+ int target; -+ int delta; -+ fixS *fixP; -+}; -+ -+typedef struct fixup_cache fixup_cacheS; -+struct fixup_cache -+{ -+ cached_fixupS *fixups; -+ unsigned n_fixups; -+ unsigned n_max; -+ -+ segT seg; -+ fragS *first_frag; -+}; -+ -+static int fixup_order (const void *a, const void *b) -+{ -+ const cached_fixupS *pa = a; -+ const cached_fixupS *pb = b; -+ -+ if (pa->addr == pb->addr) -+ { -+ if (pa->target == pb->target) -+ { -+ if (pa->fixP->fx_r_type == pb->fixP->fx_r_type) -+ return 0; -+ return pa->fixP->fx_r_type < pb->fixP->fx_r_type ? -1 : 1; -+ } -+ return pa->target - pb->target; -+ } -+ return pa->addr - pb->addr; -+} -+ -+static bfd_boolean xtensa_make_cached_fixup (cached_fixupS *o, fixS *fixP) -+{ -+ xtensa_isa isa = xtensa_default_isa; -+ int addr = fixP->fx_frag->fr_address; -+ int target; -+ int delta; -+ symbolS *s = fixP->fx_addsy; -+ int slot; -+ xtensa_format fmt; -+ xtensa_opcode opcode; -+ -+ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -+ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -+ return FALSE; -+ target = S_GET_VALUE (s); -+ delta = target - addr; -+ -+ if (abs(delta) < J_RANGE / 2) -+ return FALSE; -+ -+ xtensa_insnbuf_from_chars (isa, trampoline_buf, -+ (unsigned char *) fixP->fx_frag->fr_literal + -+ fixP->fx_where, 0); -+ fmt = xtensa_format_decode (isa, trampoline_buf); -+ gas_assert (fmt != XTENSA_UNDEFINED); -+ slot = fixP->tc_fix_data.slot; -+ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -+ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -+ if (opcode != xtensa_j_opcode) -+ return FALSE; -+ -+ o->addr = addr; -+ o->target = target; -+ o->delta = delta; -+ o->fixP = fixP; -+ -+ return TRUE; -+} -+ -+static void xtensa_realloc_fixup_cache (fixup_cacheS *cache, unsigned add) -+{ -+ if (cache->n_fixups + add > cache->n_max) -+ { -+ cache->n_max = (cache->n_fixups + add) * 2; -+ cache->fixups = xrealloc (cache->fixups, -+ sizeof (*cache->fixups) * cache->n_max); -+ } -+} -+ -+static void xtensa_cache_relaxable_fixups (fixup_cacheS *cache, -+ segment_info_type *seginfo) -+{ -+ fixS *fixP; -+ -+ cache->n_fixups = 0; -+ -+ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ { -+ xtensa_realloc_fixup_cache (cache, 1); -+ -+ if (xtensa_make_cached_fixup (cache->fixups + cache->n_fixups, fixP)) -+ ++cache->n_fixups; -+ } -+ qsort (cache->fixups, cache->n_fixups, sizeof (*cache->fixups), fixup_order); -+} -+ -+static unsigned xtensa_find_first_cached_fixup (const fixup_cacheS *cache, -+ int addr) -+{ -+ unsigned a = 0; -+ unsigned b = cache->n_fixups; -+ -+ while (b - a > 1) -+ { -+ unsigned c = (a + b) / 2; -+ -+ if (cache->fixups[c].addr < addr) -+ a = c; -+ else -+ b = c; -+ } -+ return a; -+} -+ -+static void xtensa_delete_cached_fixup (fixup_cacheS *cache, unsigned i) -+{ -+ memmove (cache->fixups + i, cache->fixups + i + 1, -+ (cache->n_fixups - i - 1) * sizeof (*cache->fixups)); -+ --cache->n_fixups; -+} -+ -+static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP) -+{ -+ cached_fixupS o; -+ unsigned i; -+ -+ if (!xtensa_make_cached_fixup (&o, fixP)) -+ return FALSE; -+ xtensa_realloc_fixup_cache (cache, 1); -+ i = xtensa_find_first_cached_fixup (cache, o.addr); -+ if (i < cache->n_fixups) -+ { -+ ++i; -+ memmove (cache->fixups + i + 1, cache->fixups + i, -+ (cache->n_fixups - i) * sizeof (*cache->fixups)); -+ } -+ cache->fixups[i] = o; -+ ++cache->n_fixups; -+ return TRUE; -+} - - /* Return the number of bytes added to this fragment, given that the - input has been stretched already by "stretch". */ -@@ -8896,35 +9044,42 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - case RELAX_TRAMPOLINE: - if (fragP->tc_frag_data.relax_seen) - { -- segment_info_type *seginfo = seg_info (now_seg); -- fragS *fP; /* The out-of-range jump. */ -- fixS *fixP; -+ static fixup_cacheS fixup_cache; -+ segment_info_type *seginfo = seg_info (now_seg); -+ int trampaddr = fragP->fr_address + fragP->fr_fix; -+ int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE; -+ unsigned i; -+ -+ if (now_seg != fixup_cache.seg || -+ fragP == fixup_cache.first_frag || -+ fixup_cache.first_frag == NULL) -+ { -+ xtensa_cache_relaxable_fixups (&fixup_cache, seginfo); -+ fixup_cache.seg = now_seg; -+ fixup_cache.first_frag = fragP; -+ } - - /* Scan for jumps that will not reach. */ -- for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr); -+ i < fixup_cache.n_fixups; ++i) -+ - { -- symbolS *s = fixP->fx_addsy; -- xtensa_opcode opcode; -- int target; -- int addr; -- int delta; -- -- if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -- fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -- continue; -- xtensa_insnbuf_from_chars (isa, trampoline_buf, -- (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, -- 0); -- fmt = xtensa_format_decode (isa, trampoline_buf); -- gas_assert (fmt != XTENSA_UNDEFINED); -- slot = fixP->tc_fix_data.slot; -- xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -- opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -- if (opcode != xtensa_j_opcode) -+ fixS *fixP = fixup_cache.fixups[i].fixP; -+ int target = fixup_cache.fixups[i].target; -+ int addr = fixup_cache.fixups[i].addr; -+ int delta = fixup_cache.fixups[i].delta + stretch; -+ -+ trampaddr = fragP->fr_address + fragP->fr_fix; -+ -+ if (addr + J_RANGE < trampaddr) - continue; -- target = S_GET_VALUE (s); -- addr = fixP->fx_frag->fr_address; -- delta = target - addr + stretch; -+ if (addr > trampaddr + J_RANGE) -+ break; -+ if (abs (delta) < J_RANGE) -+ continue; -+ -+ slot = fixP->tc_fix_data.slot; -+ - if (delta > J_RANGE || delta < -1 * J_RANGE) - { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ - struct trampoline_seg *ts = find_trampoline_seg (now_seg); -@@ -8978,14 +9133,13 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - } - if (tf->fragP == fragP) - { -- int trampaddr = fragP->fr_address + fragP->fr_fix; -- - if (abs (addr - trampaddr) < J_RANGE) - { /* The trampoline is in range of original; fix it! */ - fixS *newfixP; - int offset; - TInsn insn; - symbolS *lsym; -+ fragS *fP; /* The out-of-range jump. */ - - new_stretch += init_trampoline_frag (tf); - offset = fragP->fr_fix; /* Where to assemble the j insn. */ -@@ -9009,10 +9163,20 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - newfixP->tc_fix_data.X_add_symbol = lsym; - newfixP->tc_fix_data.X_add_number = offset; - newfixP->tc_fix_data.slot = slot; -+ -+ xtensa_delete_cached_fixup (&fixup_cache, i); -+ xtensa_add_cached_fixup (&fixup_cache, newfixP); -+ - /* Move the fix-up from the original j insn to this one. */ - fixP->fx_frag = fragP; - fixP->fx_where = fragP->fr_fix - 3; - fixP->tc_fix_data.slot = 0; -+ -+ xtensa_add_cached_fixup (&fixup_cache, fixP); -+ -+ /* re-do current fixup */ -+ --i; -+ - /* Adjust the jump around this trampoline (if present). */ - if (tf->fixP != NULL) - { -@@ -9027,6 +9191,8 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - fragP->fr_subtype = 0; - /* Remove from the trampoline_list. */ - prev->next = tf->next; -+ if (fragP == fixup_cache.first_frag) -+ fixup_cache.first_frag = NULL; - break; - } - } --- -1.8.1.4 - diff --git a/patches/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/patches/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch deleted file mode 100644 index 9ad6b3b..0000000 --- a/patches/binutils/2.24/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Thu, 14 May 2015 05:22:55 +0300 -Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections - -elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were -made local, that results in link failure with the following message: - - BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line - 3372 in elf_xtensa_finish_dynamic_sections - -elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by -relocation type. Relocation types are not changed when symbol becomes -local, but its PLT references are added to GOT references and -plt.refcount is set to 0. Such symbol cannot be unreferences in the -elf_xtensa_gc_sweep_hook and its extra references make calculated GOT -relocations section size not match number of GOT relocations. - -Fix it by treating PLT reference as GOT reference when plt.refcount is -not positive. - -2015-05-14 Max Filippov -bfd/ - * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference - as GOT reference when plt.refcount is not positive. - -Signed-off-by: Max Filippov ---- -Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 -Changes to ChangeLog are dropped. - - bfd/elf32-xtensa.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 53af1c6..2523670 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, - { - if (is_plt) - { -+ /* If the symbol has been localized its plt.refcount got moved -+ to got.refcount. Handle it as GOT. */ - if (h->plt.refcount > 0) - h->plt.refcount--; -+ else -+ is_got = TRUE; - } -- else if (is_got) -+ if (is_got) - { - if (h->got.refcount > 0) - h->got.refcount--; --- -1.8.1.4 - diff --git a/patches/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/patches/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch deleted file mode 100644 index 4a3de2c..0000000 --- a/patches/binutils/2.24/912-xtensa-fix-gas-segfault-with-text-section-literals.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sun, 17 May 2015 06:46:15 +0300 -Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals - -When --text-section-literals is used and code in the .init or .fini -emits literal in the absence of .literal_position, xtensa_move_literals -segfaults. - -Check that search_frag is non-NULL in the xtensa_move_literals and -report error otherwise. - -2015-05-26 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Check that - search_frag is non-NULL. Report error if literal frag is not - found. - -Signed-off-by: Max Filippov ---- -Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 -Changes to ChangeLog are dropped. - - gas/config/tc-xtensa.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 31c0b6b..18307c1 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) - frchain_to = NULL; - frag_splice = &(frchain_from->frch_root); - -- while (!search_frag->tc_frag_data.literal_frag) -+ while (search_frag && !search_frag->tc_frag_data.literal_frag) - { - gas_assert (search_frag->fr_fix == 0 - || search_frag->fr_type == rs_align); - search_frag = search_frag->fr_next; - } - -+ if (!search_frag) -+ { -+ search_frag = frchain_from->frch_root; -+ as_bad_where (search_frag->fr_file, search_frag->fr_line, -+ _("literal pool location required for text-section-literals; specify with .literal_position")); -+ continue; -+ } -+ - gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype - == RELAX_LITERAL_POOL_BEGIN); - xtensa_switch_section_emit_state (&state, segment->seg, 0); --- -1.8.1.4 - diff --git a/patches/binutils/2.24/913-xtensa-add-auto-litpools-option.patch b/patches/binutils/2.24/913-xtensa-add-auto-litpools-option.patch deleted file mode 100644 index f0199e1..0000000 --- a/patches/binutils/2.24/913-xtensa-add-auto-litpools-option.patch +++ /dev/null @@ -1,698 +0,0 @@ -From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Wed, 29 Jul 2015 17:42:54 +0300 -Subject: [PATCH] xtensa: add --auto-litpools option - -Auto-litpools is the automated version of text-section-literals: literal -pool candidate frags are planted every N frags and during relaxation -they are turned into actual literal pools where literals are moved to -become reachable for their first reference by L32R instruction. - -2015-08-12 David Weatherford -gas/ - * config/tc-xtensa.c (struct litpool_frag, struct litpool_seg): - New structures. - (xtensa_maybe_create_literal_pool_frag): New function. - (litpool_seg_list, auto_litpools, auto_litpool_limit) - (litpool_buf, litpool_slotbuf): New static variables. - (option_auto_litpools, option_no_auto_litpools) - (option_auto_litpool_limit): New enum identifiers. - (md_longopts): Add entries for auto-litpools, no-auto-litpools - and auto-litpool-limit. - (md_parse_option): Handle option_auto_litpools, - option_no_auto_litpools and option_auto_litpool_limit. - (md_show_usage): Add help for --[no-]auto-litpools and - --auto-litpool-limit. - (xtensa_mark_literal_pool_location): Record a place for literal - pool with a call to xtensa_maybe_create_literal_pool_frag. - (get_literal_pool_location): Find highest priority literal pool - or convert candidate to literal pool when auto-litpools are used. - (xg_assemble_vliw_tokens): Create literal pool after jump - instruction. - (xtensa_check_frag_count): Create candidate literal pool every - auto_litpool_limit frags. - (xtensa_relax_frag): Add jump around literals to non-empty - literal pool. - (xtensa_move_literals): Estimate literal pool addresses and move - unreachable literals closer to their users, converting candidate - to literal pool if needed. - (xtensa_switch_to_non_abs_literal_fragment): Only emit error - about missing .literal_position in case auto-litpools are not - used. - * config/tc-xtensa.h (xtensa_relax_statesE): New relaxation - state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN. - -2015-08-12 Max Filippov -gas/testsuite/ - * gas/xtensa/all.exp: Add auto-litpools to the list of xtensa - tests. - * gas/xtensa/auto-litpools.s: New file: auto-litpools test. - * gas/xtensa/auto-litpools.s: New file: auto-litpools test - result pattern. - -Signed-off-by: Max Filippov ---- -Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5 -Changes to ChangeLogs and documentation are dropped. - - gas/config/tc-xtensa.c | 432 ++++++++++++++++++++++++++++++- - gas/config/tc-xtensa.h | 1 + - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/auto-litpools.d | 12 + - gas/testsuite/gas/xtensa/auto-litpools.s | 13 + - 5 files changed, 454 insertions(+), 5 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d - create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 7311a05..b8b1e7d 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -440,6 +440,29 @@ bfd_boolean directive_state[] = - #endif - }; - -+/* A circular list of all potential and actual literal pool locations -+ in a segment. */ -+struct litpool_frag -+{ -+ struct litpool_frag *next; -+ struct litpool_frag *prev; -+ fragS *fragP; -+ addressT addr; -+ short priority; /* 1, 2, or 3 -- 1 is highest */ -+ short original_priority; -+}; -+ -+/* Map a segment to its litpool_frag list. */ -+struct litpool_seg -+{ -+ struct litpool_seg *next; -+ asection *seg; -+ struct litpool_frag frag_list; -+ int frag_count; /* since last litpool location */ -+}; -+ -+static struct litpool_seg litpool_seg_list; -+ - - /* Directive functions. */ - -@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean); - static void xtensa_maybe_create_trampoline_frag (void); - struct trampoline_frag; - static int init_trampoline_frag (struct trampoline_frag *); -+static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean); -+static bfd_boolean auto_litpools = FALSE; -+static int auto_litpool_limit = 10000; - - /* Alignment Functions. */ - -@@ -698,6 +724,10 @@ enum - - option_trampolines, - option_no_trampolines, -+ -+ option_auto_litpools, -+ option_no_auto_litpools, -+ option_auto_litpool_limit, - }; - - const char *md_shortopts = ""; -@@ -773,6 +803,10 @@ struct option md_longopts[] = - { "trampolines", no_argument, NULL, option_trampolines }, - { "no-trampolines", no_argument, NULL, option_no_trampolines }, - -+ { "auto-litpools", no_argument, NULL, option_auto_litpools }, -+ { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools }, -+ { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit }, -+ - { NULL, no_argument, NULL, 0 } - }; - -@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg) - use_trampolines = FALSE; - return 1; - -+ case option_auto_litpools: -+ auto_litpools = TRUE; -+ use_literal_section = FALSE; -+ return 1; -+ -+ case option_no_auto_litpools: -+ auto_litpools = FALSE; -+ auto_litpool_limit = -1; -+ return 1; -+ -+ case option_auto_litpool_limit: -+ { -+ int value = 0; -+ if (auto_litpool_limit < 0) -+ as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit")); -+ if (*arg == 0 || *arg == '-') -+ as_fatal (_("invalid auto-litpool-limit argument")); -+ value = strtol (arg, &arg, 10); -+ if (*arg != 0) -+ as_fatal (_("invalid auto-litpool-limit argument")); -+ if (value < 100 || value > 10000) -+ as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)")); -+ auto_litpool_limit = value; -+ auto_litpools = TRUE; -+ use_literal_section = FALSE; -+ return 1; -+ } -+ - default: - return 0; - } -@@ -986,7 +1048,12 @@ Xtensa options:\n\ - flix bundles\n\ - --rename-section old=new Rename section 'old' to 'new'\n\ - --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ -- when jumps do not reach their targets\n", stream); -+ when jumps do not reach their targets\n\ -+ --[no-]auto-litpools [Do not] automatically create literal pools\n\ -+ --auto-litpool-limit=\n\ -+ (range 100-10000) Maximum number of blocks of\n\ -+ instructions to emit between literal pool\n\ -+ locations; implies --auto-litpools flag\n", stream); - } - - -@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void) - pool_location = frag_now; - frag_now->tc_frag_data.lit_frchain = frchain_now; - frag_now->tc_frag_data.literal_frag = frag_now; -+ /* Just record this frag. */ -+ xtensa_maybe_create_literal_pool_frag (FALSE, FALSE); - frag_variant (rs_machine_dependent, 0, 0, - RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL); - xtensa_set_frag_assembly_state (frag_now); -@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode) - static fragS * - get_literal_pool_location (segT seg) - { -+ struct litpool_seg *lps = litpool_seg_list.next; -+ struct litpool_frag *lpf; -+ for ( ; lps && lps->seg->id != seg->id; lps = lps->next) -+ ; -+ if (lps) -+ { -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { /* Skip "candidates" for now. */ -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && -+ lpf->priority == 1) -+ return lpf->fragP; -+ } -+ /* Must convert a lower-priority pool. */ -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) -+ return lpf->fragP; -+ } -+ /* Still no match -- try for a low priority pool. */ -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) -+ return lpf->fragP; -+ } -+ } - return seg_info (seg)->tc_segment_info_data.literal_pool_loc; - } - -@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol; - frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset; - frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag; -+ if (tinsn->opcode == xtensa_l32r_opcode) -+ { -+ frag_now->tc_frag_data.literal_frags[slot] = -+ tinsn->tok[1].X_add_symbol->sy_frag; -+ } - if (tinsn->literal_space != 0) - xg_assemble_literal_space (tinsn->literal_space, slot); - frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg; -@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - frag_now->fr_symbol, frag_now->fr_offset, NULL); - xtensa_set_frag_assembly_state (frag_now); - xtensa_maybe_create_trampoline_frag (); -+ /* Always create one here. */ -+ xtensa_maybe_create_literal_pool_frag (TRUE, FALSE); - } - else if (is_branch && do_align_targets ()) - { -@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void) - clear_frag_count (); - unreachable_count = 0; - } -+ -+ /* We create an area for a possible literal pool every N (default 5000) -+ frags or so. */ -+ xtensa_maybe_create_literal_pool_frag (TRUE, TRUE); - } - - static xtensa_insnbuf trampoline_buf = NULL; - static xtensa_insnbuf trampoline_slotbuf = NULL; - -+static xtensa_insnbuf litpool_buf = NULL; -+static xtensa_insnbuf litpool_slotbuf = NULL; -+ - #define TRAMPOLINE_FRAG_SIZE 3000 - - static void -@@ -7410,6 +7518,135 @@ dump_trampolines (void) - } - } - -+static void dump_litpools (void) __attribute__ ((unused)); -+ -+static void -+dump_litpools (void) -+{ -+ struct litpool_seg *lps = litpool_seg_list.next; -+ struct litpool_frag *lpf; -+ -+ for ( ; lps ; lps = lps->next ) -+ { -+ printf("litpool seg %s\n", lps->seg->name); -+ for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next ) -+ { -+ fragS *litfrag = lpf->fragP->fr_next; -+ int count = 0; -+ while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END) -+ { -+ if (litfrag->fr_fix == 4) -+ count++; -+ litfrag = litfrag->fr_next; -+ } -+ printf(" %ld <%d:%d> (%d) [%d]: ", -+ lpf->addr, lpf->priority, lpf->original_priority, -+ lpf->fragP->fr_line, count); -+ //dump_frag(lpf->fragP); -+ } -+ } -+} -+ -+static void -+xtensa_maybe_create_literal_pool_frag (bfd_boolean create, -+ bfd_boolean only_if_needed) -+{ -+ struct litpool_seg *lps = litpool_seg_list.next; -+ fragS *fragP; -+ struct litpool_frag *lpf; -+ bfd_boolean needed = FALSE; -+ -+ if (use_literal_section || !auto_litpools) -+ return; -+ -+ for ( ; lps ; lps = lps->next ) -+ { -+ if (lps->seg == now_seg) -+ break; -+ } -+ -+ if (lps == NULL) -+ { -+ lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1); -+ lps->next = litpool_seg_list.next; -+ litpool_seg_list.next = lps; -+ lps->seg = now_seg; -+ lps->frag_list.next = &lps->frag_list; -+ lps->frag_list.prev = &lps->frag_list; -+ } -+ -+ lps->frag_count++; -+ -+ if (create) -+ { -+ if (only_if_needed) -+ { -+ if (past_xtensa_end || !use_transform() || -+ frag_now->tc_frag_data.is_no_transform) -+ { -+ return; -+ } -+ if (auto_litpool_limit <= 0) -+ { -+ /* Don't create a litpool based only on frag count. */ -+ return; -+ } -+ else if (lps->frag_count > auto_litpool_limit) -+ { -+ needed = TRUE; -+ } -+ else -+ { -+ return; -+ } -+ } -+ else -+ { -+ needed = TRUE; -+ } -+ } -+ -+ if (needed) -+ { -+ int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn. */ -+ /* Create a potential site for a literal pool. */ -+ frag_wane (frag_now); -+ frag_new (0); -+ xtensa_set_frag_assembly_state (frag_now); -+ fragP = frag_now; -+ fragP->tc_frag_data.lit_frchain = frchain_now; -+ fragP->tc_frag_data.literal_frag = fragP; -+ frag_var (rs_machine_dependent, size, size, -+ (only_if_needed) ? -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN : -+ RELAX_LITERAL_POOL_BEGIN, -+ NULL, 0, NULL); -+ frag_now->tc_frag_data.lit_seg = now_seg; -+ frag_variant (rs_machine_dependent, 0, 0, -+ RELAX_LITERAL_POOL_END, NULL, 0, NULL); -+ xtensa_set_frag_assembly_state (frag_now); -+ } -+ else -+ { -+ /* RELAX_LITERAL_POOL_BEGIN frag is being created; -+ just record it here. */ -+ fragP = frag_now; -+ } -+ -+ lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag)); -+ /* Insert at tail of circular list. */ -+ lpf->addr = 0; -+ lps->frag_list.prev->next = lpf; -+ lpf->next = &lps->frag_list; -+ lpf->prev = lps->frag_list.prev; -+ lps->frag_list.prev = lpf; -+ lpf->fragP = fragP; -+ lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1; -+ lpf->original_priority = lpf->priority; -+ -+ lps->frag_count = 0; -+} -+ - static void - xtensa_cleanup_align_frags (void) - { -@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - break; - - case RELAX_LITERAL_POOL_BEGIN: -+ if (fragP->fr_var != 0) -+ { -+ /* We have a converted "candidate" literal pool; -+ assemble a jump around it. */ -+ TInsn insn; -+ if (!litpool_slotbuf) -+ { -+ litpool_buf = xtensa_insnbuf_alloc (isa); -+ litpool_slotbuf = xtensa_insnbuf_alloc (isa); -+ } -+ new_stretch += 3; -+ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ -+ fragP->tc_frag_data.is_insn = TRUE; -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol, -+ fragP->fr_fix); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf); -+ xtensa_insnbuf_to_chars (isa, litpool_buf, -+ (unsigned char *)fragP->fr_literal + -+ fragP->fr_fix, 3); -+ fragP->fr_fix += 3; -+ fragP->fr_var -= 3; -+ /* Add a fix-up. */ -+ fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE, -+ BFD_RELOC_XTENSA_SLOT0_OP); -+ } -+ break; -+ - case RELAX_LITERAL_POOL_END: -+ case RELAX_LITERAL_POOL_CANDIDATE_BEGIN: - case RELAX_MAYBE_UNREACHABLE: - case RELAX_MAYBE_DESIRE_ALIGN: - /* No relaxation required. */ -@@ -10789,12 +11060,115 @@ xtensa_move_literals (void) - segT dest_seg; - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; -+ struct litpool_seg *lps; - - mark_literal_frags (literal_head->next); - - if (use_literal_section) - return; - -+ /* Assign addresses (rough estimates) to the potential literal pool locations -+ and create new ones if the gaps are too large. */ -+ -+ for (lps = litpool_seg_list.next; lps; lps = lps->next) -+ { -+ frchainS *frchP = seg_info (lps->seg)->frchainP; -+ struct litpool_frag *lpf = lps->frag_list.next; -+ addressT addr = 0; -+ -+ for ( ; frchP; frchP = frchP->frch_next) -+ { -+ fragS *fragP; -+ for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next) -+ { -+ if (lpf && fragP == lpf->fragP) -+ { -+ gas_assert(fragP->fr_type == rs_machine_dependent && -+ (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN || -+ fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)); -+ /* Found a litpool location. */ -+ lpf->addr = addr; -+ lpf = lpf->next; -+ } -+ if (fragP->fr_type == rs_machine_dependent && -+ fragP->fr_subtype == RELAX_SLOTS) -+ { -+ int slot; -+ for (slot = 0; slot < MAX_SLOTS; slot++) -+ { -+ if (fragP->tc_frag_data.literal_frags[slot]) -+ { -+ /* L32R; point its literal to the nearest litpool -+ preferring non-"candidate" positions to avoid -+ the jump-around. */ -+ fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; -+ struct litpool_frag *lp = lpf->prev; -+ if (!lp->fragP) -+ { -+ break; -+ } -+ while (lp->fragP->fr_subtype == -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN) -+ { -+ lp = lp->prev; -+ if (lp->fragP == NULL) -+ { -+ /* End of list; have to bite the bullet. -+ Take the nearest. */ -+ lp = lpf->prev; -+ break; -+ } -+ /* Does it (conservatively) reach? */ -+ if (addr - lp->addr <= 128 * 1024) -+ { -+ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) -+ { -+ /* Found a good one. */ -+ break; -+ } -+ else if (lp->prev->fragP && -+ addr - lp->prev->addr > 128 * 1024) -+ { -+ /* This is still a "candidate" but the next one -+ will be too far away, so revert to the nearest -+ one, convert it and add the jump around. */ -+ fragS *poolbeg; -+ fragS *poolend; -+ symbolS *lsym; -+ char label[10 + 2 * sizeof (fragS *)]; -+ lp = lpf->prev; -+ poolbeg = lp->fragP; -+ lp->priority = 1; -+ poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; -+ poolend = poolbeg->fr_next; -+ gas_assert (poolend->fr_type == rs_machine_dependent && -+ poolend->fr_subtype == RELAX_LITERAL_POOL_END); -+ /* Create a local symbol pointing to the -+ end of the pool. */ -+ sprintf (label, ".L0_LT_%p", poolbeg); -+ lsym = (symbolS *)local_symbol_make (label, lps->seg, -+ 0, poolend); -+ poolbeg->fr_symbol = lsym; -+ /* Rest is done in xtensa_relax_frag. */ -+ } -+ } -+ } -+ if (! litfrag->tc_frag_data.literal_frag) -+ { -+ /* Take earliest use of this literal to avoid -+ forward refs. */ -+ litfrag->tc_frag_data.literal_frag = lp->fragP; -+ } -+ } -+ } -+ } -+ addr += fragP->fr_fix; -+ if (fragP->fr_type == rs_fill) -+ addr += fragP->fr_offset; -+ } -+ } -+ } -+ - for (segment = literal_head->next; segment; segment = segment->next) - { - /* Keep the literals for .init and .fini in separate sections. */ -@@ -10839,9 +11213,6 @@ xtensa_move_literals (void) - while (search_frag != frag_now) - { - next_frag = search_frag->fr_next; -- -- /* First, move the frag out of the literal section and -- to the appropriate place. */ - if (search_frag->tc_frag_data.literal_frag) - { - literal_pool = search_frag->tc_frag_data.literal_frag; -@@ -10849,8 +11220,56 @@ xtensa_move_literals (void) - frchain_to = literal_pool->tc_frag_data.lit_frchain; - gas_assert (frchain_to); - } -+ -+ if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0) -+ { -+ /* Skip empty fill frags. */ -+ *frag_splice = next_frag; -+ search_frag = next_frag; -+ continue; -+ } -+ -+ if (search_frag->fr_type == rs_align) -+ { -+ /* Skip alignment frags, because the pool as a whole will be -+ aligned if used, and we don't want to force alignment if the -+ pool is unused. */ -+ *frag_splice = next_frag; -+ search_frag = next_frag; -+ continue; -+ } -+ -+ /* First, move the frag out of the literal section and -+ to the appropriate place. */ -+ -+ /* Insert an aligmnent frag at start of pool. */ -+ if (literal_pool->fr_next->fr_type == rs_machine_dependent && -+ literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END) -+ { -+ segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg; -+ emit_state prev_state; -+ fragS *prev_frag; -+ fragS *align_frag; -+ xtensa_switch_section_emit_state (&prev_state, pool_seg, 0); -+ prev_frag = frag_now; -+ frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL); -+ align_frag = frag_now; -+ frag_align (2, 0, 0); -+ /* Splice it into the right place. */ -+ prev_frag->fr_next = align_frag->fr_next; -+ align_frag->fr_next = literal_pool->fr_next; -+ literal_pool->fr_next = align_frag; -+ /* Insert after this one. */ -+ literal_pool->tc_frag_data.literal_frag = align_frag; -+ xtensa_restore_emit_state (&prev_state); -+ } - insert_after = literal_pool->tc_frag_data.literal_frag; - dest_seg = insert_after->fr_next->tc_frag_data.lit_seg; -+ /* Skip align frag. */ -+ if (insert_after->fr_next->fr_type == rs_align) -+ { -+ insert_after = insert_after->fr_next; -+ } - - *frag_splice = next_frag; - search_frag->fr_next = insert_after->fr_next; -@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) - && !recursive - && !is_init && ! is_fini) - { -- as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); -+ if (!auto_litpools) -+ { -+ as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); -+ } - - /* When we mark a literal pool location, we want to put a frag in - the literal pool that points to it. But to do that, we want to -diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h -index b2e43fa..290d902 100644 ---- a/gas/config/tc-xtensa.h -+++ b/gas/config/tc-xtensa.h -@@ -124,6 +124,7 @@ enum xtensa_relax_statesE - - RELAX_LITERAL_POOL_BEGIN, - RELAX_LITERAL_POOL_END, -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN, - /* Technically these are not relaxations at all but mark a location - to store literals later. Note that fr_var stores the frchain for - BEGIN frags and fr_var stores now_seg for END frags. */ -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index d197ec8..db39629 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -100,5 +100,6 @@ if [istarget xtensa*-*-*] then { - run_dump_test "jlong" - run_dump_test "trampoline" -+ run_dump_test "auto-litpools" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d -new file mode 100644 -index 0000000..4d1a690 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/auto-litpools.d -@@ -0,0 +1,12 @@ -+#as: --auto-litpools -+#objdump: -d -+#name: auto literal pool placement -+ -+.*: +file format .*xtensa.* -+#... -+.*4:.*l32r.a2, 0 .* -+#... -+.*3e437:.*j.3e440 .* -+#... -+.*40750:.*l32r.a2, 3e43c .* -+#... -diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s -new file mode 100644 -index 0000000..9a5b26b ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/auto-litpools.s -@@ -0,0 +1,13 @@ -+ .text -+ .align 4 -+ .literal .L0, 0x12345 -+ .literal .L1, 0x12345 -+ -+f: -+ l32r a2, .L0 -+ .rep 44000 -+ _nop -+ _nop -+ .endr -+ l32r a2, .L1 -+ ret --- -1.8.1.4 - diff --git a/patches/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch b/patches/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch deleted file mode 100644 index 2955e11..0000000 --- a/patches/binutils/2.24/914-xtensa-fix-signedness-of-gas-relocations.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 2 Feb 2016 17:11:38 +0300 -Subject: [PATCH] xtensa: fix signedness of gas relocations - -Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation -offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations -substituted for BFD_RELOC_*. This made it impossible to encode arbitrary -8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc -directive. Revert this part and add test. - -gas/ -2016-02-03 Max Filippov - * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* - substitutions for BFD_RELOC_* as unsigned. - -Signed-off-by: Max Filippov ---- - gas/config/tc-xtensa.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index a119871..36a06cc 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - default: - break; --- -2.1.4 - diff --git a/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch deleted file mode 100644 index 656373f..0000000 --- a/patches/binutils/2.24/915-xtensa-fix-.init-.fini-literals-moving.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 16 Feb 2016 02:23:28 +0300 -Subject: [PATCH] xtensa: fix .init/.fini literals moving - -Despite the documentation and the comment in xtensa_move_literals, in -the presence of --text-section-literals and --auto-litpools literals are -moved from the separate literal sections into .init and .fini, because -the check in the xtensa_move_literals is incorrect. - -This moving was broken with introduction of auto litpools: some literals -now may be lost. This happens because literal frags emitted from .init -and .fini are not closed when new .literal_position marks new literal -pool. Then frag_align(2, 0, 0) changes type of the last literal frag to -rs_align. rs_align frags are skipped in the xtensa_move_literals. As a -result fixups against such literals are not moved out of .init.literal/ -.fini.literal sections producing the following assembler error: - - test.S: Warning: fixes not all moved from .init.literal - test.S: Internal error! - -Fix check for .init.literal/.fini.literal in the xtensa_move_literals -and don't let it move literals from there in the presence of ---text-section-literals or --auto-litpools. - -2016-02-17 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Fix check for - .init.literal/.fini.literal section name. - -Signed-off-by: Max Filippov ---- -Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 - - gas/config/tc-xtensa.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 36a06cc..5773634 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; - struct litpool_seg *lps; -+ const char *init_name = INIT_SECTION_NAME; -+ const char *fini_name = FINI_SECTION_NAME; -+ int init_name_len = strlen(init_name); -+ int fini_name_len = strlen(fini_name); - - mark_literal_frags (literal_head->next); - -@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) - - for (segment = literal_head->next; segment; segment = segment->next) - { -+ const char *seg_name = segment_name (segment->seg); -+ - /* Keep the literals for .init and .fini in separate sections. */ -- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) -- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) -+ if ((!memcmp (seg_name, init_name, init_name_len) && -+ !strcmp (seg_name + init_name_len, ".literal")) || -+ (!memcmp (seg_name, fini_name, fini_name_len) && -+ !strcmp (seg_name + fini_name_len, ".literal"))) - continue; - - frchain_from = seg_info (segment->seg)->frchainP; --- -2.1.4 - diff --git a/patches/binutils/2.25.1/120-sh-conf.patch b/patches/binutils/2.25.1/120-sh-conf.patch deleted file mode 100644 index c12a023..0000000 --- a/patches/binutils/2.25.1/120-sh-conf.patch +++ /dev/null @@ -1,33 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - -diff --git a/configure b/configure -index 87677bc..2d916f1 100755 ---- a/configure -+++ b/configure -@@ -3812,7 +3812,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; -diff --git a/configure.ac b/configure.ac -index 8fe0eca..b10a99f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1140,7 +1140,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.25.1/300-001_ld_makefile_patch.patch b/patches/binutils/2.25.1/300-001_ld_makefile_patch.patch deleted file mode 100644 index 2a1320c..0000000 --- a/patches/binutils/2.25.1/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/ld/Makefile.am b/ld/Makefile.am -index 9575f1f..84df0bf 100644 ---- a/ld/Makefile.am -+++ b/ld/Makefile.am -@@ -54,7 +54,7 @@ endif - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff --git a/ld/Makefile.in b/ld/Makefile.in -index 9f56ca1..272860f 100644 ---- a/ld/Makefile.in -+++ b/ld/Makefile.in -@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.25.1/300-012_check_ldrunpath_length.patch b/patches/binutils/2.25.1/300-012_check_ldrunpath_length.patch deleted file mode 100644 index f1f31af..0000000 --- a/patches/binutils/2.25.1/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em -index 137446f..bb8391a 100644 ---- a/ld/emultempl/elf32.em -+++ b/ld/emultempl/elf32.em -@@ -1195,6 +1195,8 @@ fragment <link.next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.25.1/310-fix-gold-pthreads-typo.patch b/patches/binutils/2.25.1/310-fix-gold-pthreads-typo.patch deleted file mode 100644 index f2e6ff2..0000000 --- a/patches/binutils/2.25.1/310-fix-gold-pthreads-typo.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 -@@ -102,9 +102,9 @@ - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); - #ifdef PTHREAD_MUTEX_ADAPTIVE_NP -- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); -+ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) -- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); -+ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); - #endif - - err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/patches/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/patches/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch deleted file mode 100644 index f9a8af6..0000000 --- a/patches/binutils/2.25.1/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2015-10-20 22:39:36.371169400 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:39:38.182772700 +0100 -@@ -101,7 +101,7 @@ - int err = pthread_mutexattr_init(&attr); - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); --#ifdef PTHREAD_MUTEX_ADAPTIVE_NP -+#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) - err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) - gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/patches/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch b/patches/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch deleted file mode 100644 index af4032a..0000000 --- a/patches/binutils/2.25.1/330-Dont-link-to-libfl-as-its-unnecessary.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff -urN binutils-2.25.1.orig/binutils/configure binutils-2.25.1/binutils/configure ---- binutils-2.25.1.orig/binutils/configure 2015-10-25 13:18:46.249052806 +0000 -+++ binutils-2.25.1/binutils/configure 2015-10-25 13:39:21.339034801 +0000 -@@ -12067,6 +12067,7 @@ - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12227,6 +12228,8 @@ - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" - # If we haven't got the data from the intl directory, -diff -urN binutils-2.25.1.orig/binutils/configure.ac binutils-2.25.1/binutils/configure.ac ---- binutils-2.25.1.orig/binutils/configure.ac 2015-10-25 13:18:46.249052806 +0000 -+++ binutils-2.25.1/binutils/configure.ac 2015-10-25 13:38:52.969035216 +0000 -@@ -87,7 +87,10 @@ - fi - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" - ZW_GNU_GETTEXT_SISTER_DIR -diff -urN binutils-2.25.1.orig/gas/configure binutils-2.25.1/gas/configure ---- binutils-2.25.1.orig/gas/configure 2015-10-25 13:18:46.389052803 +0000 -+++ binutils-2.25.1/gas/configure 2015-10-25 15:16:55.988949456 +0000 -@@ -12795,6 +12795,7 @@ - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12955,6 +12956,8 @@ - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja" - # If we haven't got the data from the intl directory, -diff -urN binutils-2.25.1.orig/gas/configure.ac binutils-2.25.1/gas/configure.ac ---- binutils-2.25.1.orig/gas/configure.ac 2015-10-25 15:15:06.000000000 +0000 -+++ binutils-2.25.1/gas/configure.ac 2015-10-25 14:45:32.000000000 +0000 -@@ -717,7 +717,10 @@ - AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja" - ZW_GNU_GETTEXT_SISTER_DIR -diff -urN binutils-2.25.1.orig/ld/configure binutils-2.25.1/ld/configure ---- binutils-2.25.1.orig/ld/configure 2015-10-25 13:18:47.399052788 +0000 -+++ binutils-2.25.1/ld/configure 2015-10-25 15:17:06.472282637 +0000 -@@ -16071,6 +16071,7 @@ - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -16231,6 +16232,8 @@ - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -diff -urN binutils-2.25.1.orig/ld/configure.ac binutils-2.25.1/ld/configure.ac ---- binutils-2.25.1.orig/ld/configure.ac 2015-10-25 13:18:47.415719456 +0000 -+++ binutils-2.25.1/ld/configure.ac 2015-10-25 15:14:43.000000000 +0000 -@@ -173,7 +173,10 @@ - AC_EXEEXT - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - AM_MAINTAINER_MODE - AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/patches/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/patches/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch deleted file mode 100644 index 33441cc..0000000 --- a/patches/binutils/2.25.1/340-Darwin-gold-binary-cc-include-string-not-cstring.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- binutils-2.25.orig/gold/binary.cc 2015-06-09 10:48:32.000000000 +0100 -+++ binutils-2.25/gold/binary.cc 2015-06-09 10:49:23.000000000 +0100 -@@ -23,7 +23,7 @@ - #include "gold.h" - - #include --#include -+#include - #include "safe-ctype.h" - - #include "elfcpp.h" diff --git a/patches/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/patches/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch deleted file mode 100644 index 6168b31..0000000 --- a/patches/binutils/2.25.1/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 -From: Andrew Hsieh -Date: Wed, 18 Mar 2015 10:57:24 +0800 -Subject: [PATCH] Fix darwin build - -1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 - doesn't support ended initializer list -2. wcsncasecmp doesn't exist in MacSDK10.6.x - -Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e ---- - binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ - binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- - 2 files changed, 34 insertions(+), 3 deletions(-) - -diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c -index 13e39e4..7a98306 100644 ---- binutils-2.25.orig/bfd/peXXigen.c -+++ binutils-2.25/bfd/peXXigen.c -@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) - } - #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ - -+#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L -+/* wcsncasecmp isn't always defined in Mac SDK */ -+static int -+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) -+{ -+ wchar_t c1, c2; -+ -+ if (n == 0) -+ return (0); -+ for (; *s1; s1++, s2++) -+ { -+ c1 = towlower(*s1); -+ c2 = towlower(*s2); -+ if (c1 != c2) -+ return ((int)c1 - c2); -+ if (--n == 0) -+ return (0); -+ } -+ return (-*s2); -+} -+#endif -+ - /* Perform a comparison of two entries. */ - static signed int - rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) -diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc -index ff5a8ac..45140e0 100644 ---- binutils-2.25.orig/gold/gold-threads.cc -+++ binutils-2.25/gold/gold-threads.cc -@@ -284,9 +284,18 @@ Condvar::~Condvar() - class Once_initialize - { - public: -- Once_initialize() -- : once_(PTHREAD_ONCE_INIT) -- { } -+ Once_initialize() -+#if !defined(__APPLE__) -+ : once_(PTHREAD_ONCE_INIT) -+ { } -+#else -+// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support -+// extended initializer list as above */ -+ { -+ pthread_once_t once_2 = PTHREAD_ONCE_INIT; -+ once_ = once_2; -+ } -+#endif - - // Return a pointer to the pthread_once_t variable. - pthread_once_t* --- -2.1.3 - diff --git a/patches/binutils/2.25.1/400-arm-rotate_left-fix.patch b/patches/binutils/2.25.1/400-arm-rotate_left-fix.patch deleted file mode 100644 index 4149597..0000000 --- a/patches/binutils/2.25.1/400-arm-rotate_left-fix.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d840c081f8082e8b9e63fead5306643975a97bb3 Mon Sep 17 00:00:00 2001 -From: Richard Earnshaw -Date: Thu, 20 Nov 2014 17:02:47 +0000 -Subject: [PATCH] * config/tc-arm.c (rotate_left): Avoid undefined behaviour - when N = 0. - ---- - gas/config/tc-arm.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletion(-) - -diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c -index 5077f87..9100fb2 100644 ---- a/gas/config/tc-arm.c -+++ b/gas/config/tc-arm.c -@@ -7251,7 +7251,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb) - - /* Functions for operand encoding. ARM, then Thumb. */ - --#define rotate_left(v, n) (v << n | v >> (32 - n)) -+#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31)) - - /* If VAL can be encoded in the immediate field of an ARM instruction, - return the encoded form. Otherwise, return FAIL. */ --- -1.9.4 - diff --git a/patches/binutils/2.25.1/500-sysroot.patch b/patches/binutils/2.25.1/500-sysroot.patch deleted file mode 100644 index e49c795..0000000 --- a/patches/binutils/2.25.1/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -308,18 +308,25 @@ - directory first. */ - if (! entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.25.1/600-poison-system-directories.patch b/patches/binutils/2.25.1/600-poison-system-directories.patch deleted file mode 100644 index ec3622b..0000000 --- a/patches/binutils/2.25.1/600-poison-system-directories.patch +++ /dev/null @@ -1,276 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -[Gustavo: adapt to binutils 2.25] -Signed-off-by: Thomas Petazzoni -Signed-off-by: Gustavo Zacarias - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.ac (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -diff -Nura a/ld/config.in b/ld/config.in ---- a/ld/config.in 2014-10-14 04:32:04.000000000 -0300 -+++ b/ld/config.in 2014-12-24 08:07:28.997918918 -0300 -@@ -11,6 +11,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -diff -Nura a/ld/configure b/ld/configure ---- a/ld/configure 2014-12-23 11:22:07.000000000 -0300 -+++ b/ld/configure 2014-12-24 08:07:29.002919088 -0300 -@@ -783,6 +783,7 @@ - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_werror -@@ -1439,6 +1440,8 @@ - --disable-largefile omit support for large files - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -15487,7 +15490,18 @@ - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -diff -Nura a/ld/configure.ac b/ld/configure.ac ---- a/ld/configure.ac 2014-10-14 04:32:04.000000000 -0300 -+++ b/ld/configure.ac 2014-12-24 08:07:29.002919088 -0300 -@@ -94,6 +94,16 @@ - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -diff -Nura a/ld/ldfile.c b/ld/ldfile.c ---- a/ld/ldfile.c 2014-10-14 04:32:04.000000000 -0300 -+++ b/ld/ldfile.c 2014-12-24 08:07:29.002919088 -0300 -@@ -114,6 +114,23 @@ - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -diff -Nura a/ld/ld.h b/ld/ld.h ---- a/ld/ld.h 2014-10-14 04:32:04.000000000 -0300 -+++ b/ld/ld.h 2014-12-24 08:07:29.003919122 -0300 -@@ -161,6 +161,14 @@ - /* If TRUE we'll just print the default output on stdout. */ - bfd_boolean print_output_format; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -diff -Nura a/ld/ldlex.h b/ld/ldlex.h ---- a/ld/ldlex.h 2014-11-04 06:54:41.000000000 -0300 -+++ b/ld/ldlex.h 2014-12-24 08:09:47.477644294 -0300 -@@ -140,6 +140,8 @@ - OPTION_IGNORE_UNRESOLVED_SYMBOL, - OPTION_PUSH_STATE, - OPTION_POP_STATE, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ -diff -Nura a/ld/ldmain.c b/ld/ldmain.c ---- a/ld/ldmain.c 2014-10-14 04:32:04.000000000 -0300 -+++ b/ld/ldmain.c 2014-12-24 08:07:29.003919122 -0300 -@@ -266,6 +266,8 @@ - command_line.warn_mismatch = TRUE; - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -diff -Nura a/ld/ld.texinfo b/ld/ld.texinfo ---- a/ld/ld.texinfo 2014-12-23 05:47:10.000000000 -0300 -+++ b/ld/ld.texinfo 2014-12-24 08:07:29.005919191 -0300 -@@ -2212,6 +2212,18 @@ - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -diff -Nura a/ld/lexsup.c b/ld/lexsup.c ---- a/ld/lexsup.c 2014-11-04 06:54:41.000000000 -0300 -+++ b/ld/lexsup.c 2014-12-24 08:48:50.136583414 -0300 -@@ -513,6 +513,14 @@ - { {"pop-state", no_argument, NULL, OPTION_POP_STATE}, - '\0', NULL, N_("Pop state of flags governing input file handling"), - TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -525,6 +533,7 @@ - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1458,6 +1467,14 @@ - } - break; - -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; -+ - case OPTION_PUSH_STATE: - input_flags.pushed = xmemdup (&input_flags, - sizeof (input_flags), -@@ -1483,6 +1500,10 @@ - command_line.soname = NULL; - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); diff --git a/patches/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch b/patches/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch deleted file mode 100644 index cea92f3..0000000 --- a/patches/binutils/2.25.1/700-Fix-library-paths-on-PowerPC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 -From: Alexey Neyman -Date: Sat, 11 Mar 2017 17:27:09 -0800 -Subject: [PATCH] Fix library paths on PowerPC - -First, need to match against just the CPU name, not the whole triplet. -Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin -triplet. - -Second, it should be testing for $target, not $host. Host may be -little endian by default, and the sysroot directory layout shouldn't -depend on whether it is built on LE or BE machine. - -Signed-off-by: Alexey Neyman ---- - ld/emulparams/elf32ppccommon.sh | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh -index 1f54ef8..d00cf68 100644 ---- a/ld/emulparams/elf32ppccommon.sh -+++ b/ld/emulparams/elf32ppccommon.sh -@@ -44,11 +44,11 @@ fi - - # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. - # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. --case "$host":"$EMULATION_NAME" in -- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; -- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; -- *le-*:*64*) LIBPATH_SUFFIX=64be ;; -- *le-*:*32*) LIBPATH_SUFFIX=32be ;; -+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in -+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; -+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; -+ *le:*64*) LIBPATH_SUFFIX=64be ;; -+ *le:*32*) LIBPATH_SUFFIX=32be ;; - *:*64lppc*) LIBPATH_SUFFIX=64le ;; - *:*32lppc*) LIBPATH_SUFFIX=32le ;; - *:*64*) LIBPATH_SUFFIX=64 ;; --- -2.9.3 - diff --git a/patches/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch b/patches/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch deleted file mode 100644 index 8aeb064..0000000 --- a/patches/binutils/2.25.1/905-Fix-trampolines-search-code-for-conditional-branches.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 25 Nov 2014 21:33:21 +0300 -Subject: [PATCH] Fix trampolines search code for conditional branches - -For conditional branches that need more than one trampoline to reach its -target assembler couldn't always find suitable trampoline because -post-loop condition check was placed inside the loop, resulting in -premature loop termination. Move check outside the loop. - -This fixes the following build errors seen when assembling huge files -produced by gcc: - Error: jump target out of range; no usable trampoline found - Error: operand 1 of 'j' has out of range value '307307' - -2014-11-25 Max Filippov - -gas/ - * config/tc-xtensa.c (search_trampolines): Move post-loop - condition check outside the search loop. - -gas/testsuite/ - * gas/xtensa/trampoline.d: Add expected output for branches. - * gas/xtensa/trampoline.s: Add test case for branches. - -Signed-off-by: Max Filippov ---- -Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3 -Changes to ChangeLogs are dropped. - - gas/config/tc-xtensa.c | 8 ++++---- - gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++ - gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++ - 3 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index d11b0c7..f23ccf8 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) - if (next_addr == 0 || addr - next_addr > J_RANGE) - break; - } -- if (abs (addr - this_addr) < J_RANGE) -- return tf; -- -- return NULL; - } -+ if (abs (addr - this_addr) < J_RANGE) -+ return tf; -+ -+ return NULL; - } - for ( ; tf; tf = tf->next) - { -diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d -index b4f65dc..5ae32a6 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.d -+++ b/gas/testsuite/gas/xtensa/trampoline.d -@@ -24,3 +24,12 @@ - .*33462:.*j.0x49407 - #... - .*49407:.*j.0x49407 -+.*4940a:.*beqz.n.a2,.0x4940f -+.*4940c:.*j.0x693d1 -+#... -+.*693d1:.*j.0x7ddd4 -+#... -+.*7ddd4:.*j.0x927f5 -+#... -+.*927f5:.*j.0x927f5 -+#... -diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s -index 259a3bb..4465786 100644 ---- a/gas/testsuite/gas/xtensa/trampoline.s -+++ b/gas/testsuite/gas/xtensa/trampoline.s -@@ -19,3 +19,10 @@ - .endr - 3: - j 3b -+ bnez a2, 4f -+ .rep 50000 -+ and a2, a2, a3 -+ _ret -+ .endr -+4: -+ j 4b --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch b/patches/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch deleted file mode 100644 index 8a21100..0000000 --- a/patches/binutils/2.25.1/906-xtensa-optimize-check_section_ebb_pcrels_fit.patch +++ /dev/null @@ -1,502 +0,0 @@ -From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Fri, 27 Mar 2015 07:13:55 +0300 -Subject: [PATCH 1/4] xtensa: optimize check_section_ebb_pcrels_fit - -The original check_section_ebb_pcrels_fit algorithm checks that text -actions proposed for current EBB are OK for every relocation in a -section. There's no need to check every relocation, because text actions -for EBB can only change size of that EBB, thus only affecting -relocations that in any way cross that EBB. In addition EBBs are -iterated in ascending order of their VMA, making it easier to track -relevant relocations. - -Introduce a structure that can track relocations that cross the range of -VMAs of EBB and use it to only check relocations relevant to current EBB -in check_section_ebb_pcrels_fit. -It takes O(N log N) operations to build it and O(N) operations to move -current EBB VMA window through its entire range, where N is the number -of relocations in a section. The resulting complexity of -compute_text_actions is thus reduced from O(N^2) to O(N log N + N * M), -where M is the average number of relocations crossing each EBB. - -Original profile: - -% time self children called name ------------------------------------------ - 44.26 71.53 6429/6429 compute_text_actions - 50.2 44.26 71.53 6429 check_section_ebb_pcrels_fit - 1.16 20.12 347506666/347576152 pcrel_reloc_fits - 2.95 16.52 347506666/348104944 get_relocation_opnd - 2.01 9.74 347575100/361252208 r_reloc_init - 0.55 7.53 347575100/363381467 r_reloc_get_section - 5.76 0.02 695013332/695013332 xlate_offset_with_removed_text - 0.68 3.89 347575100/363483827 bfd_octets_per_byte - 0.32 0.00 347506666/349910253 is_alt_relocation - 0.18 0.11 6391/6391 build_xlate_map - 0.00 0.00 6429/19417168 get_xtensa_relax_info - 0.00 0.00 6391/6391 free_xlate_map ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 2.56 3.08 6429/6429 compute_text_actions - 8.2 2.56 3.08 6429 check_section_ebb_pcrels_fit - 0.08 0.91 17721075/17790561 pcrel_reloc_fits - 0.17 0.47 17721075/31685977 r_reloc_init - 0.43 0.00 35442150/35442150 xlate_offset_with_removed_text - 0.02 0.37 17721075/33815236 r_reloc_get_section - 0.22 0.11 6391/6391 build_xlate_map - 0.05 0.22 17721075/33917596 bfd_octets_per_byte - 0.03 0.00 17721075/20405299 is_alt_relocation - 0.01 0.00 6429/6429 reloc_range_list_update_range - 0.00 0.00 6429/19417168 get_xtensa_relax_info - 0.00 0.00 6391/6391 free_xlate_map ------------------------------------------ - -2015-04-01 Max Filippov -bfd/ - * elf32-xtensa.c (reloc_range_list, reloc_range_list_entry, - reloc_range): new typedef. - (reloc_range_list_struct, reloc_range_list_entry_struct, - reloc_range_struct): new structures. - (reloc_range_compare, build_reloc_ranges, - reloc_range_list_append, reloc_range_list_remove, - reloc_range_list_update_range, free_reloc_range_list): new - functions. - (compute_text_actions): precompute relocation opcodes before the - loop. Add relevant_relocs variable, initialize it before the - loop, pass it to the check_section_ebb_pcrels_fit. - (check_section_ebb_pcrels_fit): add new parameter: - relevant_relocs. Update address range in the relevant_relocs if - it's non-NULL and iterate only over relevant relocations. - -Backported from: b2b326d246f839ee218192ac88da2384d929a072 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 298 insertions(+), 23 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 0b6f584..872370b 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -6619,8 +6619,10 @@ static bfd_boolean compute_text_actions - (bfd *, asection *, struct bfd_link_info *); - static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *); - static bfd_boolean compute_ebb_actions (ebb_constraint *); -+typedef struct reloc_range_list_struct reloc_range_list; - static bfd_boolean check_section_ebb_pcrels_fit -- (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *, -+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, -+ reloc_range_list *, const ebb_constraint *, - const xtensa_opcode *); - static bfd_boolean check_section_ebb_reduces (const ebb_constraint *); - static void text_action_add_proposed -@@ -7219,6 +7221,221 @@ build_reloc_opcodes (bfd *abfd, - return reloc_opcodes; - } - -+struct reloc_range_struct -+{ -+ bfd_vma addr; -+ bfd_boolean add; /* TRUE if start of a range, FALSE otherwise. */ -+ /* Original irel index in the array of relocations for a section. */ -+ unsigned irel_index; -+}; -+typedef struct reloc_range_struct reloc_range; -+ -+typedef struct reloc_range_list_entry_struct reloc_range_list_entry; -+struct reloc_range_list_entry_struct -+{ -+ reloc_range_list_entry *next; -+ reloc_range_list_entry *prev; -+ Elf_Internal_Rela *irel; -+ xtensa_opcode opcode; -+ int opnum; -+}; -+ -+struct reloc_range_list_struct -+{ -+ /* The rest of the structure is only meaningful when ok is TRUE. */ -+ bfd_boolean ok; -+ -+ unsigned n_range; /* Number of range markers. */ -+ reloc_range *range; /* Sorted range markers. */ -+ -+ unsigned first; /* Index of a first range element in the list. */ -+ unsigned last; /* One past index of a last range element in the list. */ -+ -+ unsigned n_list; /* Number of list elements. */ -+ reloc_range_list_entry *reloc; /* */ -+ reloc_range_list_entry list_root; -+}; -+ -+static int -+reloc_range_compare (const void *a, const void *b) -+{ -+ const reloc_range *ra = a; -+ const reloc_range *rb = b; -+ -+ if (ra->addr != rb->addr) -+ return ra->addr < rb->addr ? -1 : 1; -+ if (ra->add != rb->add) -+ return ra->add ? -1 : 1; -+ return 0; -+} -+ -+static void -+build_reloc_ranges (bfd *abfd, asection *sec, -+ bfd_byte *contents, -+ Elf_Internal_Rela *internal_relocs, -+ xtensa_opcode *reloc_opcodes, -+ reloc_range_list *list) -+{ -+ unsigned i; -+ size_t n = 0; -+ size_t max_n = 0; -+ reloc_range *ranges = NULL; -+ reloc_range_list_entry *reloc = -+ bfd_malloc (sec->reloc_count * sizeof (*reloc)); -+ -+ memset (list, 0, sizeof (*list)); -+ list->ok = TRUE; -+ -+ for (i = 0; i < sec->reloc_count; i++) -+ { -+ Elf_Internal_Rela *irel = &internal_relocs[i]; -+ int r_type = ELF32_R_TYPE (irel->r_info); -+ reloc_howto_type *howto = &elf_howto_table[r_type]; -+ r_reloc r_rel; -+ -+ if (r_type == R_XTENSA_ASM_SIMPLIFY -+ || r_type == R_XTENSA_32_PCREL -+ || !howto->pc_relative) -+ continue; -+ -+ r_reloc_init (&r_rel, abfd, irel, contents, -+ bfd_get_section_limit (abfd, sec)); -+ -+ if (r_reloc_get_section (&r_rel) != sec) -+ continue; -+ -+ if (n + 2 > max_n) -+ { -+ max_n = (max_n + 2) * 2; -+ ranges = bfd_realloc (ranges, max_n * sizeof (*ranges)); -+ } -+ -+ ranges[n].addr = irel->r_offset; -+ ranges[n + 1].addr = r_rel.target_offset; -+ -+ ranges[n].add = ranges[n].addr < ranges[n + 1].addr; -+ ranges[n + 1].add = !ranges[n].add; -+ -+ ranges[n].irel_index = i; -+ ranges[n + 1].irel_index = i; -+ -+ n += 2; -+ -+ reloc[i].irel = irel; -+ -+ /* Every relocation won't possibly be checked in the optimized version of -+ check_section_ebb_pcrels_fit, so this needs to be done here. */ -+ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) -+ { -+ /* None of the current alternate relocs are PC-relative, -+ and only PC-relative relocs matter here. */ -+ } -+ else -+ { -+ xtensa_opcode opcode; -+ int opnum; -+ -+ if (reloc_opcodes) -+ opcode = reloc_opcodes[i]; -+ else -+ opcode = get_relocation_opcode (abfd, sec, contents, irel); -+ -+ if (opcode == XTENSA_UNDEFINED) -+ { -+ list->ok = FALSE; -+ break; -+ } -+ -+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -+ if (opnum == XTENSA_UNDEFINED) -+ { -+ list->ok = FALSE; -+ break; -+ } -+ -+ /* Record relocation opcode and opnum as we've calculated them -+ anyway and they won't change. */ -+ reloc[i].opcode = opcode; -+ reloc[i].opnum = opnum; -+ } -+ } -+ -+ if (list->ok) -+ { -+ ranges = bfd_realloc (ranges, n * sizeof (*ranges)); -+ qsort (ranges, n, sizeof (*ranges), reloc_range_compare); -+ -+ list->n_range = n; -+ list->range = ranges; -+ list->reloc = reloc; -+ list->list_root.prev = &list->list_root; -+ list->list_root.next = &list->list_root; -+ } -+ else -+ { -+ free (ranges); -+ free (reloc); -+ } -+} -+ -+static void reloc_range_list_append (reloc_range_list *list, -+ unsigned irel_index) -+{ -+ reloc_range_list_entry *entry = list->reloc + irel_index; -+ -+ entry->prev = list->list_root.prev; -+ entry->next = &list->list_root; -+ entry->prev->next = entry; -+ entry->next->prev = entry; -+ ++list->n_list; -+} -+ -+static void reloc_range_list_remove (reloc_range_list *list, -+ unsigned irel_index) -+{ -+ reloc_range_list_entry *entry = list->reloc + irel_index; -+ -+ entry->next->prev = entry->prev; -+ entry->prev->next = entry->next; -+ --list->n_list; -+} -+ -+/* Update relocation list object so that it lists all relocations that cross -+ [first; last] range. Range bounds should not decrease with successive -+ invocations. */ -+static void reloc_range_list_update_range (reloc_range_list *list, -+ bfd_vma first, bfd_vma last) -+{ -+ /* This should not happen: EBBs are iterated from lower addresses to higher. -+ But even if that happens there's no need to break: just flush current list -+ and start from scratch. */ -+ if ((list->last > 0 && list->range[list->last - 1].addr > last) || -+ (list->first > 0 && list->range[list->first - 1].addr >= first)) -+ { -+ list->first = 0; -+ list->last = 0; -+ list->n_list = 0; -+ list->list_root.next = &list->list_root; -+ list->list_root.prev = &list->list_root; -+ fprintf (stderr, "%s: move backwards requested\n", __func__); -+ } -+ -+ for (; list->last < list->n_range && -+ list->range[list->last].addr <= last; ++list->last) -+ if (list->range[list->last].add) -+ reloc_range_list_append (list, list->range[list->last].irel_index); -+ -+ for (; list->first < list->n_range && -+ list->range[list->first].addr < first; ++list->first) -+ if (!list->range[list->first].add) -+ reloc_range_list_remove (list, list->range[list->first].irel_index); -+} -+ -+static void free_reloc_range_list (reloc_range_list *list) -+{ -+ free (list->range); -+ free (list->reloc); -+} - - /* The compute_text_actions function will build a list of potential - transformation actions for code in the extended basic block of each -@@ -7245,6 +7462,7 @@ compute_text_actions (bfd *abfd, - property_table_entry *prop_table = 0; - int ptblsize = 0; - bfd_size_type sec_size; -+ reloc_range_list relevant_relocs; - - relax_info = get_xtensa_relax_info (sec); - BFD_ASSERT (relax_info); -@@ -7277,6 +7495,12 @@ compute_text_actions (bfd *abfd, - goto error_return; - } - -+ /* Precompute the opcode for each relocation. */ -+ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs); -+ -+ build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes, -+ &relevant_relocs); -+ - for (i = 0; i < sec->reloc_count; i++) - { - Elf_Internal_Rela *irel = &internal_relocs[i]; -@@ -7340,17 +7564,13 @@ compute_text_actions (bfd *abfd, - ebb->start_reloc_idx = i; - ebb->end_reloc_idx = i; - -- /* Precompute the opcode for each relocation. */ -- if (reloc_opcodes == NULL) -- reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, -- internal_relocs); -- - if (!extend_ebb_bounds (ebb) - || !compute_ebb_proposed_actions (&ebb_table) - || !compute_ebb_actions (&ebb_table) - || !check_section_ebb_pcrels_fit (abfd, sec, contents, -- internal_relocs, &ebb_table, -- reloc_opcodes) -+ internal_relocs, -+ &relevant_relocs, -+ &ebb_table, reloc_opcodes) - || !check_section_ebb_reduces (&ebb_table)) - { - /* If anything goes wrong or we get unlucky and something does -@@ -7372,6 +7592,8 @@ compute_text_actions (bfd *abfd, - free_ebb_constraint (&ebb_table); - } - -+ free_reloc_range_list (&relevant_relocs); -+ - #if DEBUG - if (relax_info->action_list.head) - print_action_list (stderr, &relax_info->action_list); -@@ -7974,14 +8196,17 @@ check_section_ebb_pcrels_fit (bfd *abfd, - asection *sec, - bfd_byte *contents, - Elf_Internal_Rela *internal_relocs, -+ reloc_range_list *relevant_relocs, - const ebb_constraint *constraint, - const xtensa_opcode *reloc_opcodes) - { - unsigned i, j; -+ unsigned n = sec->reloc_count; - Elf_Internal_Rela *irel; - xlate_map_t *xmap = NULL; - bfd_boolean ok = TRUE; - xtensa_relax_info *relax_info; -+ reloc_range_list_entry *entry = NULL; - - relax_info = get_xtensa_relax_info (sec); - -@@ -7992,7 +8217,40 @@ check_section_ebb_pcrels_fit (bfd *abfd, - can still be used. */ - } - -- for (i = 0; i < sec->reloc_count; i++) -+ if (relevant_relocs && constraint->action_count) -+ { -+ if (!relevant_relocs->ok) -+ { -+ ok = FALSE; -+ n = 0; -+ } -+ else -+ { -+ bfd_vma min_offset, max_offset; -+ min_offset = max_offset = constraint->actions[0].offset; -+ -+ for (i = 1; i < constraint->action_count; ++i) -+ { -+ proposed_action *action = &constraint->actions[i]; -+ bfd_vma offset = action->offset; -+ -+ if (offset < min_offset) -+ min_offset = offset; -+ if (offset > max_offset) -+ max_offset = offset; -+ } -+ reloc_range_list_update_range (relevant_relocs, min_offset, -+ max_offset); -+ n = relevant_relocs->n_list; -+ entry = &relevant_relocs->list_root; -+ } -+ } -+ else -+ { -+ relevant_relocs = NULL; -+ } -+ -+ for (i = 0; i < n; i++) - { - r_reloc r_rel; - bfd_vma orig_self_offset, orig_target_offset; -@@ -8001,7 +8259,15 @@ check_section_ebb_pcrels_fit (bfd *abfd, - reloc_howto_type *howto; - int self_removed_bytes, target_removed_bytes; - -- irel = &internal_relocs[i]; -+ if (relevant_relocs) -+ { -+ entry = entry->next; -+ irel = entry->irel; -+ } -+ else -+ { -+ irel = internal_relocs + i; -+ } - r_type = ELF32_R_TYPE (irel->r_info); - - howto = &elf_howto_table[r_type]; -@@ -8067,21 +8333,30 @@ check_section_ebb_pcrels_fit (bfd *abfd, - xtensa_opcode opcode; - int opnum; - -- if (reloc_opcodes) -- opcode = reloc_opcodes[i]; -- else -- opcode = get_relocation_opcode (abfd, sec, contents, irel); -- if (opcode == XTENSA_UNDEFINED) -+ if (relevant_relocs) - { -- ok = FALSE; -- break; -+ opcode = entry->opcode; -+ opnum = entry->opnum; - } -- -- opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -- if (opnum == XTENSA_UNDEFINED) -+ else - { -- ok = FALSE; -- break; -+ if (reloc_opcodes) -+ opcode = reloc_opcodes[relevant_relocs ? -+ (unsigned)(entry - relevant_relocs->reloc) : i]; -+ else -+ opcode = get_relocation_opcode (abfd, sec, contents, irel); -+ if (opcode == XTENSA_UNDEFINED) -+ { -+ ok = FALSE; -+ break; -+ } -+ -+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); -+ if (opnum == XTENSA_UNDEFINED) -+ { -+ ok = FALSE; -+ break; -+ } - } - - if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset)) -@@ -8778,7 +9053,7 @@ move_shared_literal (asection *sec, - /* Check all of the PC-relative relocations to make sure they still fit. */ - relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, - target_sec_cache->contents, -- target_sec_cache->relocs, -+ target_sec_cache->relocs, NULL, - &ebb_table, NULL); - - if (!relocs_fit) --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch b/patches/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch deleted file mode 100644 index 9df8065..0000000 --- a/patches/binutils/2.25.1/907-xtensa-optimize-removed_by_actions.patch +++ /dev/null @@ -1,356 +0,0 @@ -From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sat, 28 Mar 2015 08:46:28 +0300 -Subject: [PATCH 2/4] xtensa: optimize removed_by_actions - -The function removed_by_actions iterates through text actions to -calculate an offset applied by text actions to a given VMA. Although it -has a parameter p_start_action that allows for incremental offset -calculation, in many places it's used with p_start_action explicitly set -to the first action. After the first relaxation pass when the list of -text actions is finalized, an array of offsets sorted by VMA may be used -to speed up this function. - -Original profile: - -% time self children called name ------------------------------------------ - 0.35 0.00 33872/4808961 relax_section_symbols - 3.32 0.00 326022/4808961 relax_property_section - 12.83 0.00 1259379/4808961 offset_with_removed_text - 32.50 0.00 3189688/4808961 translate_reloc - 71.5 49.00 0.00 4808961 removed_by_actions ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 33872/4808537 relax_section_symbols - 0.01 0.00 326022/4808537 relax_property_section - 0.05 0.00 1258955/4808537 offset_with_removed_text_map - 0.13 0.00 3189688/4808537 translate_reloc - 1.0 0.20 0.00 4808537 removed_by_actions_map - 0.00 0.00 120/120 map_removal_by_action ------------------------------------------ - -2015-04-01 Max Filippov -bfd/ - * elf32-xtensa.c (removal_by_action_entry_struct, - removal_by_action_map_struct): new structures. - (removal_by_action_entry, removal_by_action_map): new typedefs. - (text_action_list_struct): add new field: map. - (map_removal_by_action, removed_by_actions_map, - offset_with_removed_text_map): new functions. - (relax_section): replace offset_with_removed_text with - offset_with_removed_text_map. - (translate_reloc, relax_property_section, relax_section_symbols): - replace removed_by_actions with removed_by_actions_map. - -Backported from: 071aa5c98a31c966f5fbfc573fcee61350fd1936 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 181 +++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 156 insertions(+), 25 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 872370b..21b2871 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -5420,11 +5420,28 @@ struct text_action_struct - text_action *next; - }; - -+struct removal_by_action_entry_struct -+{ -+ bfd_vma offset; -+ int removed; -+ int eq_removed; -+ int eq_removed_before_fill; -+}; -+typedef struct removal_by_action_entry_struct removal_by_action_entry; -+ -+struct removal_by_action_map_struct -+{ -+ unsigned n_entries; -+ removal_by_action_entry *entry; -+}; -+typedef struct removal_by_action_map_struct removal_by_action_map; -+ - - /* List of all of the actions taken on a text section. */ - struct text_action_list_struct - { - text_action *head; -+ removal_by_action_map map; - }; - - -@@ -5636,6 +5653,101 @@ action_list_count (text_action_list *action_list) - return count; - } - -+static void -+map_removal_by_action (text_action_list *action_list) -+{ -+ text_action *r; -+ int removed = 0; -+ removal_by_action_map map; -+ bfd_boolean eq_complete; -+ -+ map.n_entries = 0; -+ map.entry = bfd_malloc (action_list_count (action_list) * -+ sizeof (removal_by_action_entry)); -+ eq_complete = FALSE; -+ -+ for (r = action_list->head; r;) -+ { -+ removal_by_action_entry *ientry = map.entry + map.n_entries; -+ -+ if (map.n_entries && (ientry - 1)->offset == r->offset) -+ { -+ --ientry; -+ } -+ else -+ { -+ ++map.n_entries; -+ eq_complete = FALSE; -+ ientry->offset = r->offset; -+ ientry->eq_removed_before_fill = removed; -+ } -+ -+ if (!eq_complete) -+ { -+ if (r->action != ta_fill || r->removed_bytes >= 0) -+ { -+ ientry->eq_removed = removed; -+ eq_complete = TRUE; -+ } -+ else -+ ientry->eq_removed = removed + r->removed_bytes; -+ } -+ -+ removed += r->removed_bytes; -+ ientry->removed = removed; -+ r = r->next; -+ } -+ action_list->map = map; -+} -+ -+static int -+removed_by_actions_map (text_action_list *action_list, bfd_vma offset, -+ bfd_boolean before_fill) -+{ -+ unsigned a, b; -+ -+ if (!action_list->map.entry) -+ map_removal_by_action (action_list); -+ -+ if (!action_list->map.n_entries) -+ return 0; -+ -+ a = 0; -+ b = action_list->map.n_entries; -+ -+ while (b - a > 1) -+ { -+ unsigned c = (a + b) / 2; -+ -+ if (action_list->map.entry[c].offset <= offset) -+ a = c; -+ else -+ b = c; -+ } -+ -+ if (action_list->map.entry[a].offset < offset) -+ { -+ return action_list->map.entry[a].removed; -+ } -+ else if (action_list->map.entry[a].offset == offset) -+ { -+ return before_fill ? -+ action_list->map.entry[a].eq_removed_before_fill : -+ action_list->map.entry[a].eq_removed; -+ } -+ else -+ { -+ return 0; -+ } -+} -+ -+static bfd_vma -+offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) -+{ -+ int removed = removed_by_actions_map (action_list, offset, FALSE); -+ return offset - removed; -+} -+ - - /* The find_insn_action routine will only find non-fill actions. */ - -@@ -5909,6 +6021,9 @@ init_xtensa_relax_info (asection *sec) - - relax_info->action_list.head = NULL; - -+ relax_info->action_list.map.n_entries = 0; -+ relax_info->action_list.map.entry = NULL; -+ - relax_info->fix_list = NULL; - relax_info->fix_array = NULL; - relax_info->fix_array_count = 0; -@@ -9218,7 +9333,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - if (elf_hash_table (link_info)->dynamic_sections_created) - shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); - irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); -- irel->r_offset = offset_with_removed_text -+ irel->r_offset = offset_with_removed_text_map - (&relax_info->action_list, irel->r_offset); - continue; - } -@@ -9255,7 +9370,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - } - } - -- source_offset = offset_with_removed_text -+ source_offset = offset_with_removed_text_map - (&relax_info->action_list, irel->r_offset); - irel->r_offset = source_offset; - } -@@ -9352,7 +9467,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - break; - } - -- new_end_offset = offset_with_removed_text -+ new_end_offset = offset_with_removed_text_map - (&target_relax_info->action_list, - r_rel.target_offset + diff_value); - diff_value = new_end_offset - new_reloc.target_offset; -@@ -9750,7 +9865,6 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) - xtensa_relax_info *relax_info; - removed_literal *removed; - bfd_vma target_offset, base_offset; -- text_action *act; - - *new_rel = *orig_rel; - -@@ -9803,19 +9917,26 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec) - offset. */ - - base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend; -- act = relax_info->action_list.head; - if (base_offset <= target_offset) - { -- int base_removed = removed_by_actions (&act, base_offset, FALSE); -- int addend_removed = removed_by_actions (&act, target_offset, FALSE); -+ int base_removed = removed_by_actions_map (&relax_info->action_list, -+ base_offset, FALSE); -+ int addend_removed = removed_by_actions_map (&relax_info->action_list, -+ target_offset, FALSE) - -+ base_removed; -+ - new_rel->target_offset = target_offset - base_removed - addend_removed; - new_rel->rela.r_addend -= addend_removed; - } - else - { - /* Handle a negative addend. The base offset comes first. */ -- int tgt_removed = removed_by_actions (&act, target_offset, FALSE); -- int addend_removed = removed_by_actions (&act, base_offset, FALSE); -+ int tgt_removed = removed_by_actions_map (&relax_info->action_list, -+ target_offset, FALSE); -+ int addend_removed = removed_by_actions_map (&relax_info->action_list, -+ base_offset, FALSE) - -+ tgt_removed; -+ - new_rel->target_offset = target_offset - tgt_removed; - new_rel->rela.r_addend += addend_removed; - } -@@ -10138,9 +10259,10 @@ relax_property_section (bfd *abfd, - bfd_vma old_offset = val.r_rel.target_offset; - bfd_vma new_offset; - long old_size, new_size; -- text_action *act = target_relax_info->action_list.head; -- new_offset = old_offset - -- removed_by_actions (&act, old_offset, FALSE); -+ int removed_by_old_offset = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset, FALSE); -+ new_offset = old_offset - removed_by_old_offset; - - /* Assert that we are not out of bounds. */ - old_size = bfd_get_32 (abfd, size_p); -@@ -10164,9 +10286,10 @@ relax_property_section (bfd *abfd, - - /* Recompute the new_offset, but this time don't - include any fill inserted by relaxation. */ -- act = target_relax_info->action_list.head; -- new_offset = old_offset - -- removed_by_actions (&act, old_offset, TRUE); -+ removed_by_old_offset = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset, TRUE); -+ new_offset = old_offset - removed_by_old_offset; - - /* If it is not unreachable and we have not yet - seen an unreachable at this address, place it -@@ -10182,8 +10305,12 @@ relax_property_section (bfd *abfd, - } - } - else -- new_size -= -- removed_by_actions (&act, old_offset + old_size, TRUE); -+ { -+ int removed_by_old_offset_size = -+ removed_by_actions_map (&target_relax_info->action_list, -+ old_offset + old_size, TRUE); -+ new_size -= removed_by_old_offset_size - removed_by_old_offset; -+ } - - if (new_size != old_size) - { -@@ -10441,14 +10568,16 @@ relax_section_symbols (bfd *abfd, asection *sec) - - if (isym->st_shndx == sec_shndx) - { -- text_action *act = relax_info->action_list.head; - bfd_vma orig_addr = isym->st_value; -+ int removed = removed_by_actions_map (&relax_info->action_list, -+ orig_addr, FALSE); - -- isym->st_value -= removed_by_actions (&act, orig_addr, FALSE); -- -+ isym->st_value -= removed; - if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) - isym->st_size -= -- removed_by_actions (&act, orig_addr + isym->st_size, FALSE); -+ removed_by_actions_map (&relax_info->action_list, -+ orig_addr + isym->st_size, FALSE) - -+ removed; - } - } - -@@ -10466,15 +10595,17 @@ relax_section_symbols (bfd *abfd, asection *sec) - || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec) - { -- text_action *act = relax_info->action_list.head; - bfd_vma orig_addr = sym_hash->root.u.def.value; -+ int removed = removed_by_actions_map (&relax_info->action_list, -+ orig_addr, FALSE); - -- sym_hash->root.u.def.value -= -- removed_by_actions (&act, orig_addr, FALSE); -+ sym_hash->root.u.def.value -= removed; - - if (sym_hash->type == STT_FUNC) - sym_hash->size -= -- removed_by_actions (&act, orig_addr + sym_hash->size, FALSE); -+ removed_by_actions_map (&relax_info->action_list, -+ orig_addr + sym_hash->size, FALSE) - -+ removed; - } - } - --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch b/patches/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch deleted file mode 100644 index 96d526f..0000000 --- a/patches/binutils/2.25.1/908-xtensa-optimize-find_removed_literal.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 288c2b709e5e6841484e1a129eaccd299db36877 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sat, 4 Apr 2015 14:49:42 +0300 -Subject: [PATCH 3/4] xtensa: optimize find_removed_literal - -find_removed_literal uses linear search to find removed literal by its -VMA. The list of literals is fixed at that point, build an ordered index -array and use binary search instead. - -Original profile: - -% time self children called name ------------------------------------------ - 56.72 0.00 297578/669392 translate_reloc - 70.86 0.00 371814/669392 relax_section - 67.9 127.58 0.00 669392 find_removed_literal ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 297578/669392 translate_reloc - 0.00 0.00 371814/669392 relax_section - 0.0 0.00 0.00 669392 find_removed_literal - 0.00 0.00 23838/23838 map_removed_literal ------------------------------------------ - -2015-04-03 Max Filippov -bfd/ - * elf32-xtensa.c (removed_literal_map_entry): new typedef. - (removed_literal_map_entry_struct): new structure. - (removed_literal_list_struct): add new fields: n_map and map. - (map_removed_literal, removed_literal_compare): new functions. - (find_removed_literal): build index array for literals ordered - by VMA, use binary search to find removed literal. - -Backported from: 3439c466273378021821473d3fc84990e089ae34 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 58 insertions(+), 6 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 21b2871..51733ad 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -5832,6 +5832,7 @@ print_action_list (FILE *fp, text_action_list *action_list) - by the "from" offset field. */ - - typedef struct removed_literal_struct removed_literal; -+typedef struct removed_literal_map_entry_struct removed_literal_map_entry; - typedef struct removed_literal_list_struct removed_literal_list; - - struct removed_literal_struct -@@ -5841,10 +5842,19 @@ struct removed_literal_struct - removed_literal *next; - }; - -+struct removed_literal_map_entry_struct -+{ -+ bfd_vma addr; -+ removed_literal *literal; -+}; -+ - struct removed_literal_list_struct - { - removed_literal *head; - removed_literal *tail; -+ -+ unsigned n_map; -+ removed_literal_map_entry *map; - }; - - -@@ -5893,6 +5903,39 @@ add_removed_literal (removed_literal_list *removed_list, - } - } - -+static void -+map_removed_literal (removed_literal_list *removed_list) -+{ -+ unsigned n_map = 0; -+ unsigned i; -+ removed_literal_map_entry *map = NULL; -+ removed_literal *r = removed_list->head; -+ -+ for (i = 0; r; ++i, r = r->next) -+ { -+ if (i == n_map) -+ { -+ n_map = (n_map * 2) + 2; -+ map = bfd_realloc (map, n_map * sizeof (*map)); -+ } -+ map[i].addr = r->from.target_offset; -+ map[i].literal = r; -+ } -+ removed_list->map = map; -+ removed_list->n_map = i; -+} -+ -+static int -+removed_literal_compare (const void *a, const void *b) -+{ -+ const removed_literal_map_entry *pa = a; -+ const removed_literal_map_entry *pb = b; -+ -+ if (pa->addr == pb->addr) -+ return 0; -+ else -+ return pa->addr < pb->addr ? -1 : 1; -+} - - /* Check if the list of removed literals contains an entry for the - given address. Return the entry if found. */ -@@ -5900,12 +5943,21 @@ add_removed_literal (removed_literal_list *removed_list, - static removed_literal * - find_removed_literal (removed_literal_list *removed_list, bfd_vma addr) - { -- removed_literal *r = removed_list->head; -- while (r && r->from.target_offset < addr) -- r = r->next; -- if (r && r->from.target_offset == addr) -- return r; -- return NULL; -+ removed_literal_map_entry *p; -+ removed_literal *r = NULL; -+ -+ if (removed_list->map == NULL) -+ map_removed_literal (removed_list); -+ -+ p = bsearch (&addr, removed_list->map, removed_list->n_map, -+ sizeof (*removed_list->map), removed_literal_compare); -+ if (p) -+ { -+ while (p != removed_list->map && (p - 1)->addr == addr) -+ --p; -+ r = p->literal; -+ } -+ return r; - } - - --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch b/patches/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch deleted file mode 100644 index 3090cc2..0000000 --- a/patches/binutils/2.25.1/909-xtensa-replace-action-list-with-splay-tree.patch +++ /dev/null @@ -1,826 +0,0 @@ -From e5409aedd3ee2192855018a564650ffb75c26e60 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sun, 5 Apr 2015 17:04:22 +0300 -Subject: [PATCH 4/4] xtensa: replace action list with splay tree - -text_action_add uses linear list search to order text actions list by -action VMA. The list is used at the first relaxation pass, when it's not -fixed yet. -Replace the list with splay tree from libiberty. - -Original profile: - -% time self children called name ------------------------------------------ - 0.00 0.00 14/158225 compute_text_actions - 3.62 0.00 25211/158225 remove_dead_literal - 8.42 0.00 58645/158225 coalesce_shared_literal - 10.68 0.00 74355/158225 text_action_add_proposed - 38.8 22.73 0.00 158225 text_action_add - 0.00 0.00 144527/293246 bfd_zmalloc ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.00 0.00 14/158225 compute_text_actions - 0.00 0.00 25211/158225 remove_dead_literal - 0.00 0.01 58645/158225 coalesce_shared_literal - 0.00 0.01 74355/158225 text_action_add_proposed - 0.1 0.00 0.02 158225 text_action_add - 0.01 0.00 144527/144527 splay_tree_insert - 0.00 0.00 144527/195130 splay_tree_lookup - 0.00 0.00 144527/293246 bfd_zmalloc ------------------------------------------ - -2015-04-03 Max Filippov -bfd/ - * elf32-xtensa.c (splay-tree.h): include header. - (text_action_struct): drop next pointer. - (text_action_list_struct): drop head pointer, add count and - tree fields. - (find_fill_action): instead of linear search in text_action_list - search in the tree. - (text_action_compare, action_first, action_next): new functions. - (text_action_add, text_action_add_literal): instead of linear - search and insertion insert new node into the tree. - (removed_by_actions): pass additional parameter: action_list, - use it to traverse the tree. - (offset_with_removed_text): pass additional action_list parameter - to removed_by_actions. - (map_action_fn_context): new typedef. - (map_action_fn_context_struct): new structure. - (map_action_fn): new function. - (map_removal_by_action): use splay_tree_foreach to build map. - (find_insn_action): replace linear search in text_action_list - with series of splay_tree_lookups. - (print_action, print_action_list_fn): new functions. - (print_action_list): use splay_tree_foreach. - (init_xtensa_relax_info): drop action_list.head initialization. - Initialize the tree. - (compute_text_actions): use non-zero action_list_count instead of - non-NULL action list. - (xlate_map_context): new typedef. - (xlate_map_context_struct): new structure. - (xlate_map_fn): new function. - (build_xlate_map): use splay_tree_foreach to build map. - (action_remove_bytes_fn): new function. - (relax_section): use zero action_list_count instead of NULL - action list. Use splay_tree_foreach to count final section size. - Drop unused variable 'removed'. - -Backported from: 4c2af04fe8b4452bf51d2debf1bb467fafcd0f08 -Signed-off-by: Max Filippov ---- - bfd/elf32-xtensa.c | 488 +++++++++++++++++++++++++++++++---------------------- - 1 file changed, 282 insertions(+), 206 deletions(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 51733ad..53af1c6 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -28,6 +28,7 @@ - #include "libbfd.h" - #include "elf-bfd.h" - #include "elf/xtensa.h" -+#include "splay-tree.h" - #include "xtensa-isa.h" - #include "xtensa-config.h" - -@@ -5416,8 +5417,6 @@ struct text_action_struct - bfd_vma virtual_offset; /* Zero except for adding literals. */ - int removed_bytes; - literal_value value; /* Only valid when adding literals. */ -- -- text_action *next; - }; - - struct removal_by_action_entry_struct -@@ -5440,7 +5439,8 @@ typedef struct removal_by_action_map_struct removal_by_action_map; - /* List of all of the actions taken on a text section. */ - struct text_action_list_struct - { -- text_action *head; -+ unsigned count; -+ splay_tree tree; - removal_by_action_map map; - }; - -@@ -5448,20 +5448,18 @@ struct text_action_list_struct - static text_action * - find_fill_action (text_action_list *l, asection *sec, bfd_vma offset) - { -- text_action **m_p; -+ text_action a; - - /* It is not necessary to fill at the end of a section. */ - if (sec->size == offset) - return NULL; - -- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) -- { -- text_action *t = *m_p; -- /* When the action is another fill at the same address, -- just increase the size. */ -- if (t->offset == offset && t->action == ta_fill) -- return t; -- } -+ a.offset = offset; -+ a.action = ta_fill; -+ -+ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); -+ if (node) -+ return (text_action *)node->value; - return NULL; - } - -@@ -5509,6 +5507,49 @@ adjust_fill_action (text_action *ta, int fill_diff) - } - - -+static int -+text_action_compare (splay_tree_key a, splay_tree_key b) -+{ -+ text_action *pa = (text_action *)a; -+ text_action *pb = (text_action *)b; -+ static const int action_priority[] = -+ { -+ [ta_fill] = 0, -+ [ta_none] = 1, -+ [ta_convert_longcall] = 2, -+ [ta_narrow_insn] = 3, -+ [ta_remove_insn] = 4, -+ [ta_remove_longcall] = 5, -+ [ta_remove_literal] = 6, -+ [ta_widen_insn] = 7, -+ [ta_add_literal] = 8, -+ }; -+ -+ if (pa->offset == pb->offset) -+ { -+ if (pa->action == pb->action) -+ return 0; -+ return action_priority[pa->action] - action_priority[pb->action]; -+ } -+ else -+ return pa->offset < pb->offset ? -1 : 1; -+} -+ -+static text_action * -+action_first (text_action_list *action_list) -+{ -+ splay_tree_node node = splay_tree_min (action_list->tree); -+ return node ? (text_action *)node->value : NULL; -+} -+ -+static text_action * -+action_next (text_action_list *action_list, text_action *action) -+{ -+ splay_tree_node node = splay_tree_successor (action_list->tree, -+ (splay_tree_key)action); -+ return node ? (text_action *)node->value : NULL; -+} -+ - /* Add a modification action to the text. For the case of adding or - removing space, modify any current fill and assume that - "unreachable_space" bytes can be freely contracted. Note that a -@@ -5521,8 +5562,8 @@ text_action_add (text_action_list *l, - bfd_vma offset, - int removed) - { -- text_action **m_p; - text_action *ta; -+ text_action a; - - /* It is not necessary to fill at the end of a section. */ - if (action == ta_fill && sec->size == offset) -@@ -5532,34 +5573,30 @@ text_action_add (text_action_list *l, - if (action == ta_fill && removed == 0) - return; - -- for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) -+ a.action = action; -+ a.offset = offset; -+ -+ if (action == ta_fill) - { -- text_action *t = *m_p; -+ splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a); - -- if (action == ta_fill) -+ if (node) - { -- /* When the action is another fill at the same address, -- just increase the size. */ -- if (t->offset == offset && t->action == ta_fill) -- { -- t->removed_bytes += removed; -- return; -- } -- /* Fills need to happen before widens so that we don't -- insert fill bytes into the instruction stream. */ -- if (t->offset == offset && t->action == ta_widen_insn) -- break; -+ ta = (text_action *)node->value; -+ ta->removed_bytes += removed; -+ return; - } - } -+ else -+ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&a) == NULL); - -- /* Create a new record and fill it up. */ - ta = (text_action *) bfd_zmalloc (sizeof (text_action)); - ta->action = action; - ta->sec = sec; - ta->offset = offset; - ta->removed_bytes = removed; -- ta->next = (*m_p); -- *m_p = ta; -+ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); -+ ++l->count; - } - - -@@ -5570,7 +5607,6 @@ text_action_add_literal (text_action_list *l, - const literal_value *value, - int removed) - { -- text_action **m_p; - text_action *ta; - asection *sec = r_reloc_get_section (loc); - bfd_vma offset = loc->target_offset; -@@ -5578,14 +5614,6 @@ text_action_add_literal (text_action_list *l, - - BFD_ASSERT (action == ta_add_literal); - -- for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next) -- { -- if ((*m_p)->offset > offset -- && ((*m_p)->offset != offset -- || (*m_p)->virtual_offset > virtual_offset)) -- break; -- } -- - /* Create a new record and fill it up. */ - ta = (text_action *) bfd_zmalloc (sizeof (text_action)); - ta->action = action; -@@ -5594,8 +5622,10 @@ text_action_add_literal (text_action_list *l, - ta->virtual_offset = virtual_offset; - ta->value = *value; - ta->removed_bytes = removed; -- ta->next = (*m_p); -- *m_p = ta; -+ -+ BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) == NULL); -+ splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta); -+ ++l->count; - } - - -@@ -5606,7 +5636,8 @@ text_action_add_literal (text_action_list *l, - so that each search may begin where the previous one left off. */ - - static int --removed_by_actions (text_action **p_start_action, -+removed_by_actions (text_action_list *action_list, -+ text_action **p_start_action, - bfd_vma offset, - bfd_boolean before_fill) - { -@@ -5614,6 +5645,13 @@ removed_by_actions (text_action **p_start_action, - int removed = 0; - - r = *p_start_action; -+ if (r) -+ { -+ splay_tree_node node = splay_tree_lookup (action_list->tree, -+ (splay_tree_key)r); -+ BFD_ASSERT (node != NULL && r == (text_action *)node->value); -+ } -+ - while (r) - { - if (r->offset > offset) -@@ -5625,7 +5663,7 @@ removed_by_actions (text_action **p_start_action, - - removed += r->removed_bytes; - -- r = r->next; -+ r = action_next (action_list, r); - } - - *p_start_action = r; -@@ -5636,68 +5674,74 @@ removed_by_actions (text_action **p_start_action, - static bfd_vma - offset_with_removed_text (text_action_list *action_list, bfd_vma offset) - { -- text_action *r = action_list->head; -- return offset - removed_by_actions (&r, offset, FALSE); -+ text_action *r = action_first (action_list); -+ -+ return offset - removed_by_actions (action_list, &r, offset, FALSE); - } - - - static unsigned - action_list_count (text_action_list *action_list) - { -- text_action *r = action_list->head; -- unsigned count = 0; -- for (r = action_list->head; r != NULL; r = r->next) -- { -- count++; -- } -- return count; -+ return action_list->count; - } - --static void --map_removal_by_action (text_action_list *action_list) -+typedef struct map_action_fn_context_struct map_action_fn_context; -+struct map_action_fn_context_struct - { -- text_action *r; -- int removed = 0; -+ int removed; - removal_by_action_map map; - bfd_boolean eq_complete; -+}; - -- map.n_entries = 0; -- map.entry = bfd_malloc (action_list_count (action_list) * -- sizeof (removal_by_action_entry)); -- eq_complete = FALSE; -+static int -+map_action_fn (splay_tree_node node, void *p) -+{ -+ map_action_fn_context *ctx = p; -+ text_action *r = (text_action *)node->value; -+ removal_by_action_entry *ientry = ctx->map.entry + ctx->map.n_entries; - -- for (r = action_list->head; r;) -+ if (ctx->map.n_entries && (ientry - 1)->offset == r->offset) - { -- removal_by_action_entry *ientry = map.entry + map.n_entries; -+ --ientry; -+ } -+ else -+ { -+ ++ctx->map.n_entries; -+ ctx->eq_complete = FALSE; -+ ientry->offset = r->offset; -+ ientry->eq_removed_before_fill = ctx->removed; -+ } - -- if (map.n_entries && (ientry - 1)->offset == r->offset) -+ if (!ctx->eq_complete) -+ { -+ if (r->action != ta_fill || r->removed_bytes >= 0) - { -- --ientry; -+ ientry->eq_removed = ctx->removed; -+ ctx->eq_complete = TRUE; - } - else -- { -- ++map.n_entries; -- eq_complete = FALSE; -- ientry->offset = r->offset; -- ientry->eq_removed_before_fill = removed; -- } -+ ientry->eq_removed = ctx->removed + r->removed_bytes; -+ } - -- if (!eq_complete) -- { -- if (r->action != ta_fill || r->removed_bytes >= 0) -- { -- ientry->eq_removed = removed; -- eq_complete = TRUE; -- } -- else -- ientry->eq_removed = removed + r->removed_bytes; -- } -+ ctx->removed += r->removed_bytes; -+ ientry->removed = ctx->removed; -+ return 0; -+} - -- removed += r->removed_bytes; -- ientry->removed = removed; -- r = r->next; -- } -- action_list->map = map; -+static void -+map_removal_by_action (text_action_list *action_list) -+{ -+ map_action_fn_context ctx; -+ -+ ctx.removed = 0; -+ ctx.map.n_entries = 0; -+ ctx.map.entry = bfd_malloc (action_list_count (action_list) * -+ sizeof (removal_by_action_entry)); -+ ctx.eq_complete = FALSE; -+ -+ splay_tree_foreach (action_list->tree, map_action_fn, &ctx); -+ action_list->map = ctx.map; - } - - static int -@@ -5754,28 +5798,26 @@ offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset) - static text_action * - find_insn_action (text_action_list *action_list, bfd_vma offset) - { -- text_action *t; -- for (t = action_list->head; t; t = t->next) -+ static const text_action_t action[] = - { -- if (t->offset == offset) -- { -- switch (t->action) -- { -- case ta_none: -- case ta_fill: -- break; -- case ta_remove_insn: -- case ta_remove_longcall: -- case ta_convert_longcall: -- case ta_narrow_insn: -- case ta_widen_insn: -- return t; -- case ta_remove_literal: -- case ta_add_literal: -- BFD_ASSERT (0); -- break; -- } -- } -+ ta_convert_longcall, -+ ta_remove_longcall, -+ ta_widen_insn, -+ ta_narrow_insn, -+ ta_remove_insn, -+ }; -+ text_action a; -+ unsigned i; -+ -+ a.offset = offset; -+ for (i = 0; i < sizeof (action) / sizeof (*action); ++i) -+ { -+ splay_tree_node node; -+ -+ a.action = action[i]; -+ node = splay_tree_lookup (action_list->tree, (splay_tree_key)&a); -+ if (node) -+ return (text_action *)node->value; - } - return NULL; - } -@@ -5784,40 +5826,50 @@ find_insn_action (text_action_list *action_list, bfd_vma offset) - #if DEBUG - - static void --print_action_list (FILE *fp, text_action_list *action_list) -+print_action (FILE *fp, text_action *r) -+{ -+ const char *t = "unknown"; -+ switch (r->action) -+ { -+ case ta_remove_insn: -+ t = "remove_insn"; break; -+ case ta_remove_longcall: -+ t = "remove_longcall"; break; -+ case ta_convert_longcall: -+ t = "convert_longcall"; break; -+ case ta_narrow_insn: -+ t = "narrow_insn"; break; -+ case ta_widen_insn: -+ t = "widen_insn"; break; -+ case ta_fill: -+ t = "fill"; break; -+ case ta_none: -+ t = "none"; break; -+ case ta_remove_literal: -+ t = "remove_literal"; break; -+ case ta_add_literal: -+ t = "add_literal"; break; -+ } -+ -+ fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", -+ r->sec->owner->filename, -+ r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); -+} -+ -+static int -+print_action_list_fn (splay_tree_node node, void *p) - { -- text_action *r; -+ text_action *r = (text_action *)node->value; - -- fprintf (fp, "Text Action\n"); -- for (r = action_list->head; r != NULL; r = r->next) -- { -- const char *t = "unknown"; -- switch (r->action) -- { -- case ta_remove_insn: -- t = "remove_insn"; break; -- case ta_remove_longcall: -- t = "remove_longcall"; break; -- case ta_convert_longcall: -- t = "convert_longcall"; break; -- case ta_narrow_insn: -- t = "narrow_insn"; break; -- case ta_widen_insn: -- t = "widen_insn"; break; -- case ta_fill: -- t = "fill"; break; -- case ta_none: -- t = "none"; break; -- case ta_remove_literal: -- t = "remove_literal"; break; -- case ta_add_literal: -- t = "add_literal"; break; -- } -+ print_action (p, r); -+ return 0; -+} - -- fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", -- r->sec->owner->filename, -- r->sec->name, (unsigned long) r->offset, t, r->removed_bytes); -- } -+static void -+print_action_list (FILE *fp, text_action_list *action_list) -+{ -+ fprintf (fp, "Text Action\n"); -+ splay_tree_foreach (action_list->tree, print_action_list_fn, fp); - } - - #endif /* DEBUG */ -@@ -6071,8 +6123,8 @@ init_xtensa_relax_info (asection *sec) - relax_info->removed_list.head = NULL; - relax_info->removed_list.tail = NULL; - -- relax_info->action_list.head = NULL; -- -+ relax_info->action_list.tree = splay_tree_new (text_action_compare, -+ NULL, NULL); - relax_info->action_list.map.n_entries = 0; - relax_info->action_list.map.entry = NULL; - -@@ -7762,7 +7814,7 @@ compute_text_actions (bfd *abfd, - free_reloc_range_list (&relevant_relocs); - - #if DEBUG -- if (relax_info->action_list.head) -+ if (action_list_count (&relax_info->action_list)) - print_action_list (stderr, &relax_info->action_list); - #endif - -@@ -8263,6 +8315,54 @@ xlate_offset_with_removed_text (const xlate_map_t *map, - return e->new_address - e->orig_address + offset; - } - -+typedef struct xlate_map_context_struct xlate_map_context; -+struct xlate_map_context_struct -+{ -+ xlate_map_t *map; -+ xlate_map_entry_t *current_entry; -+ int removed; -+}; -+ -+static int -+xlate_map_fn (splay_tree_node node, void *p) -+{ -+ text_action *r = (text_action *)node->value; -+ xlate_map_context *ctx = p; -+ unsigned orig_size = 0; -+ -+ switch (r->action) -+ { -+ case ta_none: -+ case ta_remove_insn: -+ case ta_convert_longcall: -+ case ta_remove_literal: -+ case ta_add_literal: -+ break; -+ case ta_remove_longcall: -+ orig_size = 6; -+ break; -+ case ta_narrow_insn: -+ orig_size = 3; -+ break; -+ case ta_widen_insn: -+ orig_size = 2; -+ break; -+ case ta_fill: -+ break; -+ } -+ ctx->current_entry->size = -+ r->offset + orig_size - ctx->current_entry->orig_address; -+ if (ctx->current_entry->size != 0) -+ { -+ ctx->current_entry++; -+ ctx->map->entry_count++; -+ } -+ ctx->current_entry->orig_address = r->offset + orig_size; -+ ctx->removed += r->removed_bytes; -+ ctx->current_entry->new_address = r->offset + orig_size - ctx->removed; -+ ctx->current_entry->size = 0; -+ return 0; -+} - - /* Build a binary searchable offset translation map from a section's - action list. */ -@@ -8270,75 +8370,40 @@ xlate_offset_with_removed_text (const xlate_map_t *map, - static xlate_map_t * - build_xlate_map (asection *sec, xtensa_relax_info *relax_info) - { -- xlate_map_t *map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); - text_action_list *action_list = &relax_info->action_list; - unsigned num_actions = 0; -- text_action *r; -- int removed; -- xlate_map_entry_t *current_entry; -+ xlate_map_context ctx; - -- if (map == NULL) -+ ctx.map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t)); -+ -+ if (ctx.map == NULL) - return NULL; - - num_actions = action_list_count (action_list); -- map->entry = (xlate_map_entry_t *) -+ ctx.map->entry = (xlate_map_entry_t *) - bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1)); -- if (map->entry == NULL) -+ if (ctx.map->entry == NULL) - { -- free (map); -+ free (ctx.map); - return NULL; - } -- map->entry_count = 0; -+ ctx.map->entry_count = 0; - -- removed = 0; -- current_entry = &map->entry[0]; -+ ctx.removed = 0; -+ ctx.current_entry = &ctx.map->entry[0]; - -- current_entry->orig_address = 0; -- current_entry->new_address = 0; -- current_entry->size = 0; -+ ctx.current_entry->orig_address = 0; -+ ctx.current_entry->new_address = 0; -+ ctx.current_entry->size = 0; - -- for (r = action_list->head; r != NULL; r = r->next) -- { -- unsigned orig_size = 0; -- switch (r->action) -- { -- case ta_none: -- case ta_remove_insn: -- case ta_convert_longcall: -- case ta_remove_literal: -- case ta_add_literal: -- break; -- case ta_remove_longcall: -- orig_size = 6; -- break; -- case ta_narrow_insn: -- orig_size = 3; -- break; -- case ta_widen_insn: -- orig_size = 2; -- break; -- case ta_fill: -- break; -- } -- current_entry->size = -- r->offset + orig_size - current_entry->orig_address; -- if (current_entry->size != 0) -- { -- current_entry++; -- map->entry_count++; -- } -- current_entry->orig_address = r->offset + orig_size; -- removed += r->removed_bytes; -- current_entry->new_address = r->offset + orig_size - removed; -- current_entry->size = 0; -- } -+ splay_tree_foreach (action_list->tree, xlate_map_fn, &ctx); - -- current_entry->size = (bfd_get_section_limit (sec->owner, sec) -- - current_entry->orig_address); -- if (current_entry->size != 0) -- map->entry_count++; -+ ctx.current_entry->size = (bfd_get_section_limit (sec->owner, sec) -+ - ctx.current_entry->orig_address); -+ if (ctx.current_entry->size != 0) -+ ctx.map->entry_count++; - -- return map; -+ return ctx.map; - } - - -@@ -9302,6 +9367,16 @@ move_shared_literal (asection *sec, - - /* Second relaxation pass. */ - -+static int -+action_remove_bytes_fn (splay_tree_node node, void *p) -+{ -+ bfd_size_type *final_size = p; -+ text_action *action = (text_action *)node->value; -+ -+ *final_size -= action->removed_bytes; -+ return 0; -+} -+ - /* Modify all of the relocations to point to the right spot, and if this - is a relaxable section, delete the unwanted literals and fix the - section size. */ -@@ -9334,7 +9409,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - - internal_relocs = retrieve_internal_relocs (abfd, sec, - link_info->keep_memory); -- if (!internal_relocs && !relax_info->action_list.head) -+ if (!internal_relocs && !action_list_count (&relax_info->action_list)) - return TRUE; - - contents = retrieve_contents (abfd, sec, link_info->keep_memory); -@@ -9412,6 +9487,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - } - /* Update the action so that the code that moves - the contents will do the right thing. */ -+ /* ta_remove_longcall and ta_remove_insn actions are -+ grouped together in the tree as well as -+ ta_convert_longcall and ta_none, so that changes below -+ can be done w/o removing and reinserting action into -+ the tree. */ -+ - if (action->action == ta_remove_longcall) - action->action = ta_remove_insn; - else -@@ -9584,13 +9665,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - - if ((relax_info->is_relaxable_literal_section - || relax_info->is_relaxable_asm_section) -- && relax_info->action_list.head) -+ && action_list_count (&relax_info->action_list)) - { - /* Walk through the planned actions and build up a table - of move, copy and fill records. Use the move, copy and - fill records to perform the actions once. */ - -- int removed = 0; - bfd_size_type final_size, copy_size, orig_insn_size; - bfd_byte *scratch = NULL; - bfd_byte *dup_contents = NULL; -@@ -9601,15 +9681,12 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */ - bfd_vma dup_dot = 0; - -- text_action *action = relax_info->action_list.head; -+ text_action *action; - - final_size = sec->size; -- for (action = relax_info->action_list.head; action; -- action = action->next) -- { -- final_size -= action->removed_bytes; -- } - -+ splay_tree_foreach (relax_info->action_list.tree, -+ action_remove_bytes_fn, &final_size); - scratch = (bfd_byte *) bfd_zmalloc (final_size); - dup_contents = (bfd_byte *) bfd_zmalloc (final_size); - -@@ -9618,8 +9695,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - print_action_list (stderr, &relax_info->action_list); - #endif - -- for (action = relax_info->action_list.head; action; -- action = action->next) -+ for (action = action_first (&relax_info->action_list); action; -+ action = action_next (&relax_info->action_list, action)) - { - virtual_action = FALSE; - if (action->offset > orig_dot) -@@ -9748,7 +9825,6 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) - break; - } - -- removed += action->removed_bytes; - BFD_ASSERT (dup_dot <= final_size); - BFD_ASSERT (orig_dot <= orig_size); - } --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch b/patches/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch deleted file mode 100644 index 043ff4d..0000000 --- a/patches/binutils/2.25.1/910-xtensa-optimize-trampolines-relaxation.patch +++ /dev/null @@ -1,345 +0,0 @@ -From cbe53e134d4c3a656880a906738ce19fdcd38e8b Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Fri, 1 May 2015 11:39:12 +0300 -Subject: [PATCH] xtensa: optimize trampolines relaxation - -Currently every fixup in the current segment is checked when relaxing -trampoline frag. This is very expensive. Make a searchable array of -fixups pointing at potentially oversized jumps at the beginning of every -relaxation pass and only check subset of this cache in the reach of -single jump from the trampoline frag currently being relaxed. - -Original profile: - -% time self children called name ------------------------------------------ - 370.16 593.38 12283048/12283048 relax_segment - 98.4 370.16 593.38 12283048 xtensa_relax_frag - 58.91 269.26 2691463834/2699602236 xtensa_insnbuf_from_chars - 68.35 68.17 811266668/813338977 S_GET_VALUE - 36.85 29.51 2684369246/2685538060 xtensa_opcode_decode - 28.34 8.84 2684369246/2685538060 xtensa_format_get_slot - 12.39 5.94 2691463834/2699775044 xtensa_format_decode - 0.03 4.60 4101109/4101109 relax_frag_for_align - 0.18 1.76 994617/994617 relax_frag_immed - 0.07 0.09 24556277/24851220 new_logical_line - 0.06 0.00 12283048/14067410 as_where - 0.04 0.00 7094588/15460506 xtensa_format_num_slots - 0.00 0.00 1/712477 xtensa_insnbuf_alloc ------------------------------------------ - -Same data, after optimization: - -% time self children called name ------------------------------------------ - 0.51 7.47 12283048/12283048 relax_segment - 58.0 0.51 7.47 12283048 xtensa_relax_frag - 0.02 4.08 4101109/4101109 relax_frag_for_align - 0.18 1.39 994617/994617 relax_frag_immed - 0.01 0.98 555/555 xtensa_cache_relaxable_fixups - 0.21 0.25 7094588/16693271 xtensa_insnbuf_from_chars - 0.06 0.12 24556277/24851220 new_logical_line - 0.06 0.00 7094588/15460506 xtensa_format_num_slots - 0.02 0.04 7094588/16866079 xtensa_format_decode - 0.05 0.00 12283048/14067410 as_where - 0.00 0.00 1/712477 xtensa_insnbuf_alloc - 0.00 0.00 93808/93808 xtensa_find_first_cached_fixup ------------------------------------------ - -2015-05-02 Max Filippov -gas/ - * config/tc-xtensa.c (cached_fixupS, fixup_cacheS): New typedefs. - (struct cached_fixup, struct fixup_cache): New structures. - (fixup_order, xtensa_make_cached_fixup), - (xtensa_realloc_fixup_cache, xtensa_cache_relaxable_fixups), - (xtensa_find_first_cached_fixup, xtensa_delete_cached_fixup), - (xtensa_add_cached_fixup): New functions. - (xtensa_relax_frag): Cache fixups pointing at potentially - oversized jumps at the beginning of every relaxation pass. Only - check subset of this cache in the reach of single jump from the - trampoline frag currently being relaxed. - -Signed-off-by: Max Filippov ---- -Backported from: b76f99d702c3501ac320396ea06bc7f9237173c3 -Changes to ChangeLog are dropped. - - gas/config/tc-xtensa.c | 220 +++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 194 insertions(+), 26 deletions(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 3e85b69..31c0b6b 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -8785,6 +8785,154 @@ static long relax_frag_for_align (fragS *, long); - static long relax_frag_immed - (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean); - -+typedef struct cached_fixup cached_fixupS; -+struct cached_fixup -+{ -+ int addr; -+ int target; -+ int delta; -+ fixS *fixP; -+}; -+ -+typedef struct fixup_cache fixup_cacheS; -+struct fixup_cache -+{ -+ cached_fixupS *fixups; -+ unsigned n_fixups; -+ unsigned n_max; -+ -+ segT seg; -+ fragS *first_frag; -+}; -+ -+static int fixup_order (const void *a, const void *b) -+{ -+ const cached_fixupS *pa = a; -+ const cached_fixupS *pb = b; -+ -+ if (pa->addr == pb->addr) -+ { -+ if (pa->target == pb->target) -+ { -+ if (pa->fixP->fx_r_type == pb->fixP->fx_r_type) -+ return 0; -+ return pa->fixP->fx_r_type < pb->fixP->fx_r_type ? -1 : 1; -+ } -+ return pa->target - pb->target; -+ } -+ return pa->addr - pb->addr; -+} -+ -+static bfd_boolean xtensa_make_cached_fixup (cached_fixupS *o, fixS *fixP) -+{ -+ xtensa_isa isa = xtensa_default_isa; -+ int addr = fixP->fx_frag->fr_address; -+ int target; -+ int delta; -+ symbolS *s = fixP->fx_addsy; -+ int slot; -+ xtensa_format fmt; -+ xtensa_opcode opcode; -+ -+ if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -+ fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -+ return FALSE; -+ target = S_GET_VALUE (s); -+ delta = target - addr; -+ -+ if (abs(delta) < J_RANGE / 2) -+ return FALSE; -+ -+ xtensa_insnbuf_from_chars (isa, trampoline_buf, -+ (unsigned char *) fixP->fx_frag->fr_literal + -+ fixP->fx_where, 0); -+ fmt = xtensa_format_decode (isa, trampoline_buf); -+ gas_assert (fmt != XTENSA_UNDEFINED); -+ slot = fixP->tc_fix_data.slot; -+ xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -+ opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -+ if (opcode != xtensa_j_opcode) -+ return FALSE; -+ -+ o->addr = addr; -+ o->target = target; -+ o->delta = delta; -+ o->fixP = fixP; -+ -+ return TRUE; -+} -+ -+static void xtensa_realloc_fixup_cache (fixup_cacheS *cache, unsigned add) -+{ -+ if (cache->n_fixups + add > cache->n_max) -+ { -+ cache->n_max = (cache->n_fixups + add) * 2; -+ cache->fixups = xrealloc (cache->fixups, -+ sizeof (*cache->fixups) * cache->n_max); -+ } -+} -+ -+static void xtensa_cache_relaxable_fixups (fixup_cacheS *cache, -+ segment_info_type *seginfo) -+{ -+ fixS *fixP; -+ -+ cache->n_fixups = 0; -+ -+ for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ { -+ xtensa_realloc_fixup_cache (cache, 1); -+ -+ if (xtensa_make_cached_fixup (cache->fixups + cache->n_fixups, fixP)) -+ ++cache->n_fixups; -+ } -+ qsort (cache->fixups, cache->n_fixups, sizeof (*cache->fixups), fixup_order); -+} -+ -+static unsigned xtensa_find_first_cached_fixup (const fixup_cacheS *cache, -+ int addr) -+{ -+ unsigned a = 0; -+ unsigned b = cache->n_fixups; -+ -+ while (b - a > 1) -+ { -+ unsigned c = (a + b) / 2; -+ -+ if (cache->fixups[c].addr < addr) -+ a = c; -+ else -+ b = c; -+ } -+ return a; -+} -+ -+static void xtensa_delete_cached_fixup (fixup_cacheS *cache, unsigned i) -+{ -+ memmove (cache->fixups + i, cache->fixups + i + 1, -+ (cache->n_fixups - i - 1) * sizeof (*cache->fixups)); -+ --cache->n_fixups; -+} -+ -+static bfd_boolean xtensa_add_cached_fixup (fixup_cacheS *cache, fixS *fixP) -+{ -+ cached_fixupS o; -+ unsigned i; -+ -+ if (!xtensa_make_cached_fixup (&o, fixP)) -+ return FALSE; -+ xtensa_realloc_fixup_cache (cache, 1); -+ i = xtensa_find_first_cached_fixup (cache, o.addr); -+ if (i < cache->n_fixups) -+ { -+ ++i; -+ memmove (cache->fixups + i + 1, cache->fixups + i, -+ (cache->n_fixups - i) * sizeof (*cache->fixups)); -+ } -+ cache->fixups[i] = o; -+ ++cache->n_fixups; -+ return TRUE; -+} - - /* Return the number of bytes added to this fragment, given that the - input has been stretched already by "stretch". */ -@@ -8896,35 +9044,42 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - case RELAX_TRAMPOLINE: - if (fragP->tc_frag_data.relax_seen) - { -- segment_info_type *seginfo = seg_info (now_seg); -- fragS *fP; /* The out-of-range jump. */ -- fixS *fixP; -+ static fixup_cacheS fixup_cache; -+ segment_info_type *seginfo = seg_info (now_seg); -+ int trampaddr = fragP->fr_address + fragP->fr_fix; -+ int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE; -+ unsigned i; -+ -+ if (now_seg != fixup_cache.seg || -+ fragP == fixup_cache.first_frag || -+ fixup_cache.first_frag == NULL) -+ { -+ xtensa_cache_relaxable_fixups (&fixup_cache, seginfo); -+ fixup_cache.seg = now_seg; -+ fixup_cache.first_frag = fragP; -+ } - - /* Scan for jumps that will not reach. */ -- for (fixP = seginfo->fix_root; fixP ; fixP = fixP->fx_next) -+ for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr); -+ i < fixup_cache.n_fixups; ++i) -+ - { -- symbolS *s = fixP->fx_addsy; -- xtensa_opcode opcode; -- int target; -- int addr; -- int delta; -- -- if (fixP->fx_r_type < BFD_RELOC_XTENSA_SLOT0_OP || -- fixP->fx_r_type > BFD_RELOC_XTENSA_SLOT14_OP) -- continue; -- xtensa_insnbuf_from_chars (isa, trampoline_buf, -- (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where, -- 0); -- fmt = xtensa_format_decode (isa, trampoline_buf); -- gas_assert (fmt != XTENSA_UNDEFINED); -- slot = fixP->tc_fix_data.slot; -- xtensa_format_get_slot (isa, fmt, slot, trampoline_buf, trampoline_slotbuf); -- opcode = xtensa_opcode_decode (isa, fmt, slot, trampoline_slotbuf); -- if (opcode != xtensa_j_opcode) -+ fixS *fixP = fixup_cache.fixups[i].fixP; -+ int target = fixup_cache.fixups[i].target; -+ int addr = fixup_cache.fixups[i].addr; -+ int delta = fixup_cache.fixups[i].delta + stretch; -+ -+ trampaddr = fragP->fr_address + fragP->fr_fix; -+ -+ if (addr + J_RANGE < trampaddr) - continue; -- target = S_GET_VALUE (s); -- addr = fixP->fx_frag->fr_address; -- delta = target - addr + stretch; -+ if (addr > trampaddr + J_RANGE) -+ break; -+ if (abs (delta) < J_RANGE) -+ continue; -+ -+ slot = fixP->tc_fix_data.slot; -+ - if (delta > J_RANGE || delta < -1 * J_RANGE) - { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ - struct trampoline_seg *ts = find_trampoline_seg (now_seg); -@@ -8978,14 +9133,13 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - } - if (tf->fragP == fragP) - { -- int trampaddr = fragP->fr_address + fragP->fr_fix; -- - if (abs (addr - trampaddr) < J_RANGE) - { /* The trampoline is in range of original; fix it! */ - fixS *newfixP; - int offset; - TInsn insn; - symbolS *lsym; -+ fragS *fP; /* The out-of-range jump. */ - - new_stretch += init_trampoline_frag (tf); - offset = fragP->fr_fix; /* Where to assemble the j insn. */ -@@ -9009,10 +9163,20 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - newfixP->tc_fix_data.X_add_symbol = lsym; - newfixP->tc_fix_data.X_add_number = offset; - newfixP->tc_fix_data.slot = slot; -+ -+ xtensa_delete_cached_fixup (&fixup_cache, i); -+ xtensa_add_cached_fixup (&fixup_cache, newfixP); -+ - /* Move the fix-up from the original j insn to this one. */ - fixP->fx_frag = fragP; - fixP->fx_where = fragP->fr_fix - 3; - fixP->tc_fix_data.slot = 0; -+ -+ xtensa_add_cached_fixup (&fixup_cache, fixP); -+ -+ /* re-do current fixup */ -+ --i; -+ - /* Adjust the jump around this trampoline (if present). */ - if (tf->fixP != NULL) - { -@@ -9027,6 +9191,8 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - fragP->fr_subtype = 0; - /* Remove from the trampoline_list. */ - prev->next = tf->next; -+ if (fragP == fixup_cache.first_frag) -+ fixup_cache.first_frag = NULL; - break; - } - } --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch b/patches/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch deleted file mode 100644 index 9ad6b3b..0000000 --- a/patches/binutils/2.25.1/911-xtensa-fix-localized-symbol-refcounting-with-gc-sect.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Thu, 14 May 2015 05:22:55 +0300 -Subject: [PATCH] xtensa: fix localized symbol refcounting with --gc-sections - -elf_xtensa_gc_sweep_hook doesn't correctly unreference symbols that were -made local, that results in link failure with the following message: - - BFD (GNU Binutils) 2.24 internal error, aborting at elf32-xtensa.c line - 3372 in elf_xtensa_finish_dynamic_sections - -elf_xtensa_gc_sweep_hook determines symbol reference type (PLT or GOT) by -relocation type. Relocation types are not changed when symbol becomes -local, but its PLT references are added to GOT references and -plt.refcount is set to 0. Such symbol cannot be unreferences in the -elf_xtensa_gc_sweep_hook and its extra references make calculated GOT -relocations section size not match number of GOT relocations. - -Fix it by treating PLT reference as GOT reference when plt.refcount is -not positive. - -2015-05-14 Max Filippov -bfd/ - * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Treat PLT reference - as GOT reference when plt.refcount is not positive. - -Signed-off-by: Max Filippov ---- -Backported from: e6c9a083ec5ae7a45bd71682b26aae1939849388 -Changes to ChangeLog are dropped. - - bfd/elf32-xtensa.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c -index 53af1c6..2523670 100644 ---- a/bfd/elf32-xtensa.c -+++ b/bfd/elf32-xtensa.c -@@ -1360,10 +1360,14 @@ elf_xtensa_gc_sweep_hook (bfd *abfd, - { - if (is_plt) - { -+ /* If the symbol has been localized its plt.refcount got moved -+ to got.refcount. Handle it as GOT. */ - if (h->plt.refcount > 0) - h->plt.refcount--; -+ else -+ is_got = TRUE; - } -- else if (is_got) -+ if (is_got) - { - if (h->got.refcount > 0) - h->got.refcount--; --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch b/patches/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch deleted file mode 100644 index 4a3de2c..0000000 --- a/patches/binutils/2.25.1/912-xtensa-fix-gas-segfault-with-text-section-literals.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Sun, 17 May 2015 06:46:15 +0300 -Subject: [PATCH] xtensa: fix gas segfault with --text-section-literals - -When --text-section-literals is used and code in the .init or .fini -emits literal in the absence of .literal_position, xtensa_move_literals -segfaults. - -Check that search_frag is non-NULL in the xtensa_move_literals and -report error otherwise. - -2015-05-26 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Check that - search_frag is non-NULL. Report error if literal frag is not - found. - -Signed-off-by: Max Filippov ---- -Backported from: 4de0562a4c69fef4952aa7e19d7bda359f02e8b4 -Changes to ChangeLog are dropped. - - gas/config/tc-xtensa.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 31c0b6b..18307c1 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -10808,13 +10808,21 @@ xtensa_move_literals (void) - frchain_to = NULL; - frag_splice = &(frchain_from->frch_root); - -- while (!search_frag->tc_frag_data.literal_frag) -+ while (search_frag && !search_frag->tc_frag_data.literal_frag) - { - gas_assert (search_frag->fr_fix == 0 - || search_frag->fr_type == rs_align); - search_frag = search_frag->fr_next; - } - -+ if (!search_frag) -+ { -+ search_frag = frchain_from->frch_root; -+ as_bad_where (search_frag->fr_file, search_frag->fr_line, -+ _("literal pool location required for text-section-literals; specify with .literal_position")); -+ continue; -+ } -+ - gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype - == RELAX_LITERAL_POOL_BEGIN); - xtensa_switch_section_emit_state (&state, segment->seg, 0); --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch b/patches/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch deleted file mode 100644 index 3ed9af1..0000000 --- a/patches/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch +++ /dev/null @@ -1,699 +0,0 @@ -From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Wed, 29 Jul 2015 17:42:54 +0300 -Subject: [PATCH] xtensa: add --auto-litpools option - -Auto-litpools is the automated version of text-section-literals: literal -pool candidate frags are planted every N frags and during relaxation -they are turned into actual literal pools where literals are moved to -become reachable for their first reference by L32R instruction. - -2015-08-12 David Weatherford -gas/ - * config/tc-xtensa.c (struct litpool_frag, struct litpool_seg): - New structures. - (xtensa_maybe_create_literal_pool_frag): New function. - (litpool_seg_list, auto_litpools, auto_litpool_limit) - (litpool_buf, litpool_slotbuf): New static variables. - (option_auto_litpools, option_no_auto_litpools) - (option_auto_litpool_limit): New enum identifiers. - (md_longopts): Add entries for auto-litpools, no-auto-litpools - and auto-litpool-limit. - (md_parse_option): Handle option_auto_litpools, - option_no_auto_litpools and option_auto_litpool_limit. - (md_show_usage): Add help for --[no-]auto-litpools and - --auto-litpool-limit. - (xtensa_mark_literal_pool_location): Record a place for literal - pool with a call to xtensa_maybe_create_literal_pool_frag. - (get_literal_pool_location): Find highest priority literal pool - or convert candidate to literal pool when auto-litpools are used. - (xg_assemble_vliw_tokens): Create literal pool after jump - instruction. - (xtensa_check_frag_count): Create candidate literal pool every - auto_litpool_limit frags. - (xtensa_relax_frag): Add jump around literals to non-empty - literal pool. - (xtensa_move_literals): Estimate literal pool addresses and move - unreachable literals closer to their users, converting candidate - to literal pool if needed. - (xtensa_switch_to_non_abs_literal_fragment): Only emit error - about missing .literal_position in case auto-litpools are not - used. - * config/tc-xtensa.h (xtensa_relax_statesE): New relaxation - state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN. - -2015-08-12 Max Filippov -gas/testsuite/ - * gas/xtensa/all.exp: Add auto-litpools to the list of xtensa - tests. - * gas/xtensa/auto-litpools.s: New file: auto-litpools test. - * gas/xtensa/auto-litpools.s: New file: auto-litpools test - result pattern. - -Signed-off-by: Max Filippov ---- -Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5 -Changes to ChangeLogs and documentation are dropped. - - gas/config/tc-xtensa.c | 432 ++++++++++++++++++++++++++++++- - gas/config/tc-xtensa.h | 1 + - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/auto-litpools.d | 12 + - gas/testsuite/gas/xtensa/auto-litpools.s | 13 + - 5 files changed, 454 insertions(+), 5 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d - create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 7311a05..b8b1e7d 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -440,6 +440,29 @@ bfd_boolean directive_state[] = - #endif - }; - -+/* A circular list of all potential and actual literal pool locations -+ in a segment. */ -+struct litpool_frag -+{ -+ struct litpool_frag *next; -+ struct litpool_frag *prev; -+ fragS *fragP; -+ addressT addr; -+ short priority; /* 1, 2, or 3 -- 1 is highest */ -+ short original_priority; -+}; -+ -+/* Map a segment to its litpool_frag list. */ -+struct litpool_seg -+{ -+ struct litpool_seg *next; -+ asection *seg; -+ struct litpool_frag frag_list; -+ int frag_count; /* since last litpool location */ -+}; -+ -+static struct litpool_seg litpool_seg_list; -+ - - /* Directive functions. */ - -@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean); - static void xtensa_maybe_create_trampoline_frag (void); - struct trampoline_frag; - static int init_trampoline_frag (struct trampoline_frag *); -+static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean); -+static bfd_boolean auto_litpools = FALSE; -+static int auto_litpool_limit = 10000; - - /* Alignment Functions. */ - -@@ -698,6 +724,10 @@ enum - - option_trampolines, - option_no_trampolines, -+ -+ option_auto_litpools, -+ option_no_auto_litpools, -+ option_auto_litpool_limit, - }; - - const char *md_shortopts = ""; -@@ -773,6 +803,10 @@ struct option md_longopts[] = - { "trampolines", no_argument, NULL, option_trampolines }, - { "no-trampolines", no_argument, NULL, option_no_trampolines }, - -+ { "auto-litpools", no_argument, NULL, option_auto_litpools }, -+ { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools }, -+ { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit }, -+ - { NULL, no_argument, NULL, 0 } - }; - -@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg) - use_trampolines = FALSE; - return 1; - -+ case option_auto_litpools: -+ auto_litpools = TRUE; -+ use_literal_section = FALSE; -+ return 1; -+ -+ case option_no_auto_litpools: -+ auto_litpools = FALSE; -+ auto_litpool_limit = -1; -+ return 1; -+ -+ case option_auto_litpool_limit: -+ { -+ int value = 0; -+ if (auto_litpool_limit < 0) -+ as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit")); -+ if (*arg == 0 || *arg == '-') -+ as_fatal (_("invalid auto-litpool-limit argument")); -+ value = strtol (arg, &arg, 10); -+ if (*arg != 0) -+ as_fatal (_("invalid auto-litpool-limit argument")); -+ if (value < 100 || value > 10000) -+ as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)")); -+ auto_litpool_limit = value; -+ auto_litpools = TRUE; -+ use_literal_section = FALSE; -+ return 1; -+ } -+ - default: - return 0; - } -@@ -986,7 +1048,12 @@ Xtensa options:\n\ - flix bundles\n\ - --rename-section old=new Rename section 'old' to 'new'\n\ - --[no-]trampolines [Do not] generate trampolines (jumps to jumps)\n\ -- when jumps do not reach their targets\n", stream); -+ when jumps do not reach their targets\n\ -+ --[no-]auto-litpools [Do not] automatically create literal pools\n\ -+ --auto-litpool-limit=\n\ -+ (range 100-10000) Maximum number of blocks of\n\ -+ instructions to emit between literal pool\n\ -+ locations; implies --auto-litpools flag\n", stream); - } - - -@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void) - pool_location = frag_now; - frag_now->tc_frag_data.lit_frchain = frchain_now; - frag_now->tc_frag_data.literal_frag = frag_now; -+ /* Just record this frag. */ -+ xtensa_maybe_create_literal_pool_frag (FALSE, FALSE); - frag_variant (rs_machine_dependent, 0, 0, - RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL); - xtensa_set_frag_assembly_state (frag_now); -@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode) - static fragS * - get_literal_pool_location (segT seg) - { -+ struct litpool_seg *lps = litpool_seg_list.next; -+ struct litpool_frag *lpf; -+ for ( ; lps && lps->seg->id != seg->id; lps = lps->next) -+ ; -+ if (lps) -+ { -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { /* Skip "candidates" for now. */ -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && -+ lpf->priority == 1) -+ return lpf->fragP; -+ } -+ /* Must convert a lower-priority pool. */ -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) -+ return lpf->fragP; -+ } -+ /* Still no match -- try for a low priority pool. */ -+ for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) -+ { -+ if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) -+ return lpf->fragP; -+ } -+ } - return seg_info (seg)->tc_segment_info_data.literal_pool_loc; - } - -@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol; - frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset; - frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag; -+ if (tinsn->opcode == xtensa_l32r_opcode) -+ { -+ frag_now->tc_frag_data.literal_frags[slot] = -+ tinsn->tok[1].X_add_symbol->sy_frag; -+ } - if (tinsn->literal_space != 0) - xg_assemble_literal_space (tinsn->literal_space, slot); - frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg; -@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn) - frag_now->fr_symbol, frag_now->fr_offset, NULL); - xtensa_set_frag_assembly_state (frag_now); - xtensa_maybe_create_trampoline_frag (); -+ /* Always create one here. */ -+ xtensa_maybe_create_literal_pool_frag (TRUE, FALSE); - } - else if (is_branch && do_align_targets ()) - { -@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void) - clear_frag_count (); - unreachable_count = 0; - } -+ -+ /* We create an area for a possible literal pool every N (default 5000) -+ frags or so. */ -+ xtensa_maybe_create_literal_pool_frag (TRUE, TRUE); - } - - static xtensa_insnbuf trampoline_buf = NULL; - static xtensa_insnbuf trampoline_slotbuf = NULL; - -+static xtensa_insnbuf litpool_buf = NULL; -+static xtensa_insnbuf litpool_slotbuf = NULL; -+ - #define TRAMPOLINE_FRAG_SIZE 3000 - - static void -@@ -7410,6 +7518,135 @@ dump_trampolines (void) - } - } - -+static void dump_litpools (void) __attribute__ ((unused)); -+ -+static void -+dump_litpools (void) -+{ -+ struct litpool_seg *lps = litpool_seg_list.next; -+ struct litpool_frag *lpf; -+ -+ for ( ; lps ; lps = lps->next ) -+ { -+ printf("litpool seg %s\n", lps->seg->name); -+ for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next ) -+ { -+ fragS *litfrag = lpf->fragP->fr_next; -+ int count = 0; -+ while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END) -+ { -+ if (litfrag->fr_fix == 4) -+ count++; -+ litfrag = litfrag->fr_next; -+ } -+ printf(" %ld <%d:%d> (%d) [%d]: ", -+ lpf->addr, lpf->priority, lpf->original_priority, -+ lpf->fragP->fr_line, count); -+ //dump_frag(lpf->fragP); -+ } -+ } -+} -+ -+static void -+xtensa_maybe_create_literal_pool_frag (bfd_boolean create, -+ bfd_boolean only_if_needed) -+{ -+ struct litpool_seg *lps = litpool_seg_list.next; -+ fragS *fragP; -+ struct litpool_frag *lpf; -+ bfd_boolean needed = FALSE; -+ -+ if (use_literal_section || !auto_litpools) -+ return; -+ -+ for ( ; lps ; lps = lps->next ) -+ { -+ if (lps->seg == now_seg) -+ break; -+ } -+ -+ if (lps == NULL) -+ { -+ lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1); -+ lps->next = litpool_seg_list.next; -+ litpool_seg_list.next = lps; -+ lps->seg = now_seg; -+ lps->frag_list.next = &lps->frag_list; -+ lps->frag_list.prev = &lps->frag_list; -+ } -+ -+ lps->frag_count++; -+ -+ if (create) -+ { -+ if (only_if_needed) -+ { -+ if (past_xtensa_end || !use_transform() || -+ frag_now->tc_frag_data.is_no_transform) -+ { -+ return; -+ } -+ if (auto_litpool_limit <= 0) -+ { -+ /* Don't create a litpool based only on frag count. */ -+ return; -+ } -+ else if (lps->frag_count > auto_litpool_limit) -+ { -+ needed = TRUE; -+ } -+ else -+ { -+ return; -+ } -+ } -+ else -+ { -+ needed = TRUE; -+ } -+ } -+ -+ if (needed) -+ { -+ int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn. */ -+ /* Create a potential site for a literal pool. */ -+ frag_wane (frag_now); -+ frag_new (0); -+ xtensa_set_frag_assembly_state (frag_now); -+ fragP = frag_now; -+ fragP->tc_frag_data.lit_frchain = frchain_now; -+ fragP->tc_frag_data.literal_frag = fragP; -+ frag_var (rs_machine_dependent, size, size, -+ (only_if_needed) ? -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN : -+ RELAX_LITERAL_POOL_BEGIN, -+ NULL, 0, NULL); -+ frag_now->tc_frag_data.lit_seg = now_seg; -+ frag_variant (rs_machine_dependent, 0, 0, -+ RELAX_LITERAL_POOL_END, NULL, 0, NULL); -+ xtensa_set_frag_assembly_state (frag_now); -+ } -+ else -+ { -+ /* RELAX_LITERAL_POOL_BEGIN frag is being created; -+ just record it here. */ -+ fragP = frag_now; -+ } -+ -+ lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag)); -+ /* Insert at tail of circular list. */ -+ lpf->addr = 0; -+ lps->frag_list.prev->next = lpf; -+ lpf->next = &lps->frag_list; -+ lpf->prev = lps->frag_list.prev; -+ lps->frag_list.prev = lpf; -+ lpf->fragP = fragP; -+ lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1; -+ lpf->original_priority = lpf->priority; -+ -+ lps->frag_count = 0; -+} -+ - static void - xtensa_cleanup_align_frags (void) - { -@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) - break; - - case RELAX_LITERAL_POOL_BEGIN: -+ if (fragP->fr_var != 0) -+ { -+ /* We have a converted "candidate" literal pool; -+ assemble a jump around it. */ -+ TInsn insn; -+ if (!litpool_slotbuf) -+ { -+ litpool_buf = xtensa_insnbuf_alloc (isa); -+ litpool_slotbuf = xtensa_insnbuf_alloc (isa); -+ } -+ new_stretch += 3; -+ fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass. */ -+ fragP->tc_frag_data.is_insn = TRUE; -+ tinsn_init (&insn); -+ insn.insn_type = ITYPE_INSN; -+ insn.opcode = xtensa_j_opcode; -+ insn.ntok = 1; -+ set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol, -+ fragP->fr_fix); -+ fmt = xg_get_single_format (xtensa_j_opcode); -+ tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf); -+ xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf); -+ xtensa_insnbuf_to_chars (isa, litpool_buf, -+ (unsigned char *)fragP->fr_literal + -+ fragP->fr_fix, 3); -+ fragP->fr_fix += 3; -+ fragP->fr_var -= 3; -+ /* Add a fix-up. */ -+ fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE, -+ BFD_RELOC_XTENSA_SLOT0_OP); -+ } -+ break; -+ - case RELAX_LITERAL_POOL_END: -+ case RELAX_LITERAL_POOL_CANDIDATE_BEGIN: - case RELAX_MAYBE_UNREACHABLE: - case RELAX_MAYBE_DESIRE_ALIGN: - /* No relaxation required. */ -@@ -10789,12 +11060,115 @@ xtensa_move_literals (void) - segT dest_seg; - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; -+ struct litpool_seg *lps; - - mark_literal_frags (literal_head->next); - - if (use_literal_section) - return; - -+ /* Assign addresses (rough estimates) to the potential literal pool locations -+ and create new ones if the gaps are too large. */ -+ -+ for (lps = litpool_seg_list.next; lps; lps = lps->next) -+ { -+ frchainS *frchP = seg_info (lps->seg)->frchainP; -+ struct litpool_frag *lpf = lps->frag_list.next; -+ addressT addr = 0; -+ -+ for ( ; frchP; frchP = frchP->frch_next) -+ { -+ fragS *fragP; -+ for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next) -+ { -+ if (lpf && fragP == lpf->fragP) -+ { -+ gas_assert(fragP->fr_type == rs_machine_dependent && -+ (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN || -+ fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)); -+ /* Found a litpool location. */ -+ lpf->addr = addr; -+ lpf = lpf->next; -+ } -+ if (fragP->fr_type == rs_machine_dependent && -+ fragP->fr_subtype == RELAX_SLOTS) -+ { -+ int slot; -+ for (slot = 0; slot < MAX_SLOTS; slot++) -+ { -+ if (fragP->tc_frag_data.literal_frags[slot]) -+ { -+ /* L32R; point its literal to the nearest litpool -+ preferring non-"candidate" positions to avoid -+ the jump-around. */ -+ fragS *litfrag = fragP->tc_frag_data.literal_frags[slot]; -+ struct litpool_frag *lp = lpf->prev; -+ if (!lp->fragP) -+ { -+ break; -+ } -+ while (lp->fragP->fr_subtype == -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN) -+ { -+ lp = lp->prev; -+ if (lp->fragP == NULL) -+ { -+ /* End of list; have to bite the bullet. -+ Take the nearest. */ -+ lp = lpf->prev; -+ break; -+ } -+ /* Does it (conservatively) reach? */ -+ if (addr - lp->addr <= 128 * 1024) -+ { -+ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) -+ { -+ /* Found a good one. */ -+ break; -+ } -+ else if (lp->prev->fragP && -+ addr - lp->prev->addr > 128 * 1024) -+ { -+ /* This is still a "candidate" but the next one -+ will be too far away, so revert to the nearest -+ one, convert it and add the jump around. */ -+ fragS *poolbeg; -+ fragS *poolend; -+ symbolS *lsym; -+ char label[10 + 2 * sizeof (fragS *)]; -+ lp = lpf->prev; -+ poolbeg = lp->fragP; -+ lp->priority = 1; -+ poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; -+ poolend = poolbeg->fr_next; -+ gas_assert (poolend->fr_type == rs_machine_dependent && -+ poolend->fr_subtype == RELAX_LITERAL_POOL_END); -+ /* Create a local symbol pointing to the -+ end of the pool. */ -+ sprintf (label, ".L0_LT_%p", poolbeg); -+ lsym = (symbolS *)local_symbol_make (label, lps->seg, -+ 0, poolend); -+ poolbeg->fr_symbol = lsym; -+ /* Rest is done in xtensa_relax_frag. */ -+ } -+ } -+ } -+ if (! litfrag->tc_frag_data.literal_frag) -+ { -+ /* Take earliest use of this literal to avoid -+ forward refs. */ -+ litfrag->tc_frag_data.literal_frag = lp->fragP; -+ } -+ } -+ } -+ } -+ addr += fragP->fr_fix; -+ if (fragP->fr_type == rs_fill) -+ addr += fragP->fr_offset; -+ } -+ } -+ } -+ - for (segment = literal_head->next; segment; segment = segment->next) - { - /* Keep the literals for .init and .fini in separate sections. */ -@@ -10839,9 +11213,6 @@ xtensa_move_literals (void) - while (search_frag != frag_now) - { - next_frag = search_frag->fr_next; -- -- /* First, move the frag out of the literal section and -- to the appropriate place. */ - if (search_frag->tc_frag_data.literal_frag) - { - literal_pool = search_frag->tc_frag_data.literal_frag; -@@ -10849,8 +11220,56 @@ xtensa_move_literals (void) - frchain_to = literal_pool->tc_frag_data.lit_frchain; - gas_assert (frchain_to); - } -+ -+ if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0) -+ { -+ /* Skip empty fill frags. */ -+ *frag_splice = next_frag; -+ search_frag = next_frag; -+ continue; -+ } -+ -+ if (search_frag->fr_type == rs_align) -+ { -+ /* Skip alignment frags, because the pool as a whole will be -+ aligned if used, and we don't want to force alignment if the -+ pool is unused. */ -+ *frag_splice = next_frag; -+ search_frag = next_frag; -+ continue; -+ } -+ -+ /* First, move the frag out of the literal section and -+ to the appropriate place. */ -+ -+ /* Insert an aligmnent frag at start of pool. */ -+ if (literal_pool->fr_next->fr_type == rs_machine_dependent && -+ literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END) -+ { -+ segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg; -+ emit_state prev_state; -+ fragS *prev_frag; -+ fragS *align_frag; -+ xtensa_switch_section_emit_state (&prev_state, pool_seg, 0); -+ prev_frag = frag_now; -+ frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL); -+ align_frag = frag_now; -+ frag_align (2, 0, 0); -+ /* Splice it into the right place. */ -+ prev_frag->fr_next = align_frag->fr_next; -+ align_frag->fr_next = literal_pool->fr_next; -+ literal_pool->fr_next = align_frag; -+ /* Insert after this one. */ -+ literal_pool->tc_frag_data.literal_frag = align_frag; -+ xtensa_restore_emit_state (&prev_state); -+ } - insert_after = literal_pool->tc_frag_data.literal_frag; - dest_seg = insert_after->fr_next->tc_frag_data.lit_seg; -+ /* Skip align frag. */ -+ if (insert_after->fr_next->fr_type == rs_align) -+ { -+ insert_after = insert_after->fr_next; -+ } - - *frag_splice = next_frag; - search_frag->fr_next = insert_after->fr_next; -@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) - && !recursive - && !is_init && ! is_fini) - { -- as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); -+ if (!auto_litpools) -+ { -+ as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); -+ } - - /* When we mark a literal pool location, we want to put a frag in - the literal pool that points to it. But to do that, we want to -diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h -index b2e43fa..290d902 100644 ---- a/gas/config/tc-xtensa.h -+++ b/gas/config/tc-xtensa.h -@@ -124,6 +124,7 @@ enum xtensa_relax_statesE - - RELAX_LITERAL_POOL_BEGIN, - RELAX_LITERAL_POOL_END, -+ RELAX_LITERAL_POOL_CANDIDATE_BEGIN, - /* Technically these are not relaxations at all but mark a location - to store literals later. Note that fr_var stores the frchain for - BEGIN frags and fr_var stores now_seg for END frags. */ -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index d197ec8..db39629 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -100,6 +100,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "jlong" - run_dump_test "trampoline" - run_dump_test "first_frag_align" -+ run_dump_test "auto-litpools" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d -new file mode 100644 -index 0000000..4d1a690 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/auto-litpools.d -@@ -0,0 +1,12 @@ -+#as: --auto-litpools -+#objdump: -d -+#name: auto literal pool placement -+ -+.*: +file format .*xtensa.* -+#... -+.*4:.*l32r.a2, 0 .* -+#... -+.*3e437:.*j.3e440 .* -+#... -+.*40750:.*l32r.a2, 3e43c .* -+#... -diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s -new file mode 100644 -index 0000000..9a5b26b ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/auto-litpools.s -@@ -0,0 +1,13 @@ -+ .text -+ .align 4 -+ .literal .L0, 0x12345 -+ .literal .L1, 0x12345 -+ -+f: -+ l32r a2, .L0 -+ .rep 44000 -+ _nop -+ _nop -+ .endr -+ l32r a2, .L1 -+ ret --- -1.8.1.4 - diff --git a/patches/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch b/patches/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch deleted file mode 100644 index 66d4e60..0000000 --- a/patches/binutils/2.25.1/914-xtensa-fix-signedness-of-gas-relocations.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 2 Feb 2016 17:11:38 +0300 -Subject: [PATCH] xtensa: fix signedness of gas relocations - -Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation -offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations -substituted for BFD_RELOC_*. This made it impossible to encode arbitrary -8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc -directive. Revert this part and add test. - -gas/ -2016-02-03 Max Filippov - * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* - substitutions for BFD_RELOC_* as unsigned. - * gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa - tests. - * gas/testsuite/gas/xtensa/loc.d: New file: loc test result - patterns. - * gas/testsuite/gas/xtensa/loc.s: New file: loc test. - -Signed-off-by: Max Filippov ---- - gas/config/tc-xtensa.c | 6 +++--- - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/loc.d | 10 ++++++++++ - gas/testsuite/gas/xtensa/loc.s | 7 +++++++ - 4 files changed, 21 insertions(+), 3 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/loc.d - create mode 100644 gas/testsuite/gas/xtensa/loc.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index a119871..36a06cc 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - default: - break; -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 31b725b..7ff7bd7 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -101,6 +101,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "trampoline" - run_dump_test "first_frag_align" - run_dump_test "auto-litpools" -+ run_dump_test "loc" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/loc.d b/gas/testsuite/gas/xtensa/loc.d -new file mode 100644 -index 0000000..71983cc ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/loc.d -@@ -0,0 +1,10 @@ -+#as: -+#objdump: -r -+#name: .loc directive relocs -+ -+.*: +file format .*xtensa.* -+ -+RELOCATION RECORDS FOR \[\.debug_line\]: -+#... -+.*R_XTENSA_DIFF16.*\.text\+0x00009c42 -+#... -diff --git a/gas/testsuite/gas/xtensa/loc.s b/gas/testsuite/gas/xtensa/loc.s -new file mode 100644 -index 0000000..029e14e ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/loc.s -@@ -0,0 +1,7 @@ -+ .text -+ .file 1 "loc.s" -+ .loc 1 3 -+ nop -+ .space 40000 -+ .loc 1 5 -+ nop --- -2.1.4 - diff --git a/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch deleted file mode 100644 index ead3e42..0000000 --- a/patches/binutils/2.25.1/915-xtensa-fix-.init-.fini-literals-moving.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 16 Feb 2016 02:23:28 +0300 -Subject: [PATCH] xtensa: fix .init/.fini literals moving - -Despite the documentation and the comment in xtensa_move_literals, in -the presence of --text-section-literals and --auto-litpools literals are -moved from the separate literal sections into .init and .fini, because -the check in the xtensa_move_literals is incorrect. - -This moving was broken with introduction of auto litpools: some literals -now may be lost. This happens because literal frags emitted from .init -and .fini are not closed when new .literal_position marks new literal -pool. Then frag_align(2, 0, 0) changes type of the last literal frag to -rs_align. rs_align frags are skipped in the xtensa_move_literals. As a -result fixups against such literals are not moved out of .init.literal/ -.fini.literal sections producing the following assembler error: - - test.S: Warning: fixes not all moved from .init.literal - test.S: Internal error! - -Fix check for .init.literal/.fini.literal in the xtensa_move_literals -and don't let it move literals from there in the presence of ---text-section-literals or --auto-litpools. - -2016-02-17 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Fix check for - .init.literal/.fini.literal section name. - * testsuite/gas/xtensa/all.exp: Add init-fini-literals to the - list of xtensa tests. - * testsuite/gas/xtensa/init-fini-literals.d: New file: - init-fini-literals test result patterns. - * testsuite/gas/xtensa/init-fini-literals.s: New file: - init-fini-literals test. - -Signed-off-by: Max Filippov ---- -Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 - - gas/config/tc-xtensa.c | 12 ++++++++++-- - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ - gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ - 4 files changed, 54 insertions(+), 2 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d - create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 36a06cc..5773634 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; - struct litpool_seg *lps; -+ const char *init_name = INIT_SECTION_NAME; -+ const char *fini_name = FINI_SECTION_NAME; -+ int init_name_len = strlen(init_name); -+ int fini_name_len = strlen(fini_name); - - mark_literal_frags (literal_head->next); - -@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) - - for (segment = literal_head->next; segment; segment = segment->next) - { -+ const char *seg_name = segment_name (segment->seg); -+ - /* Keep the literals for .init and .fini in separate sections. */ -- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) -- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) -+ if ((!memcmp (seg_name, init_name, init_name_len) && -+ !strcmp (seg_name + init_name_len, ".literal")) || -+ (!memcmp (seg_name, fini_name, fini_name_len) && -+ !strcmp (seg_name + fini_name_len, ".literal"))) - continue; - - frchain_from = seg_info (segment->seg)->frchainP; -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 7ff7bd7..6b67320 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "first_frag_align" - run_dump_test "auto-litpools" - run_dump_test "loc" -+ run_dump_test "init-fini-literals" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d -new file mode 100644 -index 0000000..19ed121 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/init-fini-literals.d -@@ -0,0 +1,24 @@ -+#as: --text-section-literals -+#objdump: -r -+#name: check that literals for .init and .fini always go to separate sections -+ -+.*: +file format .*xtensa.* -+#... -+RELOCATION RECORDS FOR \[\.init\.literal\]: -+#... -+00000000 R_XTENSA_PLT init -+#... -+RELOCATION RECORDS FOR \[\.fini\.literal\]: -+#... -+00000000 R_XTENSA_PLT fini -+#... -+RELOCATION RECORDS FOR \[\.init\]: -+#... -+.* R_XTENSA_SLOT0_OP \.init\.literal -+.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 -+#... -+RELOCATION RECORDS FOR \[\.fini\]: -+#... -+.* R_XTENSA_SLOT0_OP \.fini\.literal -+.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 -+#... -diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s -new file mode 100644 -index 0000000..7c9ec17 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/init-fini-literals.s -@@ -0,0 +1,19 @@ -+ .section .init,"ax",@progbits -+ .literal_position -+ .literal .LC0, init@PLT -+ .literal_position -+ .literal .LC1, 1 -+ .align 4 -+ -+ l32r a2, .LC0 -+ l32r a2, .LC1 -+ -+ .section .fini,"ax",@progbits -+ .literal_position -+ .literal .LC2, fini@PLT -+ .literal_position -+ .literal .LC3, 1 -+ .align 4 -+ -+ l32r a2, .LC2 -+ l32r a2, .LC3 --- -2.1.4 - diff --git a/patches/binutils/2.26/120-sh-conf.patch b/patches/binutils/2.26/120-sh-conf.patch deleted file mode 100644 index c12a023..0000000 --- a/patches/binutils/2.26/120-sh-conf.patch +++ /dev/null @@ -1,33 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - -diff --git a/configure b/configure -index 87677bc..2d916f1 100755 ---- a/configure -+++ b/configure -@@ -3812,7 +3812,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; -diff --git a/configure.ac b/configure.ac -index 8fe0eca..b10a99f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1140,7 +1140,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.26/300-001_ld_makefile_patch.patch b/patches/binutils/2.26/300-001_ld_makefile_patch.patch deleted file mode 100644 index 2a1320c..0000000 --- a/patches/binutils/2.26/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/ld/Makefile.am b/ld/Makefile.am -index 9575f1f..84df0bf 100644 ---- a/ld/Makefile.am -+++ b/ld/Makefile.am -@@ -54,7 +54,7 @@ endif - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff --git a/ld/Makefile.in b/ld/Makefile.in -index 9f56ca1..272860f 100644 ---- a/ld/Makefile.in -+++ b/ld/Makefile.in -@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.26/300-012_check_ldrunpath_length.patch b/patches/binutils/2.26/300-012_check_ldrunpath_length.patch deleted file mode 100644 index f1f31af..0000000 --- a/patches/binutils/2.26/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em -index 137446f..bb8391a 100644 ---- a/ld/emultempl/elf32.em -+++ b/ld/emultempl/elf32.em -@@ -1195,6 +1195,8 @@ fragment <link.next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.26/310-fix-gold-pthreads-typo.patch b/patches/binutils/2.26/310-fix-gold-pthreads-typo.patch deleted file mode 100644 index f2e6ff2..0000000 --- a/patches/binutils/2.26/310-fix-gold-pthreads-typo.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100 -@@ -102,9 +102,9 @@ - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); - #ifdef PTHREAD_MUTEX_ADAPTIVE_NP -- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); -+ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) -- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err)); -+ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); - #endif - - err = pthread_mutex_init(&this->mutex_, &attr); diff --git a/patches/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/patches/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch deleted file mode 100644 index f9a8af6..0000000 --- a/patches/binutils/2.26/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- binutils-2.25.1/gold/gold-threads.cc.orig 2015-10-20 22:39:36.371169400 +0100 -+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:39:38.182772700 +0100 -@@ -101,7 +101,7 @@ - int err = pthread_mutexattr_init(&attr); - if (err != 0) - gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err)); --#ifdef PTHREAD_MUTEX_ADAPTIVE_NP -+#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) - err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) - gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/patches/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch b/patches/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch deleted file mode 100644 index 334ee3e..0000000 --- a/patches/binutils/2.26/330-Dont-link-to-libfl-as-its-unnecessary.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/binutils/configure b/binutils/configure -index 6e1f21e..78bf4ae 100755 ---- a/binutils/configure -+++ b/binutils/configure -@@ -12069,6 +12069,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12230,6 +12231,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg ca da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" - # If we haven't got the data from the intl directory, -diff --git a/binutils/configure.ac b/binutils/configure.ac -index defe781..8fd236a 100644 ---- a/binutils/configure.ac -+++ b/binutils/configure.ac -@@ -87,7 +87,10 @@ if test -z "$host" ; then - fi - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg ca da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/gas/configure b/gas/configure -index f959e95..9bb4043 100755 ---- a/gas/configure -+++ b/gas/configure -@@ -12819,6 +12819,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12980,6 +12981,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - # If we haven't got the data from the intl directory, -diff --git a/gas/configure.ac b/gas/configure.ac -index 07f825d..c552b7e 100644 ---- a/gas/configure.ac -+++ b/gas/configure.ac -@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) - AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/ld/configure b/ld/configure -index a446283..1a6bf81 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -16087,6 +16087,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -16248,6 +16249,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..45eec53 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -186,7 +186,10 @@ AM_PO_SUBDIRS - AC_EXEEXT - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - AM_MAINTAINER_MODE - AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/patches/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/patches/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch deleted file mode 100644 index e4f235b..0000000 --- a/patches/binutils/2.26/340-Darwin-gold-binary-cc-include-string-not-cstring.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/gold/binary.cc b/gold/binary.cc -index 52df81a..03a8f20 100644 ---- a/gold/binary.cc -+++ b/gold/binary.cc -@@ -23,7 +23,7 @@ - #include "gold.h" - - #include --#include -+#include - - #include "elfcpp.h" - #include "stringpool.h" diff --git a/patches/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/patches/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch deleted file mode 100644 index 6168b31..0000000 --- a/patches/binutils/2.26/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 -From: Andrew Hsieh -Date: Wed, 18 Mar 2015 10:57:24 +0800 -Subject: [PATCH] Fix darwin build - -1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 - doesn't support ended initializer list -2. wcsncasecmp doesn't exist in MacSDK10.6.x - -Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e ---- - binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ - binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- - 2 files changed, 34 insertions(+), 3 deletions(-) - -diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c -index 13e39e4..7a98306 100644 ---- binutils-2.25.orig/bfd/peXXigen.c -+++ binutils-2.25/bfd/peXXigen.c -@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) - } - #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ - -+#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L -+/* wcsncasecmp isn't always defined in Mac SDK */ -+static int -+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) -+{ -+ wchar_t c1, c2; -+ -+ if (n == 0) -+ return (0); -+ for (; *s1; s1++, s2++) -+ { -+ c1 = towlower(*s1); -+ c2 = towlower(*s2); -+ if (c1 != c2) -+ return ((int)c1 - c2); -+ if (--n == 0) -+ return (0); -+ } -+ return (-*s2); -+} -+#endif -+ - /* Perform a comparison of two entries. */ - static signed int - rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) -diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc -index ff5a8ac..45140e0 100644 ---- binutils-2.25.orig/gold/gold-threads.cc -+++ binutils-2.25/gold/gold-threads.cc -@@ -284,9 +284,18 @@ Condvar::~Condvar() - class Once_initialize - { - public: -- Once_initialize() -- : once_(PTHREAD_ONCE_INIT) -- { } -+ Once_initialize() -+#if !defined(__APPLE__) -+ : once_(PTHREAD_ONCE_INIT) -+ { } -+#else -+// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support -+// extended initializer list as above */ -+ { -+ pthread_once_t once_2 = PTHREAD_ONCE_INIT; -+ once_ = once_2; -+ } -+#endif - - // Return a pointer to the pthread_once_t variable. - pthread_once_t* --- -2.1.3 - diff --git a/patches/binutils/2.26/500-sysroot.patch b/patches/binutils/2.26/500-sysroot.patch deleted file mode 100644 index e49c795..0000000 --- a/patches/binutils/2.26/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -308,18 +308,25 @@ - directory first. */ - if (! entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.26/600-poison-system-directories.patch b/patches/binutils/2.26/600-poison-system-directories.patch deleted file mode 100644 index aa04082..0000000 --- a/patches/binutils/2.26/600-poison-system-directories.patch +++ /dev/null @@ -1,285 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -[Gustavo: adapt to binutils 2.25] -Signed-off-by: Thomas Petazzoni -Signed-off-by: Gustavo Zacarias - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.ac (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -diff --git a/ld/config.in b/ld/config.in -index 276fb77..35c58eb 100644 ---- a/ld/config.in -+++ b/ld/config.in -@@ -14,6 +14,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -diff --git a/ld/configure b/ld/configure -index a446283..d1f9504 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -786,6 +786,7 @@ with_lib_path - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_compressed_debug_sections -@@ -1442,6 +1443,8 @@ Optional Features: - --disable-largefile omit support for large files - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -15491,7 +15494,18 @@ else - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..2cd8443 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -diff --git a/ld/ld.h b/ld/ld.h -index d84ec4e..3476b26 100644 ---- a/ld/ld.h -+++ b/ld/ld.h -@@ -164,6 +164,14 @@ typedef struct { - /* If set, display the target memory usage (per memory region). */ - bfd_boolean print_memory_usage; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -diff --git a/ld/ld.texinfo b/ld/ld.texinfo -index 1dd7492..fb1438e 100644 ---- a/ld/ld.texinfo -+++ b/ld/ld.texinfo -@@ -2332,6 +2332,18 @@ string identifying the original linked file does not change. - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -diff --git a/ld/ldfile.c b/ld/ldfile.c -index 96f9ecc..af231c0 100644 ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -diff --git a/ld/ldlex.h b/ld/ldlex.h -index 6f11e7b..0ca3110 100644 ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -144,6 +144,8 @@ enum option_values - OPTION_PRINT_MEMORY_USAGE, - OPTION_REQUIRE_DEFINED_SYMBOL, - OPTION_ORPHAN_HANDLING, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ -diff --git a/ld/ldmain.c b/ld/ldmain.c -index bb0b9cc..a23c56c 100644 ---- a/ld/ldmain.c -+++ b/ld/ldmain.c -@@ -257,6 +257,8 @@ main (int argc, char **argv) - command_line.warn_mismatch = TRUE; - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -diff --git a/ld/lexsup.c b/ld/lexsup.c -index 4cad209..be7d584 100644 ---- a/ld/lexsup.c -+++ b/ld/lexsup.c -@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = - { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, - '\0', N_("=MODE"), N_("Control how orphan sections are handled."), - TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) - } - break; - -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; -+ - case OPTION_PUSH_STATE: - input_flags.pushed = xmemdup (&input_flags, - sizeof (input_flags), -@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) - command_line.soname = NULL; - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); diff --git a/patches/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch b/patches/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch deleted file mode 100644 index cea92f3..0000000 --- a/patches/binutils/2.26/700-Fix-library-paths-on-PowerPC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 -From: Alexey Neyman -Date: Sat, 11 Mar 2017 17:27:09 -0800 -Subject: [PATCH] Fix library paths on PowerPC - -First, need to match against just the CPU name, not the whole triplet. -Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin -triplet. - -Second, it should be testing for $target, not $host. Host may be -little endian by default, and the sysroot directory layout shouldn't -depend on whether it is built on LE or BE machine. - -Signed-off-by: Alexey Neyman ---- - ld/emulparams/elf32ppccommon.sh | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh -index 1f54ef8..d00cf68 100644 ---- a/ld/emulparams/elf32ppccommon.sh -+++ b/ld/emulparams/elf32ppccommon.sh -@@ -44,11 +44,11 @@ fi - - # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. - # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. --case "$host":"$EMULATION_NAME" in -- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; -- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; -- *le-*:*64*) LIBPATH_SUFFIX=64be ;; -- *le-*:*32*) LIBPATH_SUFFIX=32be ;; -+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in -+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; -+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; -+ *le:*64*) LIBPATH_SUFFIX=64be ;; -+ *le:*32*) LIBPATH_SUFFIX=32be ;; - *:*64lppc*) LIBPATH_SUFFIX=64le ;; - *:*32lppc*) LIBPATH_SUFFIX=32le ;; - *:*64*) LIBPATH_SUFFIX=64 ;; --- -2.9.3 - diff --git a/patches/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch b/patches/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch deleted file mode 100644 index 66d4e60..0000000 --- a/patches/binutils/2.26/914-xtensa-fix-signedness-of-gas-relocations.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 2 Feb 2016 17:11:38 +0300 -Subject: [PATCH] xtensa: fix signedness of gas relocations - -Change 1058c7532d0b "Use signed data type for R_XTENSA_DIFF* relocation -offsets." changed signedness of BFD_RELOC_XTENSA_DIFF* relocations -substituted for BFD_RELOC_*. This made it impossible to encode arbitrary -8-, 16- and 32-bit values, which broke e.g. debug info encoding by .loc -directive. Revert this part and add test. - -gas/ -2016-02-03 Max Filippov - * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF* - substitutions for BFD_RELOC_* as unsigned. - * gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa - tests. - * gas/testsuite/gas/xtensa/loc.d: New file: loc test result - patterns. - * gas/testsuite/gas/xtensa/loc.s: New file: loc test. - -Signed-off-by: Max Filippov ---- - gas/config/tc-xtensa.c | 6 +++--- - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/loc.d | 10 ++++++++++ - gas/testsuite/gas/xtensa/loc.s | 7 +++++++ - 4 files changed, 21 insertions(+), 3 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/loc.d - create mode 100644 gas/testsuite/gas/xtensa/loc.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index a119871..36a06cc 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -5961,15 +5961,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) - { - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32; -- fixP->fx_signed = 1; -+ fixP->fx_signed = 0; - break; - default: - break; -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 31b725b..7ff7bd7 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -101,6 +101,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "trampoline" - run_dump_test "first_frag_align" - run_dump_test "auto-litpools" -+ run_dump_test "loc" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/loc.d b/gas/testsuite/gas/xtensa/loc.d -new file mode 100644 -index 0000000..71983cc ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/loc.d -@@ -0,0 +1,10 @@ -+#as: -+#objdump: -r -+#name: .loc directive relocs -+ -+.*: +file format .*xtensa.* -+ -+RELOCATION RECORDS FOR \[\.debug_line\]: -+#... -+.*R_XTENSA_DIFF16.*\.text\+0x00009c42 -+#... -diff --git a/gas/testsuite/gas/xtensa/loc.s b/gas/testsuite/gas/xtensa/loc.s -new file mode 100644 -index 0000000..029e14e ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/loc.s -@@ -0,0 +1,7 @@ -+ .text -+ .file 1 "loc.s" -+ .loc 1 3 -+ nop -+ .space 40000 -+ .loc 1 5 -+ nop --- -2.1.4 - diff --git a/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch b/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch deleted file mode 100644 index ead3e42..0000000 --- a/patches/binutils/2.26/915-xtensa-fix-.init-.fini-literals-moving.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001 -From: Max Filippov -Date: Tue, 16 Feb 2016 02:23:28 +0300 -Subject: [PATCH] xtensa: fix .init/.fini literals moving - -Despite the documentation and the comment in xtensa_move_literals, in -the presence of --text-section-literals and --auto-litpools literals are -moved from the separate literal sections into .init and .fini, because -the check in the xtensa_move_literals is incorrect. - -This moving was broken with introduction of auto litpools: some literals -now may be lost. This happens because literal frags emitted from .init -and .fini are not closed when new .literal_position marks new literal -pool. Then frag_align(2, 0, 0) changes type of the last literal frag to -rs_align. rs_align frags are skipped in the xtensa_move_literals. As a -result fixups against such literals are not moved out of .init.literal/ -.fini.literal sections producing the following assembler error: - - test.S: Warning: fixes not all moved from .init.literal - test.S: Internal error! - -Fix check for .init.literal/.fini.literal in the xtensa_move_literals -and don't let it move literals from there in the presence of ---text-section-literals or --auto-litpools. - -2016-02-17 Max Filippov -gas/ - * config/tc-xtensa.c (xtensa_move_literals): Fix check for - .init.literal/.fini.literal section name. - * testsuite/gas/xtensa/all.exp: Add init-fini-literals to the - list of xtensa tests. - * testsuite/gas/xtensa/init-fini-literals.d: New file: - init-fini-literals test result patterns. - * testsuite/gas/xtensa/init-fini-literals.s: New file: - init-fini-literals test. - -Signed-off-by: Max Filippov ---- -Backported from: 4111950f363221c4641dc2f33bea61cc94f34906 - - gas/config/tc-xtensa.c | 12 ++++++++++-- - gas/testsuite/gas/xtensa/all.exp | 1 + - gas/testsuite/gas/xtensa/init-fini-literals.d | 24 ++++++++++++++++++++++++ - gas/testsuite/gas/xtensa/init-fini-literals.s | 19 +++++++++++++++++++ - 4 files changed, 54 insertions(+), 2 deletions(-) - create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.d - create mode 100644 gas/testsuite/gas/xtensa/init-fini-literals.s - -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index 36a06cc..5773634 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -11061,6 +11061,10 @@ xtensa_move_literals (void) - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; - struct litpool_seg *lps; -+ const char *init_name = INIT_SECTION_NAME; -+ const char *fini_name = FINI_SECTION_NAME; -+ int init_name_len = strlen(init_name); -+ int fini_name_len = strlen(fini_name); - - mark_literal_frags (literal_head->next); - -@@ -11171,9 +11175,13 @@ xtensa_move_literals (void) - - for (segment = literal_head->next; segment; segment = segment->next) - { -+ const char *seg_name = segment_name (segment->seg); -+ - /* Keep the literals for .init and .fini in separate sections. */ -- if (!strcmp (segment_name (segment->seg), INIT_SECTION_NAME) -- || !strcmp (segment_name (segment->seg), FINI_SECTION_NAME)) -+ if ((!memcmp (seg_name, init_name, init_name_len) && -+ !strcmp (seg_name + init_name_len, ".literal")) || -+ (!memcmp (seg_name, fini_name, fini_name_len) && -+ !strcmp (seg_name + fini_name_len, ".literal"))) - continue; - - frchain_from = seg_info (segment->seg)->frchainP; -diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp -index 7ff7bd7..6b67320 100644 ---- a/gas/testsuite/gas/xtensa/all.exp -+++ b/gas/testsuite/gas/xtensa/all.exp -@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then { - run_dump_test "first_frag_align" - run_dump_test "auto-litpools" - run_dump_test "loc" -+ run_dump_test "init-fini-literals" - } - - if [info exists errorInfo] then { -diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.d b/gas/testsuite/gas/xtensa/init-fini-literals.d -new file mode 100644 -index 0000000..19ed121 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/init-fini-literals.d -@@ -0,0 +1,24 @@ -+#as: --text-section-literals -+#objdump: -r -+#name: check that literals for .init and .fini always go to separate sections -+ -+.*: +file format .*xtensa.* -+#... -+RELOCATION RECORDS FOR \[\.init\.literal\]: -+#... -+00000000 R_XTENSA_PLT init -+#... -+RELOCATION RECORDS FOR \[\.fini\.literal\]: -+#... -+00000000 R_XTENSA_PLT fini -+#... -+RELOCATION RECORDS FOR \[\.init\]: -+#... -+.* R_XTENSA_SLOT0_OP \.init\.literal -+.* R_XTENSA_SLOT0_OP \.init\.literal\+0x00000004 -+#... -+RELOCATION RECORDS FOR \[\.fini\]: -+#... -+.* R_XTENSA_SLOT0_OP \.fini\.literal -+.* R_XTENSA_SLOT0_OP \.fini\.literal\+0x00000004 -+#... -diff --git a/gas/testsuite/gas/xtensa/init-fini-literals.s b/gas/testsuite/gas/xtensa/init-fini-literals.s -new file mode 100644 -index 0000000..7c9ec17 ---- /dev/null -+++ b/gas/testsuite/gas/xtensa/init-fini-literals.s -@@ -0,0 +1,19 @@ -+ .section .init,"ax",@progbits -+ .literal_position -+ .literal .LC0, init@PLT -+ .literal_position -+ .literal .LC1, 1 -+ .align 4 -+ -+ l32r a2, .LC0 -+ l32r a2, .LC1 -+ -+ .section .fini,"ax",@progbits -+ .literal_position -+ .literal .LC2, fini@PLT -+ .literal_position -+ .literal .LC3, 1 -+ .align 4 -+ -+ l32r a2, .LC2 -+ l32r a2, .LC3 --- -2.1.4 - diff --git a/patches/binutils/2.27/100-missing-break.patch b/patches/binutils/2.27/100-missing-break.patch deleted file mode 100644 index 6f9d67c..0000000 --- a/patches/binutils/2.27/100-missing-break.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8941017bc0226b60ce306d5271df15820ce66a53 Mon Sep 17 00:00:00 2001 -From: Alan Modra -Date: Tue, 30 Aug 2016 20:57:32 +0930 -Subject: [PATCH] ppc apuinfo for spe parsed incorrectly - -apuinfo saying SPE resulted in mach = bfd_mach_ppc_vle due to a -missing break. - - PR 20531 - * elf32-ppc.c (_bfd_elf_ppc_set_arch): Add missing "break". ---- - bfd/ChangeLog | 5 +++++ - bfd/elf32-ppc.c | 1 + - 2 files changed, 6 insertions(+) - -diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c -index 92299bc..1dd6d78 100644 ---- a/bfd/elf32-ppc.c -+++ b/bfd/elf32-ppc.c -@@ -2246,6 +2246,7 @@ _bfd_elf_ppc_set_arch (bfd *abfd) - case PPC_APUINFO_BRLOCK: - if (mach != bfd_mach_ppc_vle) - mach = bfd_mach_ppc_e500; -+ break; - - case PPC_APUINFO_VLE: - mach = bfd_mach_ppc_vle; --- -2.9.3 - diff --git a/patches/binutils/2.27/120-sh-conf.patch b/patches/binutils/2.27/120-sh-conf.patch deleted file mode 100644 index c12a023..0000000 --- a/patches/binutils/2.27/120-sh-conf.patch +++ /dev/null @@ -1,33 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - -diff --git a/configure b/configure -index 87677bc..2d916f1 100755 ---- a/configure -+++ b/configure -@@ -3812,7 +3812,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; -diff --git a/configure.ac b/configure.ac -index 8fe0eca..b10a99f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1140,7 +1140,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.27/300-001_ld_makefile_patch.patch b/patches/binutils/2.27/300-001_ld_makefile_patch.patch deleted file mode 100644 index 2a1320c..0000000 --- a/patches/binutils/2.27/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/ld/Makefile.am b/ld/Makefile.am -index 9575f1f..84df0bf 100644 ---- a/ld/Makefile.am -+++ b/ld/Makefile.am -@@ -54,7 +54,7 @@ endif - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff --git a/ld/Makefile.in b/ld/Makefile.in -index 9f56ca1..272860f 100644 ---- a/ld/Makefile.in -+++ b/ld/Makefile.in -@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.27/300-012_check_ldrunpath_length.patch b/patches/binutils/2.27/300-012_check_ldrunpath_length.patch deleted file mode 100644 index f1f31af..0000000 --- a/patches/binutils/2.27/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em -index 137446f..bb8391a 100644 ---- a/ld/emultempl/elf32.em -+++ b/ld/emultempl/elf32.em -@@ -1195,6 +1195,8 @@ fragment <link.next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/patches/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch deleted file mode 100644 index 2956385..0000000 --- a/patches/binutils/2.27/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- binutils-2.27/gold/gold-threads.cc.orig 2016-12-26 16:44:23.691075600 +1100 -+++ binutils-2.27/gold/gold-threads.cc 2016-12-26 16:46:21.071855200 +1100 -@@ -101,7 +101,7 @@ - int err = pthread_mutexattr_init(&attr); - if (err != 0) - gold_fatal(_("pthead_mutexattr_init failed: %s"), strerror(err)); --#ifdef PTHREAD_MUTEX_ADAPTIVE_NP -+#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) - err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) - gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/patches/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch b/patches/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch deleted file mode 100644 index c52af05..0000000 --- a/patches/binutils/2.27/330-Dont-link-to-libfl-as-its-unnecessary.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/binutils/configure b/binutils/configure -index 6e1f21e..78bf4ae 100755 ---- a/binutils/configure -+++ b/binutils/configure -@@ -12106,6 +12106,7 @@ - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12267,6 +12268,8 @@ - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" - # If we haven't got the data from the intl directory, -diff --git a/binutils/configure.ac b/binutils/configure.ac -index defe781..8fd236a 100644 ---- a/binutils/configure.ac -+++ b/binutils/configure.ac -@@ -87,7 +87,10 @@ - fi - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/gas/configure b/gas/configure -index f959e95..9bb4043 100755 ---- a/gas/configure -+++ b/gas/configure -@@ -12819,6 +12819,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12980,6 +12981,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - # If we haven't got the data from the intl directory, -diff --git a/gas/configure.ac b/gas/configure.ac -index 07f825d..c552b7e 100644 ---- a/gas/configure.ac -+++ b/gas/configure.ac -@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) - AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/ld/configure b/ld/configure -index a446283..1a6bf81 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -16087,6 +16087,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -16248,6 +16249,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..45eec53 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -186,7 +186,10 @@ AM_PO_SUBDIRS - AC_EXEEXT - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - AM_MAINTAINER_MODE - AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/patches/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/patches/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch deleted file mode 100644 index e4f235b..0000000 --- a/patches/binutils/2.27/340-Darwin-gold-binary-cc-include-string-not-cstring.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/gold/binary.cc b/gold/binary.cc -index 52df81a..03a8f20 100644 ---- a/gold/binary.cc -+++ b/gold/binary.cc -@@ -23,7 +23,7 @@ - #include "gold.h" - - #include --#include -+#include - - #include "elfcpp.h" - #include "stringpool.h" diff --git a/patches/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/patches/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch deleted file mode 100644 index 6168b31..0000000 --- a/patches/binutils/2.27/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 -From: Andrew Hsieh -Date: Wed, 18 Mar 2015 10:57:24 +0800 -Subject: [PATCH] Fix darwin build - -1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 - doesn't support ended initializer list -2. wcsncasecmp doesn't exist in MacSDK10.6.x - -Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e ---- - binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ - binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- - 2 files changed, 34 insertions(+), 3 deletions(-) - -diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c -index 13e39e4..7a98306 100644 ---- binutils-2.25.orig/bfd/peXXigen.c -+++ binutils-2.25/bfd/peXXigen.c -@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) - } - #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ - -+#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L -+/* wcsncasecmp isn't always defined in Mac SDK */ -+static int -+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) -+{ -+ wchar_t c1, c2; -+ -+ if (n == 0) -+ return (0); -+ for (; *s1; s1++, s2++) -+ { -+ c1 = towlower(*s1); -+ c2 = towlower(*s2); -+ if (c1 != c2) -+ return ((int)c1 - c2); -+ if (--n == 0) -+ return (0); -+ } -+ return (-*s2); -+} -+#endif -+ - /* Perform a comparison of two entries. */ - static signed int - rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) -diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc -index ff5a8ac..45140e0 100644 ---- binutils-2.25.orig/gold/gold-threads.cc -+++ binutils-2.25/gold/gold-threads.cc -@@ -284,9 +284,18 @@ Condvar::~Condvar() - class Once_initialize - { - public: -- Once_initialize() -- : once_(PTHREAD_ONCE_INIT) -- { } -+ Once_initialize() -+#if !defined(__APPLE__) -+ : once_(PTHREAD_ONCE_INIT) -+ { } -+#else -+// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support -+// extended initializer list as above */ -+ { -+ pthread_once_t once_2 = PTHREAD_ONCE_INIT; -+ once_ = once_2; -+ } -+#endif - - // Return a pointer to the pthread_once_t variable. - pthread_once_t* --- -2.1.3 - diff --git a/patches/binutils/2.27/500-sysroot.patch b/patches/binutils/2.27/500-sysroot.patch deleted file mode 100644 index 4cb9bc7..0000000 --- a/patches/binutils/2.27/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -336,18 +336,25 @@ - directory first. */ - if (!entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.27/600-poison-system-directories.patch b/patches/binutils/2.27/600-poison-system-directories.patch deleted file mode 100644 index ff235e3..0000000 --- a/patches/binutils/2.27/600-poison-system-directories.patch +++ /dev/null @@ -1,285 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -[Gustavo: adapt to binutils 2.25] -Signed-off-by: Thomas Petazzoni -Signed-off-by: Gustavo Zacarias - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.ac (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -diff --git a/ld/config.in b/ld/config.in -index 276fb77..35c58eb 100644 ---- a/ld/config.in -+++ b/ld/config.in -@@ -17,6 +17,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -diff --git a/ld/configure b/ld/configure -index a446283..d1f9504 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -788,6 +788,7 @@ with_lib_path - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_compressed_debug_sections -@@ -1445,6 +1446,8 @@ Optional Features: - --disable-largefile omit support for large files - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -15498,7 +15501,18 @@ else - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..2cd8443 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -diff --git a/ld/ld.h b/ld/ld.h -index d84ec4e..3476b26 100644 ---- a/ld/ld.h -+++ b/ld/ld.h -@@ -169,6 +169,14 @@ typedef struct { - /* If set, display the target memory usage (per memory region). */ - bfd_boolean print_memory_usage; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -diff --git a/ld/ld.texinfo b/ld/ld.texinfo -index 1dd7492..fb1438e 100644 ---- a/ld/ld.texinfo -+++ b/ld/ld.texinfo -@@ -2357,6 +2357,18 @@ string identifying the original linked file does not change. - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -diff --git a/ld/ldfile.c b/ld/ldfile.c -index 96f9ecc..af231c0 100644 ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -diff --git a/ld/ldlex.h b/ld/ldlex.h -index 6f11e7b..0ca3110 100644 ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -144,6 +144,8 @@ enum option_values - OPTION_PRINT_MEMORY_USAGE, - OPTION_REQUIRE_DEFINED_SYMBOL, - OPTION_ORPHAN_HANDLING, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ -diff --git a/ld/ldmain.c b/ld/ldmain.c -index bb0b9cc..a23c56c 100644 ---- a/ld/ldmain.c -+++ b/ld/ldmain.c -@@ -257,6 +257,8 @@ main (int argc, char **argv) - command_line.warn_mismatch = TRUE; - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -diff --git a/ld/lexsup.c b/ld/lexsup.c -index 4cad209..be7d584 100644 ---- a/ld/lexsup.c -+++ b/ld/lexsup.c -@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = - { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, - '\0', N_("=MODE"), N_("Control how orphan sections are handled."), - TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) - } - break; - -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; -+ - case OPTION_PUSH_STATE: - input_flags.pushed = xmemdup (&input_flags, - sizeof (input_flags), -@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) - command_line.soname = NULL; - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); diff --git a/patches/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch b/patches/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch deleted file mode 100644 index cea92f3..0000000 --- a/patches/binutils/2.27/700-Fix-library-paths-on-PowerPC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 -From: Alexey Neyman -Date: Sat, 11 Mar 2017 17:27:09 -0800 -Subject: [PATCH] Fix library paths on PowerPC - -First, need to match against just the CPU name, not the whole triplet. -Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin -triplet. - -Second, it should be testing for $target, not $host. Host may be -little endian by default, and the sysroot directory layout shouldn't -depend on whether it is built on LE or BE machine. - -Signed-off-by: Alexey Neyman ---- - ld/emulparams/elf32ppccommon.sh | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh -index 1f54ef8..d00cf68 100644 ---- a/ld/emulparams/elf32ppccommon.sh -+++ b/ld/emulparams/elf32ppccommon.sh -@@ -44,11 +44,11 @@ fi - - # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. - # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. --case "$host":"$EMULATION_NAME" in -- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; -- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; -- *le-*:*64*) LIBPATH_SUFFIX=64be ;; -- *le-*:*32*) LIBPATH_SUFFIX=32be ;; -+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in -+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; -+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; -+ *le:*64*) LIBPATH_SUFFIX=64be ;; -+ *le:*32*) LIBPATH_SUFFIX=32be ;; - *:*64lppc*) LIBPATH_SUFFIX=64le ;; - *:*32lppc*) LIBPATH_SUFFIX=32le ;; - *:*64*) LIBPATH_SUFFIX=64 ;; --- -2.9.3 - diff --git a/patches/binutils/2.27/999-xtensa-reverse-shift-count.patch b/patches/binutils/2.27/999-xtensa-reverse-shift-count.patch deleted file mode 100644 index f8bb9c1..0000000 --- a/patches/binutils/2.27/999-xtensa-reverse-shift-count.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 78fb7e37eb8bb08ae537d6c487996ff17c810332 Mon Sep 17 00:00:00 2001 -From: Trevor Saunders -Date: Mon, 26 Sep 2016 12:42:11 -0400 -Subject: [PATCH] tc-xtensa.c: fixup xg_reverse_shift_count typo - -gas/ChangeLog: - -2016-09-26 Trevor Saunders - - * config/tc-xtensa.c (xg_reverse_shift_count): Pass cnt_arg instead of - cnt_argp to concat. ---- - gas/ChangeLog | 5 +++++ - gas/config/tc-xtensa.c | 2 +- - 2 files changed, 6 insertions(+), 1 deletion(-) - -[[ ChangeLog skipped, fails to apply on 2.27 ]] -diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c -index d062044..ca261ae 100644 ---- a/gas/config/tc-xtensa.c -+++ b/gas/config/tc-xtensa.c -@@ -2228,7 +2228,7 @@ xg_reverse_shift_count (char **cnt_argp) - cnt_arg = *cnt_argp; - - /* replace the argument with "31-(argument)" */ -- new_arg = concat ("31-(", cnt_argp, ")", (char *) NULL); -+ new_arg = concat ("31-(", cnt_arg, ")", (char *) NULL); - - free (cnt_arg); - *cnt_argp = new_arg; --- -2.9.3 - diff --git a/patches/binutils/2.28/120-sh-conf.patch b/patches/binutils/2.28/120-sh-conf.patch deleted file mode 100644 index c12a023..0000000 --- a/patches/binutils/2.28/120-sh-conf.patch +++ /dev/null @@ -1,33 +0,0 @@ -r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines - -Likewise, binutils has no idea about any of these new targets either, so we -fix that up too.. now we're able to actually build a real toolchain for -sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more -inept targets than that one, really. Go look, I promise). - -diff --git a/configure b/configure -index 87677bc..2d916f1 100755 ---- a/configure -+++ b/configure -@@ -3812,7 +3812,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; -diff --git a/configure.ac b/configure.ac -index 8fe0eca..b10a99f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1140,7 +1140,7 @@ case "${target}" in - or1k*-*-*) - noconfigdirs="$noconfigdirs gdb" - ;; -- sh-*-* | sh64-*-*) -+ sh*-*-* | sh64-*-*) - case "${target}" in - sh*-*-elf) - ;; diff --git a/patches/binutils/2.28/300-001_ld_makefile_patch.patch b/patches/binutils/2.28/300-001_ld_makefile_patch.patch deleted file mode 100644 index 2a1320c..0000000 --- a/patches/binutils/2.28/300-001_ld_makefile_patch.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/ld/Makefile.am b/ld/Makefile.am -index 9575f1f..84df0bf 100644 ---- a/ld/Makefile.am -+++ b/ld/Makefile.am -@@ -54,7 +54,7 @@ endif - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - - EMUL = @EMUL@ - EMULATION_OFILES = @EMULATION_OFILES@ -diff --git a/ld/Makefile.in b/ld/Makefile.in -index 9f56ca1..272860f 100644 ---- a/ld/Makefile.in -+++ b/ld/Makefile.in -@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS) - # We put the scripts in the directory $(scriptdir)/ldscripts. - # We can't put the scripts in $(datadir) because the SEARCH_DIR - # directives need to be different for native and cross linkers. --scriptdir = $(tooldir)/lib -+scriptdir = $(libdir) - BASEDIR = $(srcdir)/.. - BFDDIR = $(BASEDIR)/bfd - INCDIR = $(BASEDIR)/include diff --git a/patches/binutils/2.28/300-012_check_ldrunpath_length.patch b/patches/binutils/2.28/300-012_check_ldrunpath_length.patch deleted file mode 100644 index f1f31af..0000000 --- a/patches/binutils/2.28/300-012_check_ldrunpath_length.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em -index 137446f..bb8391a 100644 ---- a/ld/emultempl/elf32.em -+++ b/ld/emultempl/elf32.em -@@ -1195,6 +1195,8 @@ fragment <link.next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) diff --git a/patches/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch b/patches/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch deleted file mode 100644 index 2956385..0000000 --- a/patches/binutils/2.28/320-MinGW-w64-winpthreads-doesnt-have-pthread_mutexattr_settype.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- binutils-2.27/gold/gold-threads.cc.orig 2016-12-26 16:44:23.691075600 +1100 -+++ binutils-2.27/gold/gold-threads.cc 2016-12-26 16:46:21.071855200 +1100 -@@ -101,7 +101,7 @@ - int err = pthread_mutexattr_init(&attr); - if (err != 0) - gold_fatal(_("pthead_mutexattr_init failed: %s"), strerror(err)); --#ifdef PTHREAD_MUTEX_ADAPTIVE_NP -+#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32) - err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); - if (err != 0) - gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err)); diff --git a/patches/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch b/patches/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch deleted file mode 100644 index c52af05..0000000 --- a/patches/binutils/2.28/330-Dont-link-to-libfl-as-its-unnecessary.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/binutils/configure b/binutils/configure -index 6e1f21e..78bf4ae 100755 ---- a/binutils/configure -+++ b/binutils/configure -@@ -12106,6 +12106,7 @@ - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12267,6 +12268,8 @@ - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" - # If we haven't got the data from the intl directory, -diff --git a/binutils/configure.ac b/binutils/configure.ac -index defe781..8fd236a 100644 ---- a/binutils/configure.ac -+++ b/binutils/configure.ac -@@ -87,7 +87,10 @@ - fi - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr ca" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/gas/configure b/gas/configure -index f959e95..9bb4043 100755 ---- a/gas/configure -+++ b/gas/configure -@@ -12819,6 +12819,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -12980,6 +12981,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - # If we haven't got the data from the intl directory, -diff --git a/gas/configure.ac b/gas/configure.ac -index 07f825d..c552b7e 100644 ---- a/gas/configure.ac -+++ b/gas/configure.ac -@@ -734,7 +734,10 @@ AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.]) - AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.]) - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - ALL_LINGUAS="fr tr es rw id ru fi ja zh_CN" - ZW_GNU_GETTEXT_SISTER_DIR -diff --git a/ld/configure b/ld/configure -index a446283..1a6bf81 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -16087,6 +16087,7 @@ fi - done - test -n "$YACC" || YACC="yacc" - -+save_LIBS=$LIBS - for ac_prog in flex lex - do - # Extract the first word of "$ac_prog", so it can be a program name with args. -@@ -16248,6 +16249,8 @@ esac - if test "$LEX" = :; then - LEX=${am_missing_run}flex - fi -+LIBS=$save_LIBS -+LEXLIB= - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..45eec53 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -186,7 +186,10 @@ AM_PO_SUBDIRS - AC_EXEEXT - - AC_PROG_YACC -+save_LIBS=$LIBS - AM_PROG_LEX -+LIBS=$save_LIBS -+LEXLIB= - - AM_MAINTAINER_MODE - AM_CONDITIONAL(GENINSRC_NEVER, false) diff --git a/patches/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch b/patches/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch deleted file mode 100644 index e4f235b..0000000 --- a/patches/binutils/2.28/340-Darwin-gold-binary-cc-include-string-not-cstring.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/gold/binary.cc b/gold/binary.cc -index 52df81a..03a8f20 100644 ---- a/gold/binary.cc -+++ b/gold/binary.cc -@@ -23,7 +23,7 @@ - #include "gold.h" - - #include --#include -+#include - - #include "elfcpp.h" - #include "stringpool.h" diff --git a/patches/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch b/patches/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch deleted file mode 100644 index 6168b31..0000000 --- a/patches/binutils/2.28/350-Darwin-Two-fixes-from-Android-NDK-PTHREAD_ONCE_INIT-wcsncasecmp.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c39479f4ab4d372b518957871e1f205a03e7c3d6 Mon Sep 17 00:00:00 2001 -From: Andrew Hsieh -Date: Wed, 18 Mar 2015 10:57:24 +0800 -Subject: [PATCH] Fix darwin build - -1. In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 - doesn't support ended initializer list -2. wcsncasecmp doesn't exist in MacSDK10.6.x - -Change-Id: I69204a72f853f5263dffedc448379d75ed4eca2e ---- - binutils-2.25/bfd/peXXigen.c | 22 ++++++++++++++++++++++ - binutils-2.25/gold/gold-threads.cc | 15 ++++++++++++--- - 2 files changed, 34 insertions(+), 3 deletions(-) - -diff --git binutils-2.25.orig/bfd/peXXigen.c binutils-2.25/bfd/peXXigen.c -index 13e39e4..7a98306 100644 ---- binutils-2.25.orig/bfd/peXXigen.c -+++ binutils-2.25/bfd/peXXigen.c -@@ -3522,6 +3522,28 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n) - } - #endif /* HAVE_WCHAR_H and not Cygwin/Mingw */ - -+#if defined __APPLE__ && __DARWIN_C_LEVEL < 200809L -+/* wcsncasecmp isn't always defined in Mac SDK */ -+static int -+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) -+{ -+ wchar_t c1, c2; -+ -+ if (n == 0) -+ return (0); -+ for (; *s1; s1++, s2++) -+ { -+ c1 = towlower(*s1); -+ c2 = towlower(*s2); -+ if (c1 != c2) -+ return ((int)c1 - c2); -+ if (--n == 0) -+ return (0); -+ } -+ return (-*s2); -+} -+#endif -+ - /* Perform a comparison of two entries. */ - static signed int - rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b) -diff --git binutils-2.25.orig/gold/gold-threads.cc binutils-2.25/gold/gold-threads.cc -index ff5a8ac..45140e0 100644 ---- binutils-2.25.orig/gold/gold-threads.cc -+++ binutils-2.25/gold/gold-threads.cc -@@ -284,9 +284,18 @@ Condvar::~Condvar() - class Once_initialize - { - public: -- Once_initialize() -- : once_(PTHREAD_ONCE_INIT) -- { } -+ Once_initialize() -+#if !defined(__APPLE__) -+ : once_(PTHREAD_ONCE_INIT) -+ { } -+#else -+// In Drawin PTHREAD_ONCE_INIT is {0x30B1BCBA, {0}} and the GCC < 4.4 doesn't support -+// extended initializer list as above */ -+ { -+ pthread_once_t once_2 = PTHREAD_ONCE_INIT; -+ once_ = once_2; -+ } -+#endif - - // Return a pointer to the pthread_once_t variable. - pthread_once_t* --- -2.1.3 - diff --git a/patches/binutils/2.28/500-sysroot.patch b/patches/binutils/2.28/500-sysroot.patch deleted file mode 100644 index 4cb9bc7..0000000 --- a/patches/binutils/2.28/500-sysroot.patch +++ /dev/null @@ -1,37 +0,0 @@ -Signed-off-by: Sven Rebhan - -Always try to prepend the sysroot prefix to absolute filenames first. - -http://bugs.gentoo.org/275666 -http://sourceware.org/bugzilla/show_bug.cgi?id=10340 - ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -336,18 +336,25 @@ - directory first. */ - if (!entry->flags.maybe_archive) - { -- if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) -+ /* For absolute pathnames, try to always open the file in the -+ sysroot first. If this fails, try to open the file at the -+ given location. */ -+ entry->flags.sysrooted = is_sysrooted_pathname (entry->filename); -+ if (!entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename) -+ && ld_sysroot) - { - char *name = concat (ld_sysroot, entry->filename, - (const char *) NULL); - if (ldfile_try_open_bfd (name, entry)) - { - entry->filename = name; -+ entry->flags.sysrooted = TRUE; - return TRUE; - } - free (name); - } -- else if (ldfile_try_open_bfd (entry->filename, entry)) -+ -+ if (ldfile_try_open_bfd (entry->filename, entry)) - return TRUE; - - if (IS_ABSOLUTE_PATH (entry->filename)) diff --git a/patches/binutils/2.28/600-poison-system-directories.patch b/patches/binutils/2.28/600-poison-system-directories.patch deleted file mode 100644 index ff235e3..0000000 --- a/patches/binutils/2.28/600-poison-system-directories.patch +++ /dev/null @@ -1,285 +0,0 @@ -Patch adapted to binutils 2.23.2 and extended to use -BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni. - -[Gustavo: adapt to binutils 2.25] -Signed-off-by: Thomas Petazzoni -Signed-off-by: Gustavo Zacarias - -Upstream-Status: Inappropriate [distribution: codesourcery] - -Patch originally created by Mark Hatle, forward-ported to -binutils 2.21 by Scott Garman. - -purpose: warn for uses of system directories when cross linking - -Code Merged from Sourcery G++ binutils 2.19 - 4.4-277 - -2008-07-02 Joseph Myers - - ld/ - * ld.h (args_type): Add error_poison_system_directories. - * ld.texinfo (--error-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.error_poison_system_directories. - * ldmain.c (main): Initialize - command_line.error_poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_ERROR_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --error-poison-system-directories. - (parse_args): Handle new option. - -2007-06-13 Joseph Myers - - ld/ - * config.in: Regenerate. - * ld.h (args_type): Add poison_system_directories. - * ld.texinfo (--no-poison-system-directories): Document. - * ldfile.c (ldfile_add_library_path): Check - command_line.poison_system_directories. - * ldmain.c (main): Initialize - command_line.poison_system_directories. - * lexsup.c (enum option_values): Add - OPTION_NO_POISON_SYSTEM_DIRECTORIES. - (ld_options): Add --no-poison-system-directories. - (parse_args): Handle new option. - -2007-04-20 Joseph Myers - - Merge from Sourcery G++ binutils 2.17: - - 2007-03-20 Joseph Myers - Based on patch by Mark Hatle . - ld/ - * configure.ac (--enable-poison-system-directories): New option. - * configure, config.in: Regenerate. - * ldfile.c (ldfile_add_library_path): If - ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib, - /usr/lib, /usr/local/lib or /usr/X11R6/lib. - -Signed-off-by: Mark Hatle -Signed-off-by: Scott Garman - -diff --git a/ld/config.in b/ld/config.in -index 276fb77..35c58eb 100644 ---- a/ld/config.in -+++ b/ld/config.in -@@ -17,6 +17,9 @@ - language is requested. */ - #undef ENABLE_NLS - -+/* Define to warn for use of native system library directories */ -+#undef ENABLE_POISON_SYSTEM_DIRECTORIES -+ - /* Additional extension a shared object might have. */ - #undef EXTRA_SHLIB_EXTENSION - -diff --git a/ld/configure b/ld/configure -index a446283..d1f9504 100755 ---- a/ld/configure -+++ b/ld/configure -@@ -788,6 +788,7 @@ with_lib_path - enable_targets - enable_64_bit_bfd - with_sysroot -+enable_poison_system_directories - enable_gold - enable_got - enable_compressed_debug_sections -@@ -1445,6 +1446,8 @@ Optional Features: - --disable-largefile omit support for large files - --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) -+ --enable-poison-system-directories -+ warn for use of native system library directories - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-got= GOT handling scheme (target, single, negative, - multigot) -@@ -15498,7 +15501,18 @@ else - fi - - -+# Check whether --enable-poison-system-directories was given. -+if test "${enable_poison_system_directories+set}" = set; then : -+ enableval=$enable_poison_system_directories; -+else -+ enable_poison_system_directories=no -+fi -+ -+if test "x${enable_poison_system_directories}" = "xyes"; then - -+$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h -+ -+fi - - # Check whether --enable-got was given. - if test "${enable_got+set}" = set; then : -diff --git a/ld/configure.ac b/ld/configure.ac -index 188172d..2cd8443 100644 ---- a/ld/configure.ac -+++ b/ld/configure.ac -@@ -95,6 +95,16 @@ AC_SUBST(use_sysroot) - AC_SUBST(TARGET_SYSTEM_ROOT) - AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE) - -+AC_ARG_ENABLE([poison-system-directories], -+ AS_HELP_STRING([--enable-poison-system-directories], -+ [warn for use of native system library directories]),, -+ [enable_poison_system_directories=no]) -+if test "x${enable_poison_system_directories}" = "xyes"; then -+ AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES], -+ [1], -+ [Define to warn for use of native system library directories]) -+fi -+ - dnl Use --enable-gold to decide if this linker should be the default. - dnl "install_as_default" is set to false if gold is the default linker. - dnl "installed_linker" is the installed BFD linker name. -diff --git a/ld/ld.h b/ld/ld.h -index d84ec4e..3476b26 100644 ---- a/ld/ld.h -+++ b/ld/ld.h -@@ -169,6 +169,14 @@ typedef struct { - /* If set, display the target memory usage (per memory region). */ - bfd_boolean print_memory_usage; - -+ /* If TRUE (the default) warn for uses of system directories when -+ cross linking. */ -+ bfd_boolean poison_system_directories; -+ -+ /* If TRUE (default FALSE) give an error for uses of system -+ directories when cross linking instead of a warning. */ -+ bfd_boolean error_poison_system_directories; -+ - /* Big or little endian as set on command line. */ - enum endian_enum endian; - -diff --git a/ld/ld.texinfo b/ld/ld.texinfo -index 1dd7492..fb1438e 100644 ---- a/ld/ld.texinfo -+++ b/ld/ld.texinfo -@@ -2357,6 +2357,18 @@ string identifying the original linked file does not change. - - Passing @code{none} for @var{style} disables the setting from any - @code{--build-id} options earlier on the command line. -+ -+@kindex --no-poison-system-directories -+@item --no-poison-system-directories -+Do not warn for @option{-L} options using system directories such as -+@file{/usr/lib} when cross linking. This option is intended for use -+in chroot environments when such directories contain the correct -+libraries for the target system rather than the host. -+ -+@kindex --error-poison-system-directories -+@item --error-poison-system-directories -+Give an error instead of a warning for @option{-L} options using -+system directories when cross linking. - @end table - - @c man end -diff --git a/ld/ldfile.c b/ld/ldfile.c -index 96f9ecc..af231c0 100644 ---- a/ld/ldfile.c -+++ b/ld/ldfile.c -@@ -114,6 +114,23 @@ ldfile_add_library_path (const char *name, bfd_boolean cmdline) - new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); - else - new_dirs->name = xstrdup (name); -+ -+#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES -+ if (command_line.poison_system_directories -+ && ((!strncmp (name, "/lib", 4)) -+ || (!strncmp (name, "/usr/lib", 8)) -+ || (!strncmp (name, "/usr/local/lib", 14)) -+ || (!strncmp (name, "/usr/X11R6/lib", 14)))) -+ { -+ if (command_line.error_poison_system_directories) -+ einfo (_("%X%P: error: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ else -+ einfo (_("%P: warning: library search path \"%s\" is unsafe for " -+ "cross-compilation\n"), name); -+ } -+#endif -+ - } - - /* Try to open a BFD for a lang_input_statement. */ -diff --git a/ld/ldlex.h b/ld/ldlex.h -index 6f11e7b..0ca3110 100644 ---- a/ld/ldlex.h -+++ b/ld/ldlex.h -@@ -144,6 +144,8 @@ enum option_values - OPTION_PRINT_MEMORY_USAGE, - OPTION_REQUIRE_DEFINED_SYMBOL, - OPTION_ORPHAN_HANDLING, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES, - }; - - /* The initial parser states. */ -diff --git a/ld/ldmain.c b/ld/ldmain.c -index bb0b9cc..a23c56c 100644 ---- a/ld/ldmain.c -+++ b/ld/ldmain.c -@@ -257,6 +257,8 @@ main (int argc, char **argv) - command_line.warn_mismatch = TRUE; - command_line.warn_search_mismatch = TRUE; - command_line.check_section_addresses = -1; -+ command_line.poison_system_directories = TRUE; -+ command_line.error_poison_system_directories = FALSE; - - /* We initialize DEMANGLING based on the environment variable - COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the -diff --git a/ld/lexsup.c b/ld/lexsup.c -index 4cad209..be7d584 100644 ---- a/ld/lexsup.c -+++ b/ld/lexsup.c -@@ -530,6 +530,14 @@ static const struct ld_option ld_options[] = - { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, - '\0', N_("=MODE"), N_("Control how orphan sections are handled."), - TWO_DASHES }, -+ { {"no-poison-system-directories", no_argument, NULL, -+ OPTION_NO_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Do not warn for -L options using system directories"), -+ TWO_DASHES }, -+ { {"error-poison-system-directories", no_argument, NULL, -+ OPTION_ERROR_POISON_SYSTEM_DIRECTORIES}, -+ '\0', NULL, N_("Give an error for -L options using system directories"), -+ TWO_DASHES }, - }; - - #define OPTION_COUNT ARRAY_SIZE (ld_options) -@@ -542,6 +550,7 @@ parse_args (unsigned argc, char **argv) - int ingroup = 0; - char *default_dirlist = NULL; - char *shortopts; -+ char *BR_paranoid_env; - struct option *longopts; - struct option *really_longopts; - int last_optind; -@@ -1516,6 +1525,14 @@ parse_args (unsigned argc, char **argv) - } - break; - -+ case OPTION_NO_POISON_SYSTEM_DIRECTORIES: -+ command_line.poison_system_directories = FALSE; -+ break; -+ -+ case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES: -+ command_line.error_poison_system_directories = TRUE; -+ break; -+ - case OPTION_PUSH_STATE: - input_flags.pushed = xmemdup (&input_flags, - sizeof (input_flags), -@@ -1559,6 +1576,10 @@ parse_args (unsigned argc, char **argv) - command_line.soname = NULL; - } - -+ BR_paranoid_env = getenv("BR_COMPILER_PARANOID_UNSAFE_PATH"); -+ if (BR_paranoid_env && strlen(BR_paranoid_env) > 0) -+ command_line.error_poison_system_directories = TRUE; -+ - while (ingroup) - { - lang_leave_group (); diff --git a/patches/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch b/patches/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch deleted file mode 100644 index cea92f3..0000000 --- a/patches/binutils/2.28/700-Fix-library-paths-on-PowerPC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1b967f3cb0682dd05128ef13495c2dca2a04dc4e Mon Sep 17 00:00:00 2001 -From: Alexey Neyman -Date: Sat, 11 Mar 2017 17:27:09 -0800 -Subject: [PATCH] Fix library paths on PowerPC - -First, need to match against just the CPU name, not the whole triplet. -Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin -triplet. - -Second, it should be testing for $target, not $host. Host may be -little endian by default, and the sysroot directory layout shouldn't -depend on whether it is built on LE or BE machine. - -Signed-off-by: Alexey Neyman ---- - ld/emulparams/elf32ppccommon.sh | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh -index 1f54ef8..d00cf68 100644 ---- a/ld/emulparams/elf32ppccommon.sh -+++ b/ld/emulparams/elf32ppccommon.sh -@@ -44,11 +44,11 @@ fi - - # Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first. - # Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc. --case "$host":"$EMULATION_NAME" in -- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;; -- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;; -- *le-*:*64*) LIBPATH_SUFFIX=64be ;; -- *le-*:*32*) LIBPATH_SUFFIX=32be ;; -+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in -+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;; -+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;; -+ *le:*64*) LIBPATH_SUFFIX=64be ;; -+ *le:*32*) LIBPATH_SUFFIX=32be ;; - *:*64lppc*) LIBPATH_SUFFIX=64le ;; - *:*32lppc*) LIBPATH_SUFFIX=32le ;; - *:*64*) LIBPATH_SUFFIX=64 ;; --- -2.9.3 - -- cgit v0.10.2-6-g49f6