remove many patch file leftovers from the merge

This commit is contained in:
Calin Crisan 2017-02-19 13:41:51 +02:00
parent ea68a1e14f
commit 87eb68dac9
488 changed files with 0 additions and 41676 deletions

View File

@ -1,53 +0,0 @@
From da6e87670ad4639371da056f9e36201a9236dfa2 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@openwide.fr>
Date: Wed, 29 Jul 2015 19:38:46 +0200
Subject: [PATCH] fix musl build
aircrack-ng doesn't build with a musl toolchain due to
cdefs.h internal glibc header being used in internal
ethernet.h [1].
[1] http://wiki.musl-libc.org/wiki/FAQ
Signed-off-by: Romain Naour <romain.naour@openwide.fr>
---
src/include/ethernet.h | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/include/ethernet.h b/src/include/ethernet.h
index 72d5e81..e9d9236 100644
--- a/src/include/ethernet.h
+++ b/src/include/ethernet.h
@@ -389,18 +389,20 @@ void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
#else /* _KERNEL */
-#include <sys/cdefs.h>
-
/*
* Ethernet address conversion/parsing routines.
*/
-__BEGIN_DECLS
-struct ether_addr *ether_aton(const char *);
-int ether_hostton(const char *, struct ether_addr *);
-int ether_line(const char *, struct ether_addr *, char *);
-char *ether_ntoa(const struct ether_addr *);
-int ether_ntohost(char *, const struct ether_addr *);
-__END_DECLS
+#ifdef __cplusplus
+extern "C" {
+#endif
+ struct ether_addr *ether_aton(const char *);
+ int ether_hostton(const char *, struct ether_addr *);
+ int ether_line(const char *, struct ether_addr *, char *);
+ char *ether_ntoa(const struct ether_addr *);
+ int ether_ntohost(char *, const struct ether_addr *);
+#ifdef __cplusplus
+}
+#endif
#endif /* !_KERNEL */
--
2.4.3

View File

@ -1,61 +0,0 @@
Fix build on big endian systems
The usb_linux_client.c file defines cpu_to_le16/32 by using the C
library htole16/32 function calls. However, cpu_to_le16/32 are used
when initializing structures, i.e in a context where a function call
is not allowed.
It works fine on little endian systems because htole16/32 are defined
by the C library as no-ops. But on big-endian systems, they are
actually doing something, which might involve calling a function,
causing build failures.
To solve this, we simply open-code cpu_to_le16/32 in a way that allows
them to be used when initializing structures.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Index: b/core/adb/usb_linux_client.c
===================================================================
--- a/core/adb/usb_linux_client.c
+++ b/core/adb/usb_linux_client.c
@@ -34,8 +34,15 @@
#define MAX_PACKET_SIZE_FS 64
#define MAX_PACKET_SIZE_HS 512
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define cpu_to_le16(x) (x)
+# define cpu_to_le32(x) (x)
+#else
+# define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
+# define cpu_to_le32(x) \
+ ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
+ (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
+#endif
struct usb_handle
{
Index: b/core/adbd/usb_linux_client.c
===================================================================
--- a/core/adbd/usb_linux_client.c
+++ b/core/adbd/usb_linux_client.c
@@ -34,8 +34,15 @@
#define MAX_PACKET_SIZE_FS 64
#define MAX_PACKET_SIZE_HS 512
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define cpu_to_le16(x) (x)
+# define cpu_to_le32(x) (x)
+#else
+# define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
+# define cpu_to_le32(x) \
+ ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
+ (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
+#endif
struct usb_handle
{

View File

@ -1,116 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-031
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-031
Bug-Reported-by: lolilolicon <lolilolicon@gmail.com>
Bug-Reference-ID: <CAMtVo_Nz=32Oq=zWTb6=+8gUNXOo2rRvud1W4oPnA-cgVk_ZqQ@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-08/msg00139.html
Bug-Description:
The new nameref assignment functionality introduced in bash-4.3 did not perform
enough validation on the variable value and would create variables with
invalid names.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/subst.h 2014-01-11 21:02:27.000000000 -0500
--- b/subst.h 2014-09-01 12:16:56.000000000 -0400
***************
*** 48,51 ****
--- 48,52 ----
#define ASS_MKGLOBAL 0x0008 /* force global assignment */
#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */
+ #define ASS_FROMREF 0x0020 /* assigning from value of nameref variable */
/* Flags for the string extraction functions. */
*** a/bash-4.3-patched/variables.c 2014-05-15 08:26:50.000000000 -0400
--- b/variables.c 2014-09-01 14:37:44.000000000 -0400
***************
*** 2504,2511 ****
int hflags, aflags;
{
! char *newval;
SHELL_VAR *entry;
entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
/* Follow the nameref chain here if this is the global variables table */
if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
--- 2566,2590 ----
int hflags, aflags;
{
! char *newname, *newval;
SHELL_VAR *entry;
+ #if defined (ARRAY_VARS)
+ arrayind_t ind;
+ char *subp;
+ int sublen;
+ #endif
+ newname = 0;
+ #if defined (ARRAY_VARS)
+ if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 && valid_array_reference (name))
+ {
+ newname = array_variable_name (name, &subp, &sublen);
+ if (newname == 0)
+ return (SHELL_VAR *)NULL; /* XXX */
+ entry = hash_lookup (newname, table);
+ }
+ else
+ #endif
entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table);
+
/* Follow the nameref chain here if this is the global variables table */
if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table)
***************
*** 2538,2541 ****
--- 2617,2630 ----
}
}
+ #if defined (ARRAY_VARS)
+ else if (entry == 0 && newname)
+ {
+ entry = make_new_array_variable (newname); /* indexed array by default */
+ if (entry == 0)
+ return entry;
+ ind = array_expand_index (name, subp, sublen);
+ bind_array_element (entry, ind, value, aflags);
+ }
+ #endif
else if (entry == 0)
{
***************
*** 2658,2662 ****
if (nameref_cell (nv) == 0)
return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
! return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags));
}
else
--- 2747,2752 ----
if (nameref_cell (nv) == 0)
return (bind_variable_internal (nv->name, value, nvc->table, 0, flags));
! /* XXX - bug here with ref=array[index] */
! return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags|ASS_FROMREF));
}
else
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 30
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 31
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,55 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-032
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-032
Bug-Reported-by: crispusfairbairn@gmail.com
Bug-Reference-ID: <b5e499f7-3b98-408d-9f94-c0387580e73a@googlegroups.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-09/msg00013.html
Bug-Description:
When bash is running in Posix mode, it allows signals -- including SIGCHLD --
to interrupt the `wait' builtin, as Posix requires. However, the interrupt
causes bash to not run a SIGCHLD trap for all exited children. This patch
fixes the issue and restores the documented behavior in Posix mode.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/jobs.c 2014-05-14 09:20:15.000000000 -0400
--- b/jobs.c 2014-09-09 11:50:38.000000000 -0400
***************
*** 3340,3344 ****
{
interrupt_immediately = 0;
! trap_handler (SIGCHLD); /* set pending_traps[SIGCHLD] */
wait_signal_received = SIGCHLD;
/* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
--- 3346,3352 ----
{
interrupt_immediately = 0;
! /* This was trap_handler (SIGCHLD) but that can lose traps if
! children_exited > 1 */
! queue_sigchld_trap (children_exited);
wait_signal_received = SIGCHLD;
/* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 31
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 32
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,229 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-033
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-033
Bug-Reported-by: mickael9@gmail.com, Jan Rome <jan.rome@gmail.com>
Bug-Reference-ID: <20140907224046.382ED3610CC@mickael-laptop.localdomain>,
<540D661D.50908@gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-09/msg00029.html
http://lists.gnu.org/archive/html/bug-bash/2014-09/msg00030.html
Bug-Description:
Bash does not clean up the terminal state in all cases where bash or
readline modifies it and bash is subsequently terminated by a fatal signal.
This happens when the `read' builtin modifies the terminal settings, both
when readline is active and when it is not. It occurs most often when a script
installs a trap that exits on a signal without re-sending the signal to itself.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/shell.c 2014-01-14 08:04:32.000000000 -0500
--- b/shell.c 2014-12-22 10:27:50.000000000 -0500
***************
*** 74,77 ****
--- 74,78 ----
#if defined (READLINE)
+ # include <readline/readline.h>
# include "bashline.h"
#endif
***************
*** 910,913 ****
--- 912,923 ----
fflush (stderr);
+ /* Clean up the terminal if we are in a state where it's been modified. */
+ #if defined (READLINE)
+ if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
+ (*rl_deprep_term_function) ();
+ #endif
+ if (read_tty_modified ())
+ read_tty_cleanup ();
+
/* Do trap[0] if defined. Allow it to override the exit status
passed to us. */
*** a/bash-4.3-patched/builtins/read.def 2014-10-01 12:57:38.000000000 -0400
--- b/builtins/read.def 2014-12-22 10:48:54.000000000 -0500
***************
*** 141,148 ****
int sigalrm_seen;
! static int reading;
static SigHandler *old_alrm;
static unsigned char delim;
/* In all cases, SIGALRM just sets a flag that we check periodically. This
avoids problems with the semi-tricky stuff we do with the xfree of
--- 141,150 ----
int sigalrm_seen;
! static int reading, tty_modified;
static SigHandler *old_alrm;
static unsigned char delim;
+ static struct ttsave termsave;
+
/* In all cases, SIGALRM just sets a flag that we check periodically. This
avoids problems with the semi-tricky stuff we do with the xfree of
***************
*** 189,193 ****
SHELL_VAR *var;
TTYSTRUCT ttattrs, ttset;
- struct ttsave termsave;
#if defined (ARRAY_VARS)
WORD_LIST *alist;
--- 191,194 ----
***************
*** 222,226 ****
USE_VAR(lastsig);
! sigalrm_seen = reading = 0;
i = 0; /* Index into the string that we are reading. */
--- 223,227 ----
USE_VAR(lastsig);
! sigalrm_seen = reading = tty_modified = 0;
i = 0; /* Index into the string that we are reading. */
***************
*** 439,442 ****
--- 440,445 ----
goto assign_vars;
}
+ if (interactive_shell == 0)
+ initialize_terminating_signals ();
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
***************
*** 483,487 ****
--- 486,493 ----
if (i < 0)
sh_ttyerror (1);
+ tty_modified = 1;
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
+ if (interactive_shell == 0)
+ initialize_terminating_signals ();
}
}
***************
*** 498,502 ****
--- 504,511 ----
sh_ttyerror (1);
+ tty_modified = 1;
add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
+ if (interactive_shell == 0)
+ initialize_terminating_signals ();
}
***************
*** 589,592 ****
--- 598,603 ----
else
lastsig = 0;
+ if (terminating_signal && tty_modified)
+ ttyrestore (&termsave); /* fix terminal before exiting */
CHECK_TERMSIG;
eof = 1;
***************
*** 979,982 ****
--- 990,1007 ----
{
ttsetattr (ttp->fd, ttp->attrs);
+ tty_modified = 0;
+ }
+
+ void
+ read_tty_cleanup ()
+ {
+ if (tty_modified)
+ ttyrestore (&termsave);
+ }
+
+ int
+ read_tty_modified ()
+ {
+ return (tty_modified);
}
*** ./bash-4.3-patched/builtins/common.h 2014-10-01 12:57:47.000000000 -0400
--- b/builtins/common.h 2014-12-22 10:10:14.000000000 -0500
***************
*** 123,126 ****
--- 141,148 ----
extern void getopts_reset __P((int));
+ /* Functions from read.def */
+ extern void read_tty_cleanup __P((void));
+ extern int read_tty_modified __P((void));
+
/* Functions from set.def */
extern int minus_o_option_value __P((char *));
*** a/bash-4.3-patched/bashline.c 2014-05-14 09:22:39.000000000 -0400
--- b/bashline.c 2014-09-08 11:28:56.000000000 -0400
***************
*** 203,206 ****
--- 203,207 ----
extern int array_needs_making;
extern int posixly_correct, no_symbolic_links;
+ extern int sigalrm_seen;
extern char *current_prompt_string, *ps1_prompt;
extern STRING_INT_ALIST word_token_alist[];
***************
*** 4209,4214 ****
/* If we're going to longjmp to top_level, make sure we clean up readline.
check_signals will call QUIT, which will eventually longjmp to top_level,
! calling run_interrupt_trap along the way. */
! if (interrupt_state)
rl_cleanup_after_signal ();
bashline_reset_event_hook ();
--- 4262,4268 ----
/* If we're going to longjmp to top_level, make sure we clean up readline.
check_signals will call QUIT, which will eventually longjmp to top_level,
! calling run_interrupt_trap along the way. The check for sigalrm_seen is
! to clean up the read builtin's state. */
! if (terminating_signal || interrupt_state || sigalrm_seen)
rl_cleanup_after_signal ();
bashline_reset_event_hook ();
*** a/bash-4.3-patched/sig.c 2014-01-10 15:06:06.000000000 -0500
--- b/sig.c 2014-09-08 11:26:33.000000000 -0400
***************
*** 533,538 ****
/* Set the event hook so readline will call it after the signal handlers
finish executing, so if this interrupted character input we can get
! quick response. */
! if (interactive_shell && interactive && no_line_editing == 0)
bashline_set_event_hook ();
#endif
--- 533,540 ----
/* Set the event hook so readline will call it after the signal handlers
finish executing, so if this interrupted character input we can get
! quick response. If readline is active or has modified the terminal we
! need to set this no matter what the signal is, though the check for
! RL_STATE_TERMPREPPED is possibly redundant. */
! if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE (RL_STATE_TERMPREPPED))
bashline_set_event_hook ();
#endif
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 32
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 33
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,94 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-034
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-034
Bug-Reported-by: Dreamcat4 <dreamcat4@gmail.com>
Bug-Reference-ID: <CAN39uTpAEs2GFu4ebC_SfSVMRTh-DJ9YanrY4BZZ3OO+CCHjng@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-05/msg00001.html
Bug-Description:
If neither the -f nor -v options is supplied to unset, and a name argument is
found to be a function and unset, subsequent name arguments are not treated as
variables before attempting to unset a function by that name.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/builtins/set.def 2013-04-19 07:20:34.000000000 -0400
--- b/builtins/set.def 2015-05-05 13:25:36.000000000 -0400
***************
*** 752,758 ****
--- 797,805 ----
{
int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
+ int global_unset_func, global_unset_var;
char *name;
unset_function = unset_variable = unset_array = nameref = any_failed = 0;
+ global_unset_func = global_unset_var = 0;
reset_internal_getopt ();
***************
*** 762,769 ****
{
case 'f':
! unset_function = 1;
break;
case 'v':
! unset_variable = 1;
break;
case 'n':
--- 809,816 ----
{
case 'f':
! global_unset_func = 1;
break;
case 'v':
! global_unset_var = 1;
break;
case 'n':
***************
*** 778,782 ****
list = loptend;
! if (unset_function && unset_variable)
{
builtin_error (_("cannot simultaneously unset a function and a variable"));
--- 825,829 ----
list = loptend;
! if (global_unset_func && global_unset_var)
{
builtin_error (_("cannot simultaneously unset a function and a variable"));
***************
*** 796,799 ****
--- 843,849 ----
name = list->word->word;
+ unset_function = global_unset_func;
+ unset_variable = global_unset_var;
+
#if defined (ARRAY_VARS)
unset_array = 0;
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 33
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 34
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,67 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-035
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-035
Bug-Reported-by: <romerox.adrian@gmail.com>
Bug-Reference-ID: <CABV5r3zhPXmSKUe9uedeGc5YFBM2njJ1iVmY2h5neWdQpDBQug@mail.gmail.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-08/msg00045.html
Bug-Description:
A locale with a long name can trigger a buffer overflow and core dump. This
applies on systems that do not have locale_charset in libc, are not using
GNU libiconv, and are not using the libintl that ships with bash in lib/intl.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/lib/sh/unicode.c 2014-01-30 16:47:19.000000000 -0500
--- b/lib/sh/unicode.c 2015-05-01 08:58:30.000000000 -0400
***************
*** 79,83 ****
if (s)
{
! strcpy (charsetbuf, s+1);
t = strchr (charsetbuf, '@');
if (t)
--- 79,84 ----
if (s)
{
! strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
! charsetbuf[sizeof (charsetbuf) - 1] = '\0';
t = strchr (charsetbuf, '@');
if (t)
***************
*** 85,89 ****
return charsetbuf;
}
! strcpy (charsetbuf, locale);
return charsetbuf;
}
--- 86,91 ----
return charsetbuf;
}
! strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
! charsetbuf[sizeof (charsetbuf) - 1] = '\0';
return charsetbuf;
}
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 34
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 35
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,61 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-036
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-036
Bug-Reported-by: emanuelczirai@cryptolab.net
Bug-Reference-ID: <f962e4f556da5ebfadaf7afe9c78a8cb@cryptolab.net>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-02/msg00071.html
Bug-Description:
When evaluating and setting integer variables, and the assignment fails to
create a variable (for example, when performing an operation on an array
variable with an invalid subscript), bash attempts to dereference a null
pointer, causing a segmentation violation.
Patch (apply with `patch -p0'):
*** a/bash-20150206/variables.c 2015-01-23 20:39:27.000000000 -0500
--- b/variables.c 2015-02-19 13:56:12.000000000 -0500
***************
*** 2834,2841 ****
v = bind_variable (lhs, rhs, 0);
! if (v && isint)
! VSETATTR (v, att_integer);
!
! VUNSETATTR (v, att_invisible);
return (v);
--- 2834,2843 ----
v = bind_variable (lhs, rhs, 0);
! if (v)
! {
! if (isint)
! VSETATTR (v, att_integer);
! VUNSETATTR (v, att_invisible);
! }
return (v);
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 35
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 36
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,47 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-037
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-037
Bug-Reported-by: Greg Wooledge <wooledg@eeg.ccf.org>
Bug-Reference-ID: <20150204144240.GN13956@eeg.ccf.org>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-02/msg00007.html
Bug-Description:
If an associative array uses `@' or `*' as a subscript, `declare -p' produces
output that cannot be reused as input.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/assoc.c 2011-11-05 16:39:05.000000000 -0400
--- b/assoc.c 2015-02-04 15:28:25.000000000 -0500
***************
*** 437,440 ****
--- 440,445 ----
if (sh_contains_shell_metas (tlist->key))
istr = sh_double_quote (tlist->key);
+ else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0')
+ istr = sh_double_quote (tlist->key);
else
istr = tlist->key;
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 36
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 37
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,92 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-038
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-038
Bug-Reported-by: worley@alum.mit.edu (Dale R. Worley)
Bug-Reference-ID: <201406100051.s5A0pCeB014978@hobgoblin.ariadne.com>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-06/msg00028.html
Bug-Description:
There are a number of instances where `time' is not recognized as a reserved
word when the shell grammar says it should be.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/parse.y 2014-04-07 11:56:12.000000000 -0400
--- b/parse.y 2014-06-11 10:25:53.000000000 -0400
***************
*** 2819,2827 ****
case OR_OR:
case '&':
case DO:
case THEN:
case ELSE:
case '{': /* } */
! case '(': /* ) */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
--- 2819,2832 ----
case OR_OR:
case '&':
+ case WHILE:
case DO:
+ case UNTIL:
+ case IF:
case THEN:
+ case ELIF:
case ELSE:
case '{': /* } */
! case '(': /* )( */
! case ')': /* only valid in case statement */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
*** a/bash-4.3-patched/y.tab.c 2014-10-05 13:52:50.000000000 -0400
--- b/y.tab.c 2015-05-19 15:08:43.000000000 -0400
***************
*** 5131,5139 ****
case OR_OR:
case '&':
case DO:
case THEN:
case ELSE:
case '{': /* } */
! case '(': /* ) */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
--- 5131,5144 ----
case OR_OR:
case '&':
+ case WHILE:
case DO:
+ case UNTIL:
+ case IF:
case THEN:
+ case ELIF:
case ELSE:
case '{': /* } */
! case '(': /* )( */
! case ')': /* only valid in case statement */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 37
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 38
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,61 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-039
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-039
Bug-Reported-by: SN <poczta-sn@gazeta.pl>
Bug-Reference-ID: <54E2554C.205@gazeta.pl>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-02/msg00060.html
Bug-Description:
Using the output of `declare -p' when run in a function can result in variables
that are invisible to `declare -p'. This problem occurs when an assignment
builtin such as `declare' receives a quoted compound array assignment as one of
its arguments.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/arrayfunc.c 2014-10-01 13:08:48.000000000 -0400
--- b/arrayfunc.c 2015-02-19 14:33:05.000000000 -0500
***************
*** 405,408 ****
--- 405,411 ----
else
array_insert (a, i, l->word->word);
+
+ VUNSETATTR (var, att_invisible); /* no longer invisible */
+
return var;
}
***************
*** 635,638 ****
--- 638,645 ----
if (nlist)
dispose_words (nlist);
+
+ if (var)
+ VUNSETATTR (var, att_invisible); /* no longer invisible */
+
return (var);
}
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 38
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 39
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,51 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-040
Signed-off-by: Gustavo Zacarias <gustavo@zacrias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-040
Bug-Reported-by: Jean Delvare <jdelvare@suse.de>
Bug-Reference-ID: <20150609180231.5f463695@endymion.delvare>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-06/msg00033.html
Bug-Description:
There is a memory leak that occurs when bash expands an array reference on
the rhs of an assignment statement.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/subst.c 2014-10-01 12:57:47.000000000 -0400
--- b/subst.c 2015-06-22 09:16:53.000000000 -0400
***************
*** 5783,5787 ****
if (pflags & PF_ASSIGNRHS)
{
! temp = array_variable_name (name, &tt, (int *)0);
if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind);
--- 5783,5787 ----
if (pflags & PF_ASSIGNRHS)
{
! var = array_variable_part (name, &tt, (int *)0);
if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind);
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 39
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 40
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,76 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-041
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-041
Bug-Reported-by: Hanno Böck <hanno@hboeck.de>
Bug-Reference-ID: <20150623131106.6f111da9@pc1>, <20150707004640.0e61d2f9@pc1>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-06/msg00089.html,
http://lists.gnu.org/archive/html/bug-bash/2015-07/msg00018.html
Bug-Description:
There are several out-of-bounds read errors that occur when completing command
lines where assignment statements appear before the command name. The first
two appear only when programmable completion is enabled; the last one only
happens when listing possible completions.
Patch (apply with `patch -p0'):
*** a/bash-4.3.40/bashline.c 2014-12-29 14:39:43.000000000 -0500
--- b/bashline.c 2015-08-12 10:21:58.000000000 -0400
***************
*** 1469,1476 ****
--- 1469,1489 ----
os = start;
n = 0;
+ was_assignment = 0;
s = find_cmd_start (os);
e = find_cmd_end (end);
do
{
+ /* Don't read past the end of rl_line_buffer */
+ if (s > rl_end)
+ {
+ s1 = s = e1;
+ break;
+ }
+ /* Or past point if point is within an assignment statement */
+ else if (was_assignment && s > rl_point)
+ {
+ s1 = s = e1;
+ break;
+ }
/* Skip over assignment statements preceding a command name. If we
don't find a command name at all, we can perform command name
*** a/bash-4.3.40/lib/readline/complete.c 2013-10-14 09:27:10.000000000 -0400
--- b/lib/readline/complete.c 2015-07-31 09:34:39.000000000 -0400
***************
*** 690,693 ****
--- 690,695 ----
if (temp == 0 || *temp == '\0')
return (pathname);
+ else if (temp[1] == 0 && temp == pathname)
+ return (pathname);
/* If the basename is NULL, we might have a pathname like '/usr/src/'.
Look for a previous slash and, if one is found, return the portion
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 40
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 41
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,59 +0,0 @@
From http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-042
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
BASH PATCH REPORT
=================
Bash-Release: 4.3
Patch-ID: bash43-042
Bug-Reported-by: Nathan Neulinger <nneul@neulinger.org>
Bug-Reference-ID: <558EFDF2.7060402@neulinger.org>
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2015-06/msg00096.html
Bug-Description:
There is a problem when parsing command substitutions containing `case'
commands within pipelines that causes the parser to not correctly identify
the end of the command substitution.
Patch (apply with `patch -p0'):
*** a/bash-4.3-patched/parse.y 2015-05-18 19:27:05.000000000 -0400
--- b/parse.y 2015-06-29 10:59:27.000000000 -0400
***************
*** 3709,3712 ****
--- 3709,3714 ----
tflags |= LEX_INWORD;
lex_wlen = 0;
+ if (tflags & LEX_RESWDOK)
+ lex_rwlen = 0;
}
}
*** a/bash-4.3-patched/y.tab.c 2015-05-18 19:27:05.000000000 -0400
--- b/y.tab.c 2015-06-29 10:59:27.000000000 -0400
***************
*** 6021,6024 ****
--- 6021,6026 ----
tflags |= LEX_INWORD;
lex_wlen = 0;
+ if (tflags & LEX_RESWDOK)
+ lex_rwlen = 0;
}
}
*** a/bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500
--- b/patchlevel.h 2014-03-20 20:01:28.000000000 -0400
***************
*** 26,30 ****
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 41
#endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
looks for to find the patch level (for the sccs version string). */
! #define PATCHLEVEL 42
#endif /* _PATCHLEVEL_H_ */

View File

@ -1,48 +0,0 @@
From c36db3f798bf576f42d81a0c51198b17d7112e8c Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Sat, 8 Aug 2015 17:43:28 +0200
Subject: [PATCH] Do not use the non-standard <sys/cdefs.h> header
<sys/cdefs.h> is glibc-specific, and should be used only internally by
glibc, not by external libraries/programs. It is not available in all
standard C libraries.
Submitted upstream: https://sourceforge.net/p/bcusdk/patches/3/
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
eibd/include/eibclient.h | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/eibd/include/eibclient.h b/eibd/include/eibclient.h
index 2781878..b095a1c 100644
--- a/eibd/include/eibclient.h
+++ b/eibd/include/eibclient.h
@@ -27,10 +27,11 @@
#ifndef EIBCLIENT_H
#define EIBCLIENT_H
-#include <sys/cdefs.h>
#include <stdint.h>
-__BEGIN_DECLS;
+#ifdef __cplusplus
+extern "C" {
+#endif
#include "eibloadresult.h"
@@ -889,5 +890,9 @@ int EIB_Cache_LastUpdates_async (EIBConnection * con, uint16_t start,
uint16_t * end);
-__END_DECLS
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
--
2.5.0

View File

@ -1,31 +0,0 @@
From 2541ee3d709803096b17e45610ccc1404e2e5eee Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Sat, 8 Aug 2015 17:46:34 +0200
Subject: [PATCH] fd_set requires inclusion of <sys/select.h>
According to POSIX.1-2001, the definition fd_set and related macros is
in <sys/select.h>, so it should be included in files using fd_set to
make the code compatible with all standard C libraries.
Submitted upstream: https://sourceforge.net/p/bcusdk/patches/3/
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
eibd/examples/common.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/eibd/examples/common.h b/eibd/examples/common.h
index 51fc514..f038da1 100644
--- a/eibd/examples/common.h
+++ b/eibd/examples/common.h
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/select.h>
#include "eibclient.h"
/** unsigned char*/
--
2.5.0

View File

@ -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)
;;

View File

@ -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

View File

@ -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)

View File

@ -1,37 +0,0 @@
Signed-off-by: Sven Rebhan <odinshorse@googlemail.com>
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))

View File

@ -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 <thomas.petazzoni@free-electrons.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
Merge from Sourcery G++ binutils 2.17:
2007-03-20 Joseph Myers <joseph@codesourcery.com>
Based on patch by Mark Hatle <mark.hatle@windriver.com>.
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 <mark.hatle@windriver.com>
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
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=<type> 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. */

View File

@ -1,846 +0,0 @@
From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001
From: David Weatherford <weath@cadence.com>
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

View File

@ -1,51 +0,0 @@
From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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

View File

@ -1,133 +0,0 @@
From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001
From: Volodymyr Arbatov <arbatov@cadence.com>
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 <arbatov@cadence.com>
David Weatherford <weath@cadence.com>
Max Filippov <jcmvbkbc@gmail.com>
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

View File

@ -1,47 +0,0 @@
From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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

View File

@ -1,79 +0,0 @@
From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <augustine.sterling@gmail.com>
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 <augustine.sterling@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,90 +0,0 @@
From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,57 +0,0 @@
From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,56 +0,0 @@
From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,47 +0,0 @@
From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
substitutions for BFD_RELOC_* as unsigned.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
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

View File

@ -1,70 +0,0 @@
From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
gas/
* config/tc-xtensa.c (xtensa_move_literals): Fix check for
.init.literal/.fini.literal section name.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Backported from: 4111950f363221c4641dc2f33bea61cc94f34906
gas/config/tc-xtensa.c | 12 ++++++++++--
1 file changed, 19 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

View File

@ -1,46 +0,0 @@
From 369be6981b26787b2685e3b8c6da779dae8ce35f Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
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) <arnout@mind.be>
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

View File

@ -1,66 +0,0 @@
From: Alan Modra <amodra@gmail.com>
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);

View File

@ -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)
;;

View File

@ -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

View File

@ -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)

View File

@ -1,37 +0,0 @@
Signed-off-by: Sven Rebhan <odinshorse@googlemail.com>
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))

View File

@ -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 <thomas.petazzoni@free-electrons.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
Merge from Sourcery G++ binutils 2.17:
2007-03-20 Joseph Myers <joseph@codesourcery.com>
Based on patch by Mark Hatle <mark.hatle@windriver.com>.
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 <mark.hatle@windriver.com>
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
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=<type> 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. */

View File

@ -1,846 +0,0 @@
From a82c7d9030b67a6a76a5403d0e1641f9e42141ac Mon Sep 17 00:00:00 2001
From: David Weatherford <weath@cadence.com>
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

View File

@ -1,51 +0,0 @@
From a35d5e823fdfe8a6e7e05ca8e3fb8bb5697335b1 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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

View File

@ -1,133 +0,0 @@
From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001
From: Volodymyr Arbatov <arbatov@cadence.com>
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 <arbatov@cadence.com>
David Weatherford <weath@cadence.com>
Max Filippov <jcmvbkbc@gmail.com>
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

View File

@ -1,47 +0,0 @@
From e7d17e71cdc10a2e81e454ce3b9637f1b2a587f2 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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

View File

@ -1,79 +0,0 @@
From 7fc39194f8fb48914c995f8ec3826d50086f1ec0 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <augustine.sterling@gmail.com>
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 <augustine.sterling@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,90 +0,0 @@
From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,502 +0,0 @@
From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,356 +0,0 @@
From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,146 +0,0 @@
From 288c2b709e5e6841484e1a129eaccd299db36877 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,826 +0,0 @@
From e5409aedd3ee2192855018a564650ffb75c26e60 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,345 +0,0 @@
From cbe53e134d4c3a656880a906738ce19fdcd38e8b Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,57 +0,0 @@
From 8ec76b16f62d1bf386fb2c39af5f66c3afddc5cb Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,56 +0,0 @@
From 2d0522e76e4afeeb2e104e0a4332d94fa0d2fbf6 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,698 +0,0 @@
From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <weath@cadence.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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=<value>\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

View File

@ -1,99 +0,0 @@
From 6c7c5c477ef9ccf2d2548cf2ac3cec9bd3c9c5b6 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
substitutions for BFD_RELOC_* as unsigned.
gas/testsuite/
2016-02-03 Max Filippov <jcmvbkbc@gmail.com>
* gas/xtensa/all.exp: Add loc to list of xtensa tests.
* gas/xtensa/loc.d: New file: loc test result patterns.
* gas/xtensa/loc.s: New file: loc test.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
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

View File

@ -1,149 +0,0 @@
From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,46 +0,0 @@
From 1ceee199e9a32034c6def7700fdbb26335ca76a3 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Fri, 25 Dec 2015 11:38:13 +0100
Subject: [PATCH] sh-conf
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).
[Romain: rebase on top of 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
configure | 2 +-
configure.ac | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 34b66f7..905bc7b 100755
--- a/configure
+++ b/configure
@@ -3939,7 +3939,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 4977d97..1e69ee2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1276,7 +1276,7 @@ case "${target}" in
or1k*-*-*)
noconfigdirs="$noconfigdirs gdb"
;;
- sh-*-* | sh64-*-*)
+ sh*-*-* | sh64-*-*)
case "${target}" in
sh*-*-elf)
;;
--
2.4.3

View File

@ -1,41 +0,0 @@
From d76a7549b43974fe8564971a3f40459bc495a8a7 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Fri, 25 Dec 2015 11:40:53 +0100
Subject: [PATCH] ld-makefile
[Romain: rebase on top of 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
ld/Makefile.am | 2 +-
ld/Makefile.in | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 0b3b049..3871c74 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -57,7 +57,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 ed98f87..530e4c9 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -413,7 +413,7 @@ AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS)
# 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
--
2.4.3

View File

@ -1,36 +0,0 @@
From ebe1cba46df52d7bf86def3d681271fd05fb453b Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Fri, 25 Dec 2015 11:41:47 +0100
Subject: [PATCH] check-ldrunpath-length
[Romain: rebase on top of 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
ld/emultempl/elf32.em | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 0405d4f..efd3300 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1242,6 +1242,8 @@ fragment <<EOF
&& 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;
@@ -1523,6 +1525,8 @@ gld${EMULATION_NAME}_before_allocation (void)
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)
--
2.4.3

View File

@ -1,52 +0,0 @@
From 30628870e583375f8927c04398c7219c6e9f703c Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Fri, 25 Dec 2015 11:42:48 +0100
Subject: [PATCH] add sysroot fix from bug #3049
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
Signed-off-by: Sven Rebhan <odinshorse@googlemail.com>
[Romain: rebase on top of 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
ld/ldfile.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/ld/ldfile.c b/ld/ldfile.c
index 96f9ecc..1439309 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -335,18 +335,25 @@ ldfile_open_file_search (const char *arch,
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))
--
2.4.3

View File

@ -1,306 +0,0 @@
From be366461dd49e760440fb28eaee5164eb281adcc Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Fri, 25 Dec 2015 11:45:38 +0100
Subject: [PATCH] poison-system-directories
Patch adapted to binutils 2.23.2 and extended to use
BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni.
[Romain: rebase on top of 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
[Gustavo: adapt to binutils 2.25]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
Merge from Sourcery G++ binutils 2.17:
2007-03-20 Joseph Myers <joseph@codesourcery.com>
Based on patch by Mark Hatle <mark.hatle@windriver.com>.
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 <mark.hatle@windriver.com>
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
ld/config.in | 3 +++
ld/configure | 14 ++++++++++++++
ld/configure.ac | 10 ++++++++++
ld/ld.h | 8 ++++++++
ld/ld.texinfo | 12 ++++++++++++
ld/ldfile.c | 17 +++++++++++++++++
ld/ldlex.h | 2 ++
ld/ldmain.c | 2 ++
ld/lexsup.c | 21 +++++++++++++++++++++
9 files changed, 89 insertions(+)
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=<type> 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 1439309..086b354 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 ();
--
2.4.3

View File

@ -1,108 +0,0 @@
From 5eeb7401eed2f26d5fc255de816ca70a2cb9374e Mon Sep 17 00:00:00 2001
From: Sandra Loosemore <sandra@codesourcery.com>
Date: Sun, 27 Dec 2015 12:30:26 -0800
Subject: [PATCH 900/901] Correct nios2 _gp address computation.
2015-12-27 Sandra Loosemore <sandra@codesourcery.com>
bfd/
* elf32-nios2.c (nios2_elf_assign_gp): Correct computation of _gp
address.
(nios2_elf32_relocate_section): Tidy code for R_NIOS2_GPREL error
messages.
[Romain:
- backport upstream patch on 2.26
- drop bfd/ChangeLog entry]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
bfd/elf32-nios2.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
index 6b29d8b..01ebd6e 100644
--- a/bfd/elf32-nios2.c
+++ b/bfd/elf32-nios2.c
@@ -3086,7 +3086,15 @@ lookup:
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
gp_found = TRUE;
- *pgp = lh->u.def.value;
+ {
+ asection *sym_sec = lh->u.def.section;
+ bfd_vma sym_value = lh->u.def.value;
+
+ if (sym_sec->output_section)
+ sym_value = (sym_value + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ *pgp = sym_value;
+ }
break;
case bfd_link_hash_indirect:
case bfd_link_hash_warning:
@@ -3719,7 +3727,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
struct elf32_nios2_link_hash_entry *eh;
bfd_vma relocation;
bfd_vma gp;
- bfd_vma reloc_address;
bfd_reloc_status_type r = bfd_reloc_ok;
const char *name = NULL;
int r_type;
@@ -3762,12 +3769,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
if (bfd_link_relocatable (info))
continue;
- if (sec && sec->output_section)
- reloc_address = (sec->output_section->vma + sec->output_offset
- + rel->r_offset);
- else
- reloc_address = 0;
-
if (howto)
{
switch (howto->type)
@@ -3816,6 +3817,15 @@ nios2_elf32_relocate_section (bfd *output_bfd,
/* Turns an absolute address into a gp-relative address. */
if (!nios2_elf_assign_gp (output_bfd, &gp, info))
{
+ bfd_vma reloc_address;
+
+ if (sec && sec->output_section)
+ reloc_address = (sec->output_section->vma
+ + sec->output_offset
+ + rel->r_offset);
+ else
+ reloc_address = 0;
+
format = _("global pointer relative relocation at address "
"0x%08x when _gp not defined\n");
sprintf (msgbuf, format, reloc_address);
@@ -3825,7 +3835,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
else
{
bfd_vma symbol_address = rel->r_addend + relocation;
- relocation = relocation + rel->r_addend - gp;
+ relocation = symbol_address - gp;
rel->r_addend = 0;
if (((signed) relocation < -32768
|| (signed) relocation > 32767)
@@ -3833,6 +3843,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|| h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
+ if (h)
+ name = h->root.root.string;
format = _("Unable to reach %s (at 0x%08x) from the "
"global pointer (at 0x%08x) because the "
"offset (%d) is out of the allowed range, "
@@ -3848,7 +3860,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
rel->r_offset, relocation,
rel->r_addend);
}
-
break;
case R_NIOS2_UJMP:
r = nios2_elf32_do_ujmp_relocate (input_bfd, howto,
--
2.4.3

View File

@ -1,67 +0,0 @@
From 39c481c2fb0e7fb127a15facf70b55d517462809 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@gmail.com>
Date: Sat, 6 Feb 2016 00:35:31 +0100
Subject: [PATCH 901/901] Fix assertion, reduce number of messages about FDE
encoding
Patch by Nick Clifton [1]
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=19405
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
bfd/elf-eh-frame.c | 17 ++++++++++++++---
bfd/elf32-nios2.c | 4 ++--
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index e303189..e79bff0 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -1369,14 +1369,25 @@ _bfd_elf_discard_section_eh_frame
&& ent->make_relative == 0)
|| (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
{
+ static int num_warnings_issued = 0;
/* If a shared library uses absolute pointers
which we cannot turn into PC relative,
don't create the binary search table,
since it is affected by runtime relocations. */
hdr_info->u.dwarf.table = FALSE;
- (*info->callbacks->einfo)
- (_("%P: FDE encoding in %B(%A) prevents .eh_frame_hdr"
- " table being created.\n"), abfd, sec);
+ if (num_warnings_issued < 10)
+ {
+ (*info->callbacks->einfo)
+ (_("%P: FDE encoding in %B(%A) prevents .eh_frame_hdr"
+ " table being created.\n"), abfd, sec);
+ num_warnings_issued ++;
+ }
+ else if (num_warnings_issued == 10)
+ {
+ (*info->callbacks->einfo)
+ (_("%P: Further warnings about FDE encoding preventing .eh_frame_hdr generation dropped.\n"));
+ num_warnings_issued ++;
+ }
}
ent->removed = 0;
hdr_info->u.dwarf.fde_count++;
diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
index 01ebd6e..d1b7f83 100644
--- a/bfd/elf32-nios2.c
+++ b/bfd/elf32-nios2.c
@@ -1905,8 +1905,8 @@ nios2_elf32_install_imm16 (asection *sec, bfd_vma offset, bfd_vma value)
{
bfd_vma word = bfd_get_32 (sec->owner, sec->contents + offset);
- BFD_ASSERT(value <= 0xffff);
-
+ BFD_ASSERT (value <= 0xffff || ((bfd_signed_vma) value) >= -0xffff);
+
bfd_put_32 (sec->owner, word | ((value & 0xffff) << 6),
sec->contents + offset);
}
--
2.4.3

View File

@ -1,101 +0,0 @@
From eb3e02b484ff75f4a2f54192422a88baa275bdfc Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
substitutions for BFD_RELOC_* as unsigned.
gas/testsuite/
2016-02-03 Max Filippov <jcmvbkbc@gmail.com>
* gas/xtensa/all.exp: Add loc to list of xtensa tests.
* gas/xtensa/loc.d: New file: loc test result patterns.
* gas/xtensa/loc.s: New file: loc test.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
[Rebase on 2.26]
Signed-off-by: Romain Naour <romain.naour@gmail.com>
---
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 d707da8..f623add 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 db39629..4daeff2 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.4.3

View File

@ -1,149 +0,0 @@
From 7db2accc3fdea0aaa0c3a76a413d8e8030e022c3 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
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 <jcmvbkbc@gmail.com>
---
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

View File

@ -1,236 +0,0 @@
From 7827cdf59a1894abe18aa20043a63c8c875c3fce Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Sat, 1 Jun 2013 01:01:44 +0000
Subject: [PATCH] PR other/56780 merge from gcc
binutils-gdb upstream a4818a052efb4cea976a03a2f7cb0b38b23d12d0
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206367 138bc75d-0d04-0410-961f-82ee72b054a4
[Romain
rename patch name
squash the two upstream commits
Remove the ChangeLog]
Signed-off-by: Romain Naour <romain.naour@openwide.fr>
---
libiberty/Makefile.in | 24 ++++++++++-----------
libiberty/configure | 57 +++++++++++++++++++++++++++-----------------------
libiberty/configure.ac | 47 ++++++++++++++++++++++-------------------
3 files changed, 68 insertions(+), 60 deletions(-)
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 0a5da31..4f40c72 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -354,19 +354,19 @@ install-strip: install
# since it will be passed the multilib flags.
MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory`
install_to_libdir: all
- ${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR)
- $(INSTALL_DATA) $(TARGETLIB) $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n
- ( cd $(DESTDIR)$(libdir)/$(MULTIOSDIR) ; chmod 644 $(TARGETLIB)n ;$(RANLIB) $(TARGETLIB)n )
- mv -f $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)
if test -n "${target_header_dir}"; then \
- case "${target_header_dir}" in \
- /*) thd=${target_header_dir};; \
- *) thd=${includedir}/${target_header_dir};; \
- esac; \
- ${mkinstalldirs} $(DESTDIR)$${thd}; \
- for h in ${INSTALLED_HEADERS}; do \
- ${INSTALL_DATA} $$h $(DESTDIR)$${thd}; \
- done; \
+ ${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR); \
+ $(INSTALL_DATA) $(TARGETLIB) $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n; \
+ ( cd $(DESTDIR)$(libdir)/$(MULTIOSDIR) ; chmod 644 $(TARGETLIB)n ;$(RANLIB) $(TARGETLIB)n ); \
+ mv -f $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB); \
+ case "${target_header_dir}" in \
+ /*) thd=${target_header_dir};; \
+ *) thd=${includedir}/${target_header_dir};; \
+ esac; \
+ ${mkinstalldirs} $(DESTDIR)$${thd}; \
+ for h in ${INSTALLED_HEADERS}; do \
+ ${INSTALL_DATA} $$h $(DESTDIR)$${thd}; \
+ done; \
fi
@$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install
diff --git a/libiberty/configure b/libiberty/configure
index 6e98352..44d1f78 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -675,8 +675,8 @@ with_cross_host
with_newlib
enable_maintainer_mode
enable_multilib
-enable_largefile
enable_install_libiberty
+enable_largefile
'
ac_precious_vars='build_alias
host_alias
@@ -1303,8 +1303,8 @@ Optional Features:
enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-multilib build many library versions (default)
+ --enable-install-libiberty Install headers and library for end users
--disable-largefile omit support for large files
- --enable-install-libiberty Install headers for end users
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -2784,6 +2784,35 @@ if test $cross_compiling = no && test $multilib = yes \
cross_compiling=maybe
fi
+# We may wish to install the target headers somewhere.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install libiberty headers and static library" >&5
+$as_echo_n "checking whether to install libiberty headers and static library... " >&6; }
+
+# Check whether --enable-install-libiberty was given.
+if test "${enable_install_libiberty+set}" = set; then :
+ enableval=$enable_install_libiberty; enable_install_libiberty=$enableval
+else
+ enable_install_libiberty=no
+fi
+
+# Option parsed, now set things appropriately.
+case x"$enable_install_libiberty" in
+ xyes|x)
+ target_header_dir=libiberty
+ ;;
+ xno)
+ target_header_dir=
+ ;;
+ *)
+ # This could be sanity-checked in various ways...
+ target_header_dir="${enable_install_libiberty}"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_install_libiberty" >&5
+$as_echo "$enable_install_libiberty" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: target_header_dir = $target_header_dir" >&5
+$as_echo "$as_me: target_header_dir = $target_header_dir" >&6;}
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -5475,7 +5504,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
@@ -5752,29 +5780,6 @@ _ACEOF
esac
- # We may wish to install the target headers somewhere.
- # Check whether --enable-install-libiberty was given.
-if test "${enable_install_libiberty+set}" = set; then :
- enableval=$enable_install_libiberty; enable_install_libiberty=$enableval
-else
- enable_install_libiberty=no
-fi
-
- # Option parsed, now set things appropriately.
- case x"$enable_install_libiberty" in
- xyes|x)
- target_header_dir=libiberty
- ;;
- xno)
- target_header_dir=
- ;;
- *)
- # This could be sanity-checked in various ways...
- target_header_dir="${enable_install_libiberty}"
- ;;
- esac
-
-
else
# Not a target library, so we set things up to run the test suite.
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 754b66a..04260ec 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -128,6 +128,31 @@ if test $cross_compiling = no && test $multilib = yes \
cross_compiling=maybe
fi
+# We may wish to install the target headers somewhere.
+AC_MSG_CHECKING([whether to install libiberty headers and static library])
+dnl install-libiberty is disabled by default
+
+AC_ARG_ENABLE(install-libiberty,
+[ --enable-install-libiberty Install headers and library for end users],
+enable_install_libiberty=$enableval,
+enable_install_libiberty=no)dnl
+
+# Option parsed, now set things appropriately.
+case x"$enable_install_libiberty" in
+ xyes|x)
+ target_header_dir=libiberty
+ ;;
+ xno)
+ target_header_dir=
+ ;;
+ *)
+ # This could be sanity-checked in various ways...
+ target_header_dir="${enable_install_libiberty}"
+ ;;
+esac
+AC_MSG_RESULT($enable_install_libiberty)
+AC_MSG_NOTICE([target_header_dir = $target_header_dir])
+
GCC_NO_EXECUTABLES
AC_PROG_CC
AC_SYS_LARGEFILE
@@ -379,7 +404,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
@@ -490,27 +514,6 @@ if test -n "${with_target_subdir}"; then
esac
- # We may wish to install the target headers somewhere.
- AC_ARG_ENABLE(install-libiberty,
- [ --enable-install-libiberty Install headers for end users],
- enable_install_libiberty=$enableval,
- enable_install_libiberty=no)dnl
-
- # Option parsed, now set things appropriately.
- case x"$enable_install_libiberty" in
- xyes|x)
- target_header_dir=libiberty
- ;;
- xno)
- target_header_dir=
- ;;
- *)
- # This could be sanity-checked in various ways...
- target_header_dir="${enable_install_libiberty}"
- ;;
- esac
-
-
else
# Not a target library, so we set things up to run the test suite.
--
1.9.3

View File

@ -1,279 +0,0 @@
Patch adapted to binutils arc-4.8-R3 and extended to use
BR_COMPILER_PARANOID_UNSAFE_PATH by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
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 <joseph@codesourcery.com>
Merge from Sourcery G++ binutils 2.17:
2007-03-20 Joseph Myers <joseph@codesourcery.com>
Based on patch by Mark Hatle <mark.hatle@windriver.com>.
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 <mark.hatle@windriver.com>
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
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=<type> 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
@@ -2156,6 +2156,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. */

View File

@ -1,91 +0,0 @@
From 74ff2db959c5fa75bec770c41ed2951a740fe936 Mon Sep 17 00:00:00 2001
From: jzmaddock <jz.maddock@gmail.com>
Date: Fri, 1 Jan 2016 16:49:48 +0000
Subject: [PATCH] Change <quadmath.h> config to not use it at all if we don't
have __has_include as GCC may be configured with --disable-libquadmath but
still signal that it supports __float128
Backported from: 74ff2db959c5fa75bec770c41ed2951a740fe936
[Jörg Krause: adjust pathes to match sourceforge release tarball]
Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
---
boost/math/special_functions/fpclassify.hpp | 16 +++++++++++++---
boost/math/tools/config.hpp | 12 ------------
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/boost/math/special_functions/fpclassify.hpp b/boost/math/special_functions/fpclassify.hpp
index 0a4e1ac..58fad13 100644
--- a/boost/math/special_functions/fpclassify.hpp
+++ b/boost/math/special_functions/fpclassify.hpp
@@ -81,7 +81,12 @@ is used.
#include <float.h>
#endif
#ifdef BOOST_MATH_USE_FLOAT128
+#ifdef __has_include
+#if __has_include("quadmath.h")
#include "quadmath.h"
+#define BOOST_MATH_HAS_QUADMATH_H
+#endif
+#endif
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
@@ -124,9 +129,14 @@ inline bool is_nan_helper(T, const boost::false_type&)
{
return false;
}
-#ifdef BOOST_MATH_USE_FLOAT128
+#if defined(BOOST_MATH_USE_FLOAT128)
+#if defined(BOOST_MATH_HAS_QUADMATH_H)
inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnanq(f); }
inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnanq(f); }
+#else
+inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnan(static_cast<double>(f)); }
+inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnan(static_cast<double>(f)); }
+#endif
#endif
}
@@ -519,7 +529,7 @@ inline bool (isinf)(long double x)
return detail::isinf_impl(static_cast<value_type>(x), method());
}
#endif
-#ifdef BOOST_MATH_USE_FLOAT128
+#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
template<>
inline bool (isinf)(__float128 x)
{
@@ -611,7 +621,7 @@ inline bool (isnan)(long double x)
return detail::isnan_impl(x, method());
}
#endif
-#ifdef BOOST_MATH_USE_FLOAT128
+#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
template<>
inline bool (isnan)(__float128 x)
{
diff --git a/boost/math/tools/config.hpp b/boost/math/tools/config.hpp
index ffd0ab4..75d29b6 100644
--- a/boost/math/tools/config.hpp
+++ b/boost/math/tools/config.hpp
@@ -265,18 +265,6 @@
# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF
#endif
//
-// Test whether to support __float128, if we don't have quadmath.h then this can't currently work:
-//
-#ifndef BOOST_MATH_USE_FLOAT128
-#ifdef __has_include
-#if ! __has_include("quadmath.h")
-#define BOOST_MATH_DISABLE_FLOAT128
-#endif
-#elif !defined(BOOST_ARCH_X86)
-#define BOOST_MATH_DISABLE_FLOAT128
-#endif
-#endif
-//
// And then the actual configuration:
//
#if defined(_GLIBCXX_USE_FLOAT128) && defined(BOOST_GCC) && !defined(__STRICT_ANSI__) \

View File

@ -1,50 +0,0 @@
From a4e9686f8a0258bc30f9da2abab65673d6b9bd50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jupp=20M=C3=BCller?= <jupp0r@gmail.com>
Date: Wed, 23 Dec 2015 09:18:51 +0100
Subject: [PATCH] Fix declaration changes meaning error with GCC 4.4.7 (#11856)
Backported from a4e9686f8a0258bc30f9da2abab65673d6b9bd50
[Jörg Krause: adjust pathes to match sourceforge release tarball]
Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
---
libs/container/src/pool_resource.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libs/container/src/pool_resource.cpp b/libs/container/src/pool_resource.cpp
index 4df7ee2..45f1564 100644
--- a/libs/container/src/pool_resource.cpp
+++ b/libs/container/src/pool_resource.cpp
@@ -32,11 +32,11 @@ namespace pmr {
class pool_data_t
: public block_slist_base<>
{
- typedef block_slist_base<> block_slist_base;
+ typedef block_slist_base<> block_slist_base_t;
public:
explicit pool_data_t(std::size_t initial_blocks_per_chunk)
- : block_slist_base(), next_blocks_per_chunk(initial_blocks_per_chunk)
+ : block_slist_base_t(), next_blocks_per_chunk(initial_blocks_per_chunk)
{ slist_algo::init_header(&free_slist); }
void *allocate_block() BOOST_NOEXCEPT
@@ -59,7 +59,7 @@ class pool_data_t
void release(memory_resource &upstream)
{
slist_algo::init_header(&free_slist);
- this->block_slist_base::release(upstream);
+ this->block_slist_base_t::release(upstream);
next_blocks_per_chunk = pool_options_minimum_max_blocks_per_chunk;
}
@@ -72,7 +72,7 @@ class pool_data_t
//Minimum block size is at least max_align, so all pools allocate sizes that are multiple of max_align,
//meaning that all blocks are max_align-aligned.
- char *p = static_cast<char *>(block_slist_base::allocate(blocks_per_chunk*pool_block, mr));
+ char *p = static_cast<char *>(block_slist_base_t::allocate(blocks_per_chunk*pool_block, mr));
//Create header types. This is no-throw
for(std::size_t i = 0, max = blocks_per_chunk; i != max; ++i){

View File

@ -1,32 +0,0 @@
From fbd1393858719c7bda7d251f742950c1bc691ea8 Mon Sep 17 00:00:00 2001
From: Kohei Takahashi <flast@flast.jp>
Date: Wed, 6 Jan 2016 19:39:55 +0900
Subject: [PATCH] Qualify std:: for isnan in some situation.
Because isnan is implemented as a macro and libstdc++ undef it within
<cmath> (at least FreeBSD 10).
Backported from fbd1393858719c7bda7d251f742950c1bc691ea8
[Jörg Krause: adjust pathes to match sourceforge release tarball]
Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
---
boost/math/special_functions/fpclassify.hpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/boost/math/special_functions/fpclassify.hpp b/boost/math/special_functions/fpclassify.hpp
index 58fad13..d83e111 100644
--- a/boost/math/special_functions/fpclassify.hpp
+++ b/boost/math/special_functions/fpclassify.hpp
@@ -133,6 +133,10 @@ inline bool is_nan_helper(T, const boost::false_type&)
#if defined(BOOST_MATH_HAS_QUADMATH_H)
inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnanq(f); }
inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnanq(f); }
+#elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \
+ _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
+inline bool is_nan_helper(__float128 f, const boost::true_type&) { return std::isnan(static_cast<double>(f)); }
+inline bool is_nan_helper(__float128 f, const boost::false_type&) { return std::isnan(static_cast<double>(f)); }
#else
inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnan(static_cast<double>(f)); }
inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnan(static_cast<double>(f)); }

View File

@ -1,37 +0,0 @@
Disable fenv.h in certain configurations
The boost build system does not properly test whether fenv.h is
available, and if it is, if it supports all the features used by
Boost. This causes build failures with uClibc (reported upstream at
https://svn.boost.org/trac/boost/ticket/11756) but also with glibc on
specific architectures that don't have a full fenv implementation,
such as NIOSII or Microblaze.
To address this, we forcefully disable the use of fenv support in the
affected configurations.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[Thomas: add Microblaze/NIOSII exclusions.]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Index: b/boost/config/platform/linux.hpp
===================================================================
--- a/boost/config/platform/linux.hpp
+++ b/boost/config/platform/linux.hpp
@@ -47,6 +47,16 @@
#endif
//
+// uClibc has no support for fenv.h, and also a few architectures
+// don't have fenv.h support at all (or incomplete support) even with
+// glibc.
+
+//
+#if defined(__UCLIBC__) || defined(__nios2__) || defined(__microblaze__)
+# define BOOST_NO_FENV_H
+#endif
+
+//
// If glibc is past version 2 then we definitely have
// gettimeofday, earlier versions may or may not have it:
//

View File

@ -1,45 +0,0 @@
From 4f1c6784b37a11c78fe84bb238fb7cc377ce0d36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Krause?= <joerg.krause@embedded.rocks>
Date: Wed, 30 Mar 2016 23:28:33 +0200
Subject: [PATCH] Fix for uClibc and gcc <= 4.8.2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
getchar() is defined as a macro in uClibc. This hits gcc bug 58952 [1] for all
gcc version <= 4.8.2 and building boost/test fails:
./boost/test/impl/unit_test_main.ipp: In function 'int boost::unit_test::unit_test_main(boost::unit_test::init_unit_test_func, int, char**)':
./boost/test/impl/unit_test_main.ipp:194:18: error: expected unqualified-id before '(' token
To allow building boost/test with uClibc based toolchains with gcc <= 4.8.2 use
parenthesis for std::getchar.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58952
Upstream status: Pending
https://github.com/boostorg/test/pull/97
Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
---
include/boost/test/impl/unit_test_main.ipp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index 1f30c02..db61930 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -191,7 +191,9 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
if( runtime_config::get<bool>( runtime_config::WAIT_FOR_DEBUGGER ) ) {
results_reporter::get_stream() << "Press any key to continue..." << std::endl;
- std::getchar();
+ // getchar is defined as a macro in uClibc. Use parenthesis to fix
+ // gcc bug 58952 for gcc <= 4.8.2.
+ (std::getchar)();
results_reporter::get_stream() << "Continuing..." << std::endl;
}
--
2.7.4

View File

@ -1,30 +0,0 @@
commit 5eebb7f9288b7881ffb929b1fd494fe3ac3be27d
Author: Russell Senior <russell@personaltelco.net>
Date: Wed Mar 6 12:49:42 2013 -0800
bridge-utils: Fix compile against linux-3.8.x
Linux 3.8 has a header, include/uapi/linux/if_bridge.h that uses a
struct in6_addr but doesn't define it. The trivial seeming fix of
including the header that does define it causes more problems. The
problem was discussed on mailing lists in January 2013. The final
suggestion I found was here:
http://www.redhat.com/archives/libvir-list/2013-January/msg01253.html
This is intended to implement that suggestion.
Signed-off-by: Russell Senior <russell@personaltelco.net>
diff --git a/libbridge/libbridge.h b/libbridge/libbridge.h
index 39964f2..dd14bae 100644
--- a/libbridge/libbridge.h
+++ b/libbridge/libbridge.h
@@ -20,6 +20,7 @@
#define _LIBBRIDGE_H
#include <sys/socket.h>
+#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_bridge.h>

View File

@ -1,81 +0,0 @@
commit bb9970a9df95837e39d680021b1f73d231e85406
Author: Stephen Hemminger <shemminger@vyatta.com>
Date: Tue May 3 09:52:43 2011 -0700
Check error returns from write to sysfs
Add helper function to check write to sysfs files.
Fix incorrect sysfs path in br_set.
[Thomas De Schampheleire: update commit message only]
Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
diff --git a/libbridge/libbridge_devif.c b/libbridge/libbridge_devif.c
index aa8bc36..1e83925 100644
--- a/libbridge/libbridge_devif.c
+++ b/libbridge/libbridge_devif.c
@@ -280,25 +280,38 @@ fallback:
return old_get_port_info(brname, port, info);
}
+static int set_sysfs(const char *path, unsigned long value)
+{
+ int fd, ret = 0, cc;
+ char buf[32];
+
+ fd = open(path, O_WRONLY);
+ if (fd < 0)
+ return -1;
+
+ cc = snprintf(buf, sizeof(buf), "%lu\n", value);
+ if (write(fd, buf, cc) < 0)
+ ret = -1;
+ close(fd);
+
+ return ret;
+}
+
static int br_set(const char *bridge, const char *name,
unsigned long value, unsigned long oldcode)
{
int ret;
char path[SYSFS_PATH_MAX];
- FILE *f;
- snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/%s", bridge, name);
+ snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/bridge/%s",
+ bridge, name);
- f = fopen(path, "w");
- if (f) {
- ret = fprintf(f, "%ld\n", value);
- fclose(f);
- } else {
+ if ((ret = set_sysfs(path, value)) < 0) {
/* fallback to old ioctl */
struct ifreq ifr;
unsigned long args[4] = { oldcode, value, 0, 0 };
-
+
strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
ifr.ifr_data = (char *) &args;
ret = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
@@ -348,14 +361,10 @@ static int port_set(const char *bridge, const char *ifname,
{
int ret;
char path[SYSFS_PATH_MAX];
- FILE *f;
snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "%s/brport/%s", ifname, name);
- f = fopen(path, "w");
- if (f) {
- ret = fprintf(f, "%ld\n", value);
- fclose(f);
- } else {
+
+ if ((ret = set_sysfs(path, value)) < 0) {
int index = get_portno(bridge, ifname);
if (index < 0)

View File

@ -1,132 +0,0 @@
From 9bef473d17ec01efe760462271791dfaaea280c0 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Wed, 29 Jul 2015 22:35:19 +0200
Subject: [PATCH 1/3] configure: refactor backtrace() detection
The current code assumes that if __GLIBC__ is not defined, backtrace
support is not available, and defines BTRFS_DISABLE_BACKTRACE.
However, this macro is already defined by the configure.ac script when
--disable-backtrace is passed. This means that if you are using a C
library like musl which does not define __GLIBC__, and you pass
--disable-backtrace, you get a macro redefinition.
Instead of relying on __GLIBC__, this commit implements a proper
configure.ac based detection of backtrace support:
* If the user passes --enable-backtrace, we check if the backtrace()
function is available. If not, we abort the configure process with
an error. Otherwise we enable backtrace support by defining
HAVE_BACKTRACE.
* If the user passes --disable-backtrace, then we don't enable
backtrace support.
* If the user passes nothing special, we auto-detect: if backtrace()
is available, we use it, otherwise we simply warn at configure time
but not fail.
Upstream-status: pending
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Brendan Heading <brendanheading@gmail.com>
---
configure.ac | 32 ++++++++++++++++++++++----------
kerncompat.h | 9 ++++-----
2 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index c3a22d1..e936a10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,22 +63,34 @@ AC_DEFUN([PKG_STATIC], [
fi
])
-
+# Provide a --{enable,disable}-backtrace option. If not passed, set
+# enable_backtrace to 'auto' so that we try to enable backtrace
+# support if available, but if not available, we gracefully fallback
+# without backtrace support.
AC_ARG_ENABLE([backtrace],
AS_HELP_STRING([--disable-backtrace], [disable btrfs backtrace]),
- [], [enable_backtrace=yes]
+ [enable_backtrace=${enableval}], [enable_backtrace=auto]
)
-AS_IF([test "x$enable_backtrace" = xno], [
- AC_DEFINE([BTRFS_DISABLE_BACKTRACE], [1], [disable backtrace stuff in kerncompat.h ])
-])
-
-if test "x$enable_backtrace" = xyes; then
- AC_CHECK_HEADERS([execinfo.h])
- AC_CHECK_FUNCS([backtrace backtrace_symbols_fd], [],
- AC_MSG_ERROR([standard library does not have backtrace support]))
+# Backtrace support requested (enable_backtrace is either 'yes' or
+# 'auto'), so check for needed headers and functions.
+if test "x$enable_backtrace" != xno; then
+ AC_CHECK_HEADERS([execinfo.h])
+ AC_CHECK_FUNCS([backtrace backtrace_symbols_fd])
fi
+if test "x$ac_cv_func_backtrace" = xno; then
+ # If backtrace support was requested but not available, we fail if
+ # --enable-backtrace was passed, or we simply warn if we're
+ # auto-detecting.
+ if test "x$enable_backtrace" = xyes ; then
+ AC_MSG_ERROR([standard library does not have backtrace support])
+ elif test "x$enable_backtrace" = xauto ; then
+ AC_MSG_WARN([standard library does not have backtrace support, disabled])
+ fi
+else
+ AC_DEFINE([HAVE_BACKTRACE], [1], [Enable backtrace support])
+fi
AC_ARG_ENABLE([documentation],
AS_HELP_STRING([--disable-documentation], [do not build domumentation]),
diff --git a/kerncompat.h b/kerncompat.h
index 5d92856..8318665 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -33,11 +33,10 @@
#include <features.h>
#ifndef __GLIBC__
-#define BTRFS_DISABLE_BACKTRACE
#define __always_inline __inline __attribute__ ((__always_inline__))
#endif
-#ifndef BTRFS_DISABLE_BACKTRACE
+#ifdef HAVE_BACKTRACE
#include <execinfo.h>
#endif
@@ -65,7 +64,7 @@
#define ULONG_MAX (~0UL)
#endif
-#ifndef BTRFS_DISABLE_BACKTRACE
+#ifdef HAVE_BACKTRACE
#define MAX_BACKTRACE 16
static inline void print_trace(void)
{
@@ -285,7 +284,7 @@ static inline long IS_ERR(const void *ptr)
#define vmalloc(x) malloc(x)
#define vfree(x) free(x)
-#ifndef BTRFS_DISABLE_BACKTRACE
+#ifdef HAVE_BACKTRACE
#define BUG_ON(c) assert_trace(#c, __FILE__, __func__, __LINE__, !(c))
#else
#define BUG_ON(c) assert(!(c))
@@ -293,7 +292,7 @@ static inline long IS_ERR(const void *ptr)
#define WARN_ON(c) BUG_ON(c)
-#ifndef BTRFS_DISABLE_BACKTRACE
+#ifdef HAVE_BACKTRACE
#define ASSERT(c) assert_trace(#c, __FILE__, __func__, __LINE__, (c))
#else
#define ASSERT(c) assert(c)
--
2.4.3

View File

@ -1,42 +0,0 @@
From 1d99ae25bb1bd4879c6f20f607faf3040018ee84 Mon Sep 17 00:00:00 2001
From: Brendan Heading <brendanheading@gmail.com>
Date: Thu, 30 Jul 2015 15:44:52 +0100
Subject: [PATCH 2/3] configure: refactor always_inline detection
Use configure.ac to detect the availability of the always_inline glibc
macro, and define it only if it does not exist.
Signed-off-by: Brendan Heading <brendanheading@gmail.com>
---
configure.ac | 1 +
kerncompat.h | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index e936a10..d3d81a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,7 @@ AC_PATH_PROG([RMDIR], [rmdir], [rmdir])
AC_CHECK_FUNCS([openat], [],
[AC_MSG_ERROR([cannot find openat() function])])
+AC_CHECK_DECLS([__always_inline])
m4_ifndef([PKG_PROG_PKG_CONFIG],
[m4_fatal([Could not locate the pkg-config autoconf
diff --git a/kerncompat.h b/kerncompat.h
index 8318665..757b9b4 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -32,7 +32,7 @@
#include <features.h>
-#ifndef __GLIBC__
+#ifndef HAVE_DECL___ALWAYS_INLINE
#define __always_inline __inline __attribute__ ((__always_inline__))
#endif
--
2.4.3

View File

@ -1,67 +0,0 @@
From 3197a4b058615d81aa4623fb5a52e57d7fbc3af2 Mon Sep 17 00:00:00 2001
From: Brendan Heading <brendanheading@gmail.com>
Date: Thu, 30 Jul 2015 15:47:16 +0100
Subject: [PATCH 3/3] compile: fix undefined PATH_MAX under musl
musl's strict implementation requires #include <limits.h> for PATH_MAX.
Upstream-status: submitted
Signed-off-by: Brendan Heading <brendanheading@gmail.com>
---
cmds-inspect.c | 1 +
cmds-receive.c | 1 +
cmds-scrub.c | 1 +
cmds-send.c | 1 +
4 files changed, 4 insertions(+)
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 71451fe..9712581 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/ioctl.h>
#include <errno.h>
+#include <limits.h>
#include "kerncompat.h"
#include "ioctl.h"
diff --git a/cmds-receive.c b/cmds-receive.c
index 071bea9..d4b3103 100644
--- a/cmds-receive.c
+++ b/cmds-receive.c
@@ -28,6 +28,7 @@
#include <wait.h>
#include <assert.h>
#include <getopt.h>
+#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
diff --git a/cmds-scrub.c b/cmds-scrub.c
index b7aa809..5a85dc4 100644
--- a/cmds-scrub.c
+++ b/cmds-scrub.c
@@ -34,6 +34,7 @@
#include <ctype.h>
#include <signal.h>
#include <stdarg.h>
+#include <limits.h>
#include "ctree.h"
#include "ioctl.h"
diff --git a/cmds-send.c b/cmds-send.c
index 20bba18..a0b7f95 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -33,6 +33,7 @@
#include <assert.h>
#include <getopt.h>
#include <uuid/uuid.h>
+#include <limits.h>
#include "ctree.h"
#include "ioctl.h"
--
2.4.3

View File

@ -1,84 +0,0 @@
From 4194c2875310c13ee3ca2bb0e1aea6a2ae67c55a Mon Sep 17 00:00:00 2001
From: Ron Yorston <rmy@pobox.com>
Date: Thu, 29 Oct 2015 16:44:56 +0000
Subject: [PATCH] ash: fix error during recursive processing of here document
Save the value of the checkkwd flag to prevent it being clobbered
during recursion.
Based on commit ec2c84d from git://git.kernel.org/pub/scm/utils/dash/dash.git
by Herbert Xu.
function old new delta
readtoken 190 203 +13
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 13/0) Total: 13 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
(cherry picked from commit 713f07d906d9171953be0c12e2369869855b6ca6)
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
---
shell/ash.c | 5 +++--
shell/ash_test/ash-heredoc/heredoc3.right | 1 +
shell/ash_test/ash-heredoc/heredoc3.tests | 9 +++++++++
3 files changed, 13 insertions(+), 2 deletions(-)
create mode 100644 shell/ash_test/ash-heredoc/heredoc3.right
create mode 100755 shell/ash_test/ash-heredoc/heredoc3.tests
diff --git a/shell/ash.c b/shell/ash.c
index 8a1628e..256e933 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -11893,6 +11893,7 @@ static int
readtoken(void)
{
int t;
+ int kwd = checkkwd;
#if DEBUG
smallint alreadyseen = tokpushback;
#endif
@@ -11906,7 +11907,7 @@ readtoken(void)
/*
* eat newlines
*/
- if (checkkwd & CHKNL) {
+ if (kwd & CHKNL) {
while (t == TNL) {
parseheredoc();
t = xxreadtoken();
@@ -11920,7 +11921,7 @@ readtoken(void)
/*
* check for keywords
*/
- if (checkkwd & CHKKWD) {
+ if (kwd & CHKKWD) {
const char *const *pp;
pp = findkwd(wordtext);
diff --git a/shell/ash_test/ash-heredoc/heredoc3.right b/shell/ash_test/ash-heredoc/heredoc3.right
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc3.right
@@ -0,0 +1 @@
+hello
diff --git a/shell/ash_test/ash-heredoc/heredoc3.tests b/shell/ash_test/ash-heredoc/heredoc3.tests
new file mode 100755
index 0000000..96c227c
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc3.tests
@@ -0,0 +1,9 @@
+echo hello >greeting
+cat <<EOF &&
+$(cat greeting)
+EOF
+{
+ echo $?
+ cat greeting
+} >/dev/null
+rm greeting
--
2.7.4

View File

@ -1,73 +0,0 @@
From 3c4de6e36c4d387a648622e7b828a05f2b1b47e6 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Fri, 26 Feb 2016 15:54:56 +0100
Subject: [PATCH] udhcpc: fix OPTION_6RD parsing (could overflow its malloced
buffer)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
(cherry picked from commit 352f79acbd759c14399e39baef21fc4ffe180ac2)
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
---
networking/udhcp/common.c | 15 +++++++++++++--
networking/udhcp/dhcpc.c | 4 ++--
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index bc41c8d..680852c 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -142,7 +142,7 @@ const char dhcp_option_strings[] ALIGN1 =
* udhcp_str2optset: to determine how many bytes to allocate.
* xmalloc_optname_optval: to estimate string length
* from binary option length: (option[LEN] / dhcp_option_lengths[opt_type])
- * is the number of elements, multiply in by one element's string width
+ * is the number of elements, multiply it by one element's string width
* (len_of_option_as_string[opt_type]) and you know how wide string you need.
*/
const uint8_t dhcp_option_lengths[] ALIGN1 = {
@@ -162,7 +162,18 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = {
[OPTION_S32] = 4,
/* Just like OPTION_STRING, we use minimum length here */
[OPTION_STATIC_ROUTES] = 5,
- [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */
+ [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */
+ /* The above value was chosen as follows:
+ * len_of_option_as_string[] for this option is >60: it's a string of the form
+ * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ".
+ * Each additional ipv4 address takes 4 bytes in binary option and appends
+ * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4
+ * but this severely overestimates string length: instead of 16 bytes,
+ * it adds >60 for every 4 bytes in binary option.
+ * We cheat and declare here that option is in units of 12 bytes.
+ * This adds more than 60 bytes for every three ipv4 addresses - more than enough.
+ * (Even 16 instead of 12 should work, but let's be paranoid).
+ */
};
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 915f659..2332b57 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -113,7 +113,7 @@ static const uint8_t len_of_option_as_string[] = {
[OPTION_IP ] = sizeof("255.255.255.255 "),
[OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2,
[OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "),
- [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
+ [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
[OPTION_STRING ] = 1,
[OPTION_STRING_HOST ] = 1,
#if ENABLE_FEATURE_UDHCP_RFC3397
@@ -220,7 +220,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
type = optflag->flags & OPTION_TYPE_MASK;
optlen = dhcp_option_lengths[type];
upper_length = len_of_option_as_string[type]
- * ((unsigned)(len + optlen - 1) / (unsigned)optlen);
+ * ((unsigned)(len + optlen) / (unsigned)optlen);
dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
dest += sprintf(ret, "%s=", opt_name);
--
2.7.4

View File

@ -1,56 +0,0 @@
From 3a76bb5136d05f94ee62e377aa723e63444912c7 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Thu, 10 Mar 2016 11:47:58 +0100
Subject: [PATCH] udhcp: fix a SEGV on malformed RFC1035-encoded domain name
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
(cherry picked from commit d474ffc68290e0a83651c4432eeabfa62cd51e87)
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
---
networking/udhcp/domain_codec.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c
index c1325d8..8429367 100644
--- a/networking/udhcp/domain_codec.c
+++ b/networking/udhcp/domain_codec.c
@@ -63,11 +63,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
if (crtpos + *c + 1 > clen) /* label too long? abort */
return NULL;
if (dst)
- memcpy(dst + len, c + 1, *c);
+ /* \3com ---> "com." */
+ ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.';
len += *c + 1;
crtpos += *c + 1;
- if (dst)
- dst[len - 1] = '.';
} else {
/* NUL: end of current domain name */
if (retpos == 0) {
@@ -78,7 +77,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
crtpos = retpos;
retpos = depth = 0;
}
- if (dst)
+ if (dst && len != 0)
+ /* \4host\3com\0\4host and we are at \0:
+ * \3com was converted to "com.", change dot to space.
+ */
dst[len - 1] = ' ';
}
@@ -228,6 +230,9 @@ int main(int argc, char **argv)
int len;
uint8_t *encoded;
+ uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 };
+ printf("NUL:'%s'\n", dname_dec(str, 6, ""));
+
#define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre))
printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:"));
printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", ""));
--
2.7.4

View File

@ -1,37 +0,0 @@
From d7b20d9bbed23a7a7e40af2f5e78f37ff67e8d93 Mon Sep 17 00:00:00 2001
From: Rodrigo Rebello <rprebello@gmail.com>
Date: Mon, 23 Nov 2015 02:12:48 -0200
Subject: [PATCH] src: fix build with musl libc
The GNU version of 'struct tcphdr' is not exposed by musl libc headers
unless _GNU_SOURCE is defined. Without this definition, the build fails
with:
rpc.c: In function 'rpc_helper_cb':
rpc.c:351:15: error: 'struct tcphdr' has no member named 'doff'
offset += th->doff * 4;
^
Upstream status: sent
http://patchwork.ozlabs.org/patch/547376/
Signed-off-by: Rodrigo Rebello <rprebello@gmail.com>
---
src/helpers/rpc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/helpers/rpc.c b/src/helpers/rpc.c
index 82493c2..3a7b337 100644
--- a/src/helpers/rpc.c
+++ b/src/helpers/rpc.c
@@ -28,6 +28,7 @@
#include <rpc/rpc_msg.h>
#include <rpc/pmap_prot.h>
+#define _GNU_SOURCE
#include <netinet/tcp.h>
#include <netinet/udp.h>
--
2.1.4

View File

@ -1,21 +0,0 @@
Remove PIE flags from the build
Generating a statically linked binary built with PIE requires the
Scrt1.o file, which isn't part of Buildroot uClibc toolchains. To
solve this, we simply disable the PIE flags.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Index: b/Makedefs.in
===================================================================
--- a/Makedefs.in
+++ b/Makedefs.in
@@ -142,7 +142,7 @@
IPPFIND_MAN = @IPPFIND_MAN@
LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
-L../scheduler @LDARCHFLAGS@ \
- @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+ @LDFLAGS@ @RELROFLAGS@ $(OPTIM)
LINKCUPS = @LINKCUPS@ $(LIBGSSAPI) $(DNSSDLIBS) $(LIBZ)
LINKCUPSIMAGE = @LINKCUPSIMAGE@
LIBS = $(LINKCUPS) $(COMMONLIBS)

View File

@ -1,34 +0,0 @@
dhcp cross compile support integration
Allow BINDCONFIG to be initialized in environment passed to configure.
Allow archiver to be determined during configure.
This patch is submitted upstream as part of a cross compiling enhancement
suggestion to dhcp-suggest@isc.org. Reference ISC-Bugs #41502.
Signed-off-by: Doug Kehn <rdkehn@yahoo.com>
Index: dhcp-4.3.3-P1/configure.ac
===================================================================
--- dhcp-4.3.3-P1.orig/configure.ac
+++ dhcp-4.3.3-P1/configure.ac
@@ -33,7 +33,7 @@ if test "$GCC" = "yes"; then
fi
# We can have some flags to pass to bind configure
-BINDCONFIG=
+BINDCONFIG="$BINDCONFIG"
AC_SUBST(BINDCONFIG)
# POSIX doesn't include the IPv6 Advanced Socket API and glibc hides
@@ -43,6 +43,9 @@ AC_SUBST(BINDCONFIG)
# Use this to define _GNU_SOURCE to pull in the IPv6 Advanced Socket API.
AC_USE_SYSTEM_EXTENSIONS
+AC_CHECK_TOOL(AR,ar)
+AC_SUBST(AR)
+
AC_PROG_RANLIB
AC_CONFIG_HEADERS([includes/config.h])

View File

@ -1,40 +0,0 @@
ensure host compiler is used
dns/Makefile.in patch is derived from:
http://wiki.beyondlogic.org/patches/dhcp-4.3.0b1.bind_arm-linux-gnueabi.patch
This patch is already accepted upstream and will be included in the next
release:
--[snip]--
From Francis Dupont via RT <dhcp-suggest@isc.org>
To rdkehn@yahoo.com
Message body
It was fixed on the master branch sometimes ago.
Quoting master RELNOTES:
- Made the embedded bind libraries able to be cross compiled
(please refer to the bind9 documentation to learn how to cross
compile DHCP and its bind library dependency).
[ISC-Bugs #38836]
This is in the Changes since 4.3.3 so for the next release.
--[snip]--
Signed-off-by: Doug Kehn <rdkehn@yahoo.com>
Index: dhcp-4.3.3-P1/bind/bind-9.9.7-P3/lib/export/dns/Makefile.in
===================================================================
--- dhcp-4.3.3-P1.orig/bind/bind-9.9.7-P3/lib/export/dns/Makefile.in
+++ dhcp-4.3.3-P1/bind/bind-9.9.7-P3/lib/export/dns/Makefile.in
@@ -168,7 +168,9 @@ code.h: gen
./gen -s ${srcdir} > code.h
gen: ${srcdir}/gen.c
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS}
+ ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \
+ ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c \
+ ${BUILD_LIBS}
#We don't need rbtdb64 for this library
#rbtdb64.@O@: rbtdb.c

View File

@ -1,45 +0,0 @@
From 7a589ef6dab52ad32a296939f0ed2acb4d76b2a7 Mon Sep 17 00:00:00 2001
From: "Yann E. MORIN" <yann.morin.1998@free.fr>
Date: Sun, 16 Aug 2015 15:55:43 +0200
Subject: [PATCH] mkfs.fat: fix incorrect int type
u_int32_t is not a stanard type, while uint32_t is. This fixes builds
with the musl C library, which only defines so-called "clean" headers;
build failures are like (back-quotes and elision manually added for
readability):
http://autobuild.buildroot.org/results/a09/a0923d7f6d4dbae02eba4c5024bbdae3a52aa85a/build-end.log
/home/peko/autobuild/instance-1/output/host/usr/bin/x86_64-linux-gcc -D_LARGEFILE_SOURCE \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -D_GNU_SOURCE -D_LARGEFILE_SOURCE \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o mkfs.fat.o src/mkfs.fat.c
src/mkfs.fat.c: In function 'main':
src/mkfs.fat.c:1415:18: error: 'u_int32_t' undeclared (first use in this function)
volume_id = (u_int32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); [...]
^
src/mkfs.fat.c:1415:18: note: each undeclared identifier is reported only once for each
function it appears in
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
Upstream status: applied: https://github.com/dosfstools/dosfstools/pull/9
---
src/mkfs.fat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/mkfs.fat.c b/src/mkfs.fat.c
index b38d116..dddbe24 100644
--- a/src/mkfs.fat.c
+++ b/src/mkfs.fat.c
@@ -1412,7 +1412,7 @@ int main(int argc, char **argv)
gettimeofday(&create_timeval, NULL);
create_time = create_timeval.tv_sec;
- volume_id = (u_int32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); /* Default volume ID = creation time, fudged for more uniqueness */
+ volume_id = (uint32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); /* Default volume ID = creation time, fudged for more uniqueness */
check_atari();
printf("mkfs.fat " VERSION " (" VERSION_DATE ")\n");
--
1.9.1

View File

@ -1,15 +0,0 @@
config BR2_PACKAGE_ELEMENTARY
bool "elementary"
depends on BR2_PACKAGE_EFL
depends on BR2_TOOLCHAIN_HAS_THREADS # elm_store.c
depends on !BR2_STATIC_LIBS
help
Elementary is a widget toolkit and EFL wrapper and convenience
library to make it easy to build applications and tools with UIs
with less code.
https://enlightenment.org
comment "elementary needs a toolchain w/ threads, dynamic library"
depends on BR2_PACKAGE_EFL
depends on !BR2_TOOLCHAIN_HAS_THREADS || BR2_STATIC_LIBS

View File

@ -1,2 +0,0 @@
# From https://download.enlightenment.org/rel/libs/elementary/elementary-1.15.3.tar.xz.sha256
sha256 474a9175061021ce8cbcfdbde6162316fc0d927b21118d1ab549377ebc802a93 elementary-1.15.3.tar.xz

View File

@ -1,37 +0,0 @@
################################################################################
#
# elementary
#
################################################################################
ELEMENTARY_VERSION = 1.15.3
ELEMENTARY_SOURCE = elementary-$(ELEMENTARY_VERSION).tar.xz
ELEMENTARY_SITE = http://download.enlightenment.org/rel/libs/elementary
ELEMENTARY_LICENSE = LGPLv2.1
ELEMENTARY_LICENSE_FILES = COPYING
ELEMENTARY_INSTALL_STAGING = YES
ELEMENTARY_DEPENDENCIES = host-pkgconf host-efl host-elementary efl
ELEMENTARY_CONF_OPTS = \
--with-edje-cc=$(HOST_DIR)/usr/bin/edje_cc \
--with-eet-eet=$(HOST_DIR)/usr/bin/eet \
--with-eolian-gen=$(HOST_DIR)/usr/bin/eolian_gen \
--with-eldbus_codegen=$(HOST_DIR)/usr/bin/eldbus-codegen \
--with-elm-prefs-cc=$(HOST_DIR)/usr/bin/elm_prefs_cc \
--with-doxygen=no \
--disable-elementary-test
# We need a host package in order to provide elm_prefs_cc and
# elementary_codegen.
HOST_ELEMENTARY_DEPENDENCIES = host-pkgconf host-efl
HOST_ELEMENTARY_CONF_OPTS = \
--with-edje-cc=$(HOST_DIR)/usr/bin/edje_cc \
--with-eet-eet=$(HOST_DIR)/usr/bin/eet \
--with-eolian-gen=$(HOST_DIR)/usr/bin/eolian_gen \
--with-doxygen=no \
--disable-elementary-test
$(eval $(autotools-package))
$(eval $(host-autotools-package))

View File

@ -1,93 +0,0 @@
Allow the usage of an external implementation of the argp functions
uClibc lack the argp family of functions that glibc has. Therefore, we
add a check in the configure script to see if argp_parse is available
in the C library. If not, we look if it is available in the additional
'argp' library. If so, we link against that library. If not, we error
out.
This allows to build elfutils against uClibc with an external argp
library.
Based on the former patch by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
diff -rup a/configure.ac b/configure.ac
--- a/configure.ac 2015-01-06 11:30:02.170052875 +0000
+++ b/configure.ac 2015-01-06 11:31:10.122219826 +0000
@@ -253,6 +253,13 @@ AC_SUBST([LIBEBL_SUBDIR])
AC_DEFINE_UNQUOTED(LIBEBL_SUBDIR, "$LIBEBL_SUBDIR")
AH_TEMPLATE([LIBEBL_SUBDIR], [$libdir subdirectory containing libebl modules.])
+AC_CHECK_FUNC([argp_parse])
+if test "$ac_cv_func_argp_parse" != yes; then
+ AC_CHECK_LIB([argp],[argp_parse],ARGP_LIBS=-largp,
+ AC_MSG_ERROR([No argp_parse function available.]))
+fi
+AC_SUBST(ARGP_LIBS)
+
dnl Test for zlib and bzlib, gives ZLIB/BZLIB .am
dnl conditional and config.h USE_ZLIB/USE_BZLIB #define.
save_LIBS="$LIBS"
diff -rup a/libdw/Makefile.am b/libdw/Makefile.am
--- a/libdw/Makefile.am 2014-12-19 20:43:11.000000000 +0000
+++ b/libdw/Makefile.am 2015-01-06 11:32:21.075438524 +0000
@@ -112,7 +112,7 @@ libdw.so$(EXEEXT): $(srcdir)/libdw.map l
-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
- -ldl $(zip_LIBS)
+ -ldl $(zip_LIBS) $(ARGP_LIBS)
@$(textrel_check)
ln -fs $@ $@.$(VERSION)
diff -rup a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am 2015-01-06 11:30:02.430057339 +0000
+++ b/src/Makefile.am 2015-01-06 11:34:53.061049752 +0000
@@ -94,27 +94,29 @@ readelf_no_Werror = yes
strings_no_Werror = yes
addr2line_no_Wformat = yes
-readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl
+readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl $(ARGP_LIBS)
nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) -ldl \
- $(demanglelib)
-size_LDADD = $(libelf) $(libeu)
-strip_LDADD = $(libebl) $(libelf) $(libeu) -ldl
-ld_LDADD = $(libebl) $(libelf) $(libeu) -ldl
+ $(demanglelib) $(ARGP_LIBS)
+size_LDADD = $(libelf) $(libeu) $(ARGP_LIBS)
+strip_LDADD = $(libebl) $(libelf) $(libeu) -ldl $(ARGP_LIBS)
+ld_LDADD = $(libebl) $(libelf) $(libeu) -ldl $(ARGP_LIBS)
if NATIVE_LD
# -ldl is always needed for libebl.
ld_LDADD += libld_elf.a
endif
ld_LDFLAGS = -rdynamic
-elflint_LDADD = $(libebl) $(libelf) $(libeu) -ldl
-findtextrel_LDADD = $(libdw) $(libelf)
-addr2line_LDADD = $(libdw) $(libelf)
-elfcmp_LDADD = $(libebl) $(libelf) -ldl
-objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) -ldl
-ranlib_LDADD = libar.a $(libelf) $(libeu)
-strings_LDADD = $(libelf) $(libeu)
-ar_LDADD = libar.a $(libelf) $(libeu)
-unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) -ldl
-stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) -ldl $(demanglelib)
+elflint_LDADD = $(libebl) $(libelf) $(libeu) -ldl $(ARGP_LIBS)
+findtextrel_LDADD = $(libdw) $(libelf) $(ARGP_LIBS)
+addr2line_LDADD = $(libdw) $(libelf) $(ARGP_LIBS)
+elfcmp_LDADD = $(libebl) $(libelf) -ldl $(ARGP_LIBS)
+objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) -ldl \
+ $(ARGP_LIBS)
+ranlib_LDADD = libar.a $(libelf) $(libeu) $(ARGP_LIBS)
+strings_LDADD = $(libelf) $(libeu) $(ARGP_LIBS)
+ar_LDADD = libar.a $(libelf) $(libeu) $(ARGP_LIBS)
+unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) -ldl $(ARGP_LIBS)
+stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) -ldl \
+ $(demanglelib) $(ARGP_LIBS)
ldlex.o: ldscript.c
ldlex_no_Werror = yes

View File

@ -1,139 +0,0 @@
From bafacacaf7659a4933604662daba26a480b29a8d Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Thu, 23 Apr 2015 20:46:59 +0200
Subject: [PATCH] Allow disabling symbol versioning at configure time
Due to missing symbol versioning support in uClibc calls to versioned
functions that internally call different version of themselves results
in infinite recursion.
Introduce macro SYMBOL_VERSIONING and use it instead of plain SHARED to
decide whether symbol versioning is needed. Control this macro
definition with new configure option --disable-symbol-versioning.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
Backported from: bafacacaf7659a4933604662daba26a480b29a8d
Changes to ChangeLogs are dropped.
config/eu.am | 10 ++++++++--
configure.ac | 7 +++++++
lib/eu-config.h | 6 +++---
libdwfl/core-file.c | 2 +-
libdwfl/dwfl_module_build_id.c | 2 +-
libdwfl/dwfl_report_elf.c | 2 +-
diff --git a/config/eu.am b/config/eu.am
index faf8add..6103a3e 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -38,16 +38,22 @@ AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+DEFS.os = -DPIC -DSHARED
+if SYMBOL_VERSIONING
+DEFS.os += -DSYMBOL_VERSIONING
+else
+endif
+
%.os: %.c %.o
if AMDEP
- if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+ if $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) -MT $@ -MD -MP \
-MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
rm -f "$(DEPDIR)/$*.Tpo"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
else
- $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $<
+ $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) $<
endif
CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index ed2c964..be01573 100644
--- a/configure.ac
+++ b/configure.ac
@@ -241,6 +241,13 @@ AS_HELP_STRING([--disable-textrelcheck],
[Disable textrelcheck being a fatal error]))
AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"])
+AC_ARG_ENABLE([symbol-versioning],
+AS_HELP_STRING([--disable-symbol-versioning],
+ [Disable symbol versioning in shared objects]))
+AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
+AS_IF([test "x$enable_symbol_versioning" = "xno"],
+ [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.])])
+
dnl The directories with content.
dnl Documentation.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 3afff26..5bb21c1 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -163,7 +163,7 @@ asm (".section predict_data, \"aw\"; .previous\n"
#define ELFUTILS_HEADER(name) <lib##name.h>
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
# define OLD_VERSION(name, version) \
asm (".globl _compat." #version "." #name "\n" \
"_compat." #version "." #name " = " #name "\n" \
@@ -181,8 +181,8 @@ asm (".section predict_data, \"aw\"; .previous\n"
# define OLD_VERSION(name, version) /* Nothing for static linking. */
# define NEW_VERSION(name, version) /* Nothing for static linking. */
# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
- error "should use #ifdef SHARED"
-# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SHARED"
+ error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
#endif
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 324e9d2..bbe0899 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -588,7 +588,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
INTDEF (dwfl_core_file_report)
NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
without_executable)
diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c
index 350bbf8..c9a42ca 100644
--- a/libdwfl/dwfl_module_build_id.c
+++ b/libdwfl/dwfl_module_build_id.c
@@ -101,7 +101,7 @@ dwfl_module_build_id (Dwfl_Module *mod,
INTDEF (dwfl_module_build_id)
NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
int
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 3a4ae2e..624284c 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -321,7 +321,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
INTDEF (dwfl_report_elf)
NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
Dwfl_Module *
_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
const char *file_name, int fd,
--
1.8.1.4

View File

@ -1,57 +0,0 @@
From 33d34a10fdc01c5716aebdb93c34fdfd7557adc0 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Tue, 22 Dec 2015 17:39:35 +0100
Subject: [PATCH] Fix access to the dentry
Since Linux 2.6.20, the dentry pointer is no longer stored in
file->f_dentry, but in file->f_path.dentry. Until Linux 3.19, there
was a compatibility macro which made the change transparent, but this
macro has now been removed.
Since we probably don't care about compatibility with kernels older
than 2.6.20, this commit takes the simple approach of using
file->f_path.dentry. This will work with any kernel >= 2.6.20.
Submitted upstream at https://github.com/nicupavel/emlog/pull/3.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
emlog.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/emlog.c b/emlog.c
index 41a67e2..1ef3d80 100644
--- a/emlog.c
+++ b/emlog.c
@@ -292,8 +292,8 @@ static ssize_t emlog_read(struct file *file, char __user *buffer, /* The bu
struct emlog_info *einfo;
/* get the metadata about this emlog */
- if ((einfo = get_einfo(file->f_dentry->d_inode)) == NULL) {
- pr_err("can not fetch einfo for inode %ld.\n", (long)(file->f_dentry->d_inode->i_ino));
+ if ((einfo = get_einfo(file->f_path.dentry->d_inode)) == NULL) {
+ pr_err("can not fetch einfo for inode %ld.\n", (long)(file->f_path.dentry->d_inode->i_ino));
return -EIO;
}
@@ -368,7 +368,7 @@ static ssize_t emlog_write(struct file *file,
struct emlog_info *einfo;
/* get the metadata about this emlog */
- if ((einfo = get_einfo(file->f_dentry->d_inode)) == NULL)
+ if ((einfo = get_einfo(file->f_path.dentry->d_inode)) == NULL)
return -EIO;
/* if the message is longer than the buffer, just take the beginning
@@ -403,7 +403,7 @@ static unsigned int emlog_poll(struct file *file, struct poll_table_struct * wai
struct emlog_info *einfo;
/* get the metadata about this emlog */
- if ((einfo = get_einfo(file->f_dentry->d_inode)) == NULL)
+ if ((einfo = get_einfo(file->f_path.dentry->d_inode)) == NULL)
return -EIO;
poll_wait(file, EMLOG_READQ(einfo), wait);
--
2.6.4

View File

@ -1,757 +0,0 @@
From cdfcb1b5c95e93b00ae9e9d25708b4a3bee72c15 Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Mon, 2 May 2016 00:02:44 +0200
Subject: [PATCH] Address CVE-2016-0718 (/patch/ version 2.2.1)
* Out of bounds memory access when doing text conversion on malformed input
* Integer overflow related to memory allocation
Reported by Gustavo Grieco
Patch credits go to
* Christian Heimes
* Karl Waclawek
* Gustavo Grieco
* Sebastian Pipping
* Pascal Cuoq
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
---
lib/xmlparse.c | 34 +++++++++-----
lib/xmltok.c | 115 +++++++++++++++++++++++++++++++++++-------------
lib/xmltok.h | 10 ++++-
lib/xmltok_impl.c | 62 +++++++++++++-------------
4 files changed, 146 insertions(+), 75 deletions(-)
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
index e308c79..13e080d 100644
--- a/lib/xmlparse.c
+++ b/lib/xmlparse.c
@@ -2426,11 +2426,11 @@ doContent(XML_Parser parser,
for (;;) {
int bufSize;
int convLen;
- XmlConvert(enc,
+ const enum XML_Convert_Result convert_res = XmlConvert(enc,
&fromPtr, rawNameEnd,
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if (fromPtr == rawNameEnd) {
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
tag->name.strLen = convLen;
break;
}
@@ -2651,11 +2651,11 @@ doContent(XML_Parser parser,
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
*eventPP = s;
}
@@ -3261,11 +3261,11 @@ doCdataSection(XML_Parser parser,
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
*eventPP = s;
}
@@ -5342,6 +5342,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
const char *s, const char *end)
{
if (MUST_CONVERT(enc, s)) {
+ enum XML_Convert_Result convert_res;
const char **eventPP;
const char **eventEndPP;
if (enc == encoding) {
@@ -5354,11 +5355,11 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
}
do {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
*eventPP = s;
- } while (s != end);
+ } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
}
else
defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
@@ -6163,8 +6164,8 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc,
if (!pool->ptr && !poolGrow(pool))
return NULL;
for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if (ptr == end)
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
if (!poolGrow(pool))
return NULL;
@@ -6248,8 +6249,13 @@ poolGrow(STRING_POOL *pool)
}
}
if (pool->blocks && pool->start == pool->blocks->s) {
- int blockSize = (int)(pool->end - pool->start)*2;
- BLOCK *temp = (BLOCK *)
+ BLOCK *temp;
+ int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+
+ if (blockSize < 0)
+ return XML_FALSE;
+
+ temp = (BLOCK *)
pool->mem->realloc_fcn(pool->blocks,
(offsetof(BLOCK, s)
+ blockSize * sizeof(XML_Char)));
@@ -6264,6 +6270,10 @@ poolGrow(STRING_POOL *pool)
else {
BLOCK *tem;
int blockSize = (int)(pool->end - pool->start);
+
+ if (blockSize < 0)
+ return XML_FALSE;
+
if (blockSize < INIT_BLOCK_SIZE)
blockSize = INIT_BLOCK_SIZE;
else
diff --git a/expat/lib/xmltok.c b/expat/lib/xmltok.c
index bf09dfc..cb98ce1 100644
--- a/lib/xmltok.c
+++ b/lib/xmltok.c
@@ -318,39 +318,55 @@ enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
UTF8_cval4 = 0xf0
};
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
utf8_toUtf8(const ENCODING *enc,
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
char *to;
const char *from;
if (fromLim - *fromP > toLim - *toP) {
/* Avoid copying partial characters. */
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
break;
}
- for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+ for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
*to = *from;
*fromP = from;
*toP = to;
+
+ if ((to == toLim) && (from < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return res;
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
utf8_toUtf16(const ENCODING *enc,
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
unsigned short *to = *toP;
const char *from = *fromP;
- while (from != fromLim && to != toLim) {
+ while (from < fromLim && to < toLim) {
switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
case BT_LEAD2:
+ if (fromLim - from < 2) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ break;
+ }
*to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
from += 2;
break;
case BT_LEAD3:
+ if (fromLim - from < 3) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ break;
+ }
*to++ = (unsigned short)(((from[0] & 0xf) << 12)
| ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
from += 3;
@@ -358,8 +374,14 @@ utf8_toUtf16(const ENCODING *enc,
case BT_LEAD4:
{
unsigned long n;
- if (to + 1 == toLim)
+ if (toLim - to < 2) {
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
goto after;
+ }
+ if (fromLim - from < 4) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ goto after;
+ }
n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
| ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
n -= 0x10000;
@@ -377,6 +399,7 @@ utf8_toUtf16(const ENCODING *enc,
after:
*fromP = from;
*toP = to;
+ return res;
}
#ifdef XML_NS
@@ -425,7 +448,7 @@ static const struct normal_encoding internal_utf8_encoding = {
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
latin1_toUtf8(const ENCODING *enc,
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
@@ -433,30 +456,35 @@ latin1_toUtf8(const ENCODING *enc,
for (;;) {
unsigned char c;
if (*fromP == fromLim)
- break;
+ return XML_CONVERT_COMPLETED;
c = (unsigned char)**fromP;
if (c & 0x80) {
if (toLim - *toP < 2)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
*(*toP)++ = (char)((c >> 6) | UTF8_cval2);
*(*toP)++ = (char)((c & 0x3f) | 0x80);
(*fromP)++;
}
else {
if (*toP == toLim)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
*(*toP)++ = *(*fromP)++;
}
}
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
latin1_toUtf16(const ENCODING *enc,
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
- while (*fromP != fromLim && *toP != toLim)
+ while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = (unsigned char)*(*fromP)++;
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
#ifdef XML_NS
@@ -483,13 +511,18 @@ static const struct normal_encoding latin1_encoding = {
STANDARD_VTABLE(sb_)
};
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
ascii_toUtf8(const ENCODING *enc,
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
- while (*fromP != fromLim && *toP != toLim)
+ while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = *(*fromP)++;
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
#ifdef XML_NS
@@ -536,13 +569,14 @@ unicode_byte_type(char hi, char lo)
}
#define DEFINE_UTF16_TO_UTF8(E) \
-static void PTRCALL \
+static enum XML_Convert_Result PTRCALL \
E ## toUtf8(const ENCODING *enc, \
const char **fromP, const char *fromLim, \
char **toP, const char *toLim) \
{ \
- const char *from; \
- for (from = *fromP; from != fromLim; from += 2) { \
+ const char *from = *fromP; \
+ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \
+ for (; from < fromLim; from += 2) { \
int plane; \
unsigned char lo2; \
unsigned char lo = GET_LO(from); \
@@ -552,7 +586,7 @@ E ## toUtf8(const ENCODING *enc, \
if (lo < 0x80) { \
if (*toP == toLim) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
*(*toP)++ = lo; \
break; \
@@ -562,7 +596,7 @@ E ## toUtf8(const ENCODING *enc, \
case 0x4: case 0x5: case 0x6: case 0x7: \
if (toLim - *toP < 2) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
*(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
*(*toP)++ = ((lo & 0x3f) | 0x80); \
@@ -570,7 +604,7 @@ E ## toUtf8(const ENCODING *enc, \
default: \
if (toLim - *toP < 3) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
/* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
*(*toP)++ = ((hi >> 4) | UTF8_cval3); \
@@ -580,7 +614,11 @@ E ## toUtf8(const ENCODING *enc, \
case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
if (toLim - *toP < 4) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ if (fromLim - from < 4) { \
+ *fromP = from; \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
} \
plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
*(*toP)++ = ((plane >> 2) | UTF8_cval4); \
@@ -596,20 +634,32 @@ E ## toUtf8(const ENCODING *enc, \
} \
} \
*fromP = from; \
+ if (from < fromLim) \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
+ else \
+ return XML_CONVERT_COMPLETED; \
}
#define DEFINE_UTF16_TO_UTF16(E) \
-static void PTRCALL \
+static enum XML_Convert_Result PTRCALL \
E ## toUtf16(const ENCODING *enc, \
const char **fromP, const char *fromLim, \
unsigned short **toP, const unsigned short *toLim) \
{ \
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
+ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
/* Avoid copying first half only of surrogate */ \
if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
fromLim -= 2; \
- for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+ res = XML_CONVERT_INPUT_INCOMPLETE; \
+ } \
+ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
*(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+ if ((*toP == toLim) && (*fromP < fromLim)) \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ else \
+ return res; \
}
#define SET2(ptr, ch) \
@@ -1288,7 +1338,7 @@ unknown_isInvalid(const ENCODING *enc, const char *p)
return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
unknown_toUtf8(const ENCODING *enc,
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
@@ -1299,21 +1349,21 @@ unknown_toUtf8(const ENCODING *enc,
const char *utf8;
int n;
if (*fromP == fromLim)
- break;
+ return XML_CONVERT_COMPLETED;
utf8 = uenc->utf8[(unsigned char)**fromP];
n = *utf8++;
if (n == 0) {
int c = uenc->convert(uenc->userData, *fromP);
n = XmlUtf8Encode(c, buf);
if (n > toLim - *toP)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
utf8 = buf;
*fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- (BT_LEAD2 - 2));
}
else {
if (n > toLim - *toP)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
(*fromP)++;
}
do {
@@ -1322,13 +1372,13 @@ unknown_toUtf8(const ENCODING *enc,
}
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
unknown_toUtf16(const ENCODING *enc,
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- while (*fromP != fromLim && *toP != toLim) {
+ while (*fromP < fromLim && *toP < toLim) {
unsigned short c = uenc->utf16[(unsigned char)**fromP];
if (c == 0) {
c = (unsigned short)
@@ -1340,6 +1390,11 @@ unknown_toUtf16(const ENCODING *enc,
(*fromP)++;
*(*toP)++ = c;
}
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
ENCODING *
@@ -1503,7 +1558,7 @@ initScan(const ENCODING * const *encodingTable,
{
const ENCODING **encPtr;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
encPtr = enc->encPtr;
if (ptr + 1 == end) {
diff --git a/expat/lib/xmltok.h b/expat/lib/xmltok.h
index ca867aa..752007e 100644
--- a/lib/xmltok.h
+++ b/lib/xmltok.h
@@ -130,6 +130,12 @@ typedef int (PTRCALL *SCANNER)(const ENCODING *,
const char *,
const char **);
+enum XML_Convert_Result {
+ XML_CONVERT_COMPLETED = 0,
+ XML_CONVERT_INPUT_INCOMPLETE = 1,
+ XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
+};
+
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
@@ -158,12 +164,12 @@ struct encoding {
const char *ptr,
const char *end,
const char **badPtr);
- void (PTRCALL *utf8Convert)(const ENCODING *enc,
+ enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
char **toP,
const char *toLim);
- void (PTRCALL *utf16Convert)(const ENCODING *enc,
+ enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
diff --git a/expat/lib/xmltok_impl.c b/expat/lib/xmltok_impl.c
index 9c2895b..6c5a3ba 100644
--- a/lib/xmltok_impl.c
+++ b/lib/xmltok_impl.c
@@ -93,13 +93,13 @@ static int PTRCALL
PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (ptr < end) {
if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_MINUS:
@@ -147,7 +147,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_PERCNT:
if (ptr + MINBPC(enc) == end)
@@ -233,7 +233,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
@@ -242,7 +242,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_QUEST:
@@ -305,7 +305,7 @@ static int PTRCALL
PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
@@ -348,7 +348,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
ptr += MINBPC(enc);
break;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
@@ -391,11 +391,11 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_CR: case BT_LF:
break;
@@ -432,7 +432,7 @@ static int PTRCALL
PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
@@ -441,7 +441,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
@@ -464,7 +464,7 @@ static int PTRCALL
PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (ptr < end) {
if (CHAR_MATCHES(enc, ptr, ASCII_x))
return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
switch (BYTE_TYPE(enc, ptr)) {
@@ -474,7 +474,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
break;
@@ -506,7 +506,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
@@ -529,7 +529,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
#ifdef XML_NS
int hadColon = 0;
#endif
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
@@ -716,7 +716,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
hadColon = 0;
#endif
/* we have a start-tag */
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
@@ -740,7 +740,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
case BT_S: case BT_CR: case BT_LF:
{
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_GT:
@@ -785,7 +785,7 @@ static int PTRCALL
PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
@@ -832,7 +832,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
ptr += MINBPC(enc);
break;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
@@ -895,7 +895,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
@@ -921,7 +921,7 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_CR: case BT_LF: case BT_S:
@@ -941,7 +941,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
const char *ptr, const char *end,
const char **nextTokPtr)
{
- while (ptr != end) {
+ while (ptr < end) {
int t = BYTE_TYPE(enc, ptr);
switch (t) {
INVALID_CASES(ptr, nextTokPtr)
@@ -973,7 +973,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
int tok;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
@@ -1141,7 +1141,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_GT: case BT_RPAR: case BT_COMMA:
@@ -1204,10 +1204,10 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
const char *start;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
start = ptr;
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
@@ -1262,10 +1262,10 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
const char *start;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
start = ptr;
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
@@ -1326,7 +1326,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
end = ptr + n;
}
}
- while (ptr != end) {
+ while (ptr < end) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_LT:
@@ -1373,7 +1373,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
{
ptr += MINBPC(enc);
end -= MINBPC(enc);
- for (; ptr != end; ptr += MINBPC(enc)) {
+ for (; ptr < end; ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
@@ -1760,7 +1760,7 @@ PREFIX(updatePosition)(const ENCODING *enc,
case BT_CR:
pos->lineNumber++;
ptr += MINBPC(enc);
- if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+ if (ptr < end && BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
pos->columnNumber = (XML_Size)-1;
break;
--
2.8.2

View File

@ -1,46 +0,0 @@
From 265d97d02e8ef373653c76a339869985eb3ba27a Mon Sep 17 00:00:00 2001
From: Gustavo Zacarias <gustavo@zacarias.com.ar>
Date: Tue, 10 Mar 2015 15:10:35 -0300
Subject: [PATCH] configure: add check for fallocate
We need to check for fallocate() rather than just linux/falloc.h +
FALLOC_FL_PUNCH_HOLE since in uClibc we've got both but still not
fallocate() itself since it's only implemented in newer unreleased
versions.
Status: sent upstream.
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
---
configure.ac | 1 +
mkfs/f2fs_format_utils.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index ae451b8..900b84a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_GETMNTENT
AC_CHECK_FUNCS_ONCE([
+ fallocate
getmntent
memset
])
diff --git a/mkfs/f2fs_format_utils.c b/mkfs/f2fs_format_utils.c
index a0f85f5..ddeafeb 100644
--- a/mkfs/f2fs_format_utils.c
+++ b/mkfs/f2fs_format_utils.c
@@ -46,7 +46,7 @@ int f2fs_trim_device()
#if defined(WITH_BLKDISCARD) && defined(BLKDISCARD)
MSG(0, "Info: Discarding device\n");
if (S_ISREG(stat_buf.st_mode)) {
-#ifdef FALLOC_FL_PUNCH_HOLE
+#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
if (fallocate(config.fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
range[0], range[1]) < 0) {
MSG(0, "Info: fallocate(PUNCH_HOLE|KEEP_SIZE) is failed\n");
--
2.0.5

View File

@ -1,63 +0,0 @@
From 74f1c9b43b191a9d6b494e90a4a11677fca33c13 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Sun, 11 Sep 2011 19:04:51 +0200
Subject: [PATCH 01/13] Support raw dvdsub palette as stored on normal dvd's
This is how the palette is stored on dvd's. Currently
only xbmc passes the palette information to libavcodec
this way.
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavcodec/dvdsubdec.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 39604f3..a711e16 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -64,6 +64,24 @@ static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *
}
}
+static void ayvu_to_argb(const uint8_t *ayvu, uint32_t *argb, int num_values)
+{
+ uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ uint8_t r, g, b;
+ int i, y, cb, cr, a;
+ int r_add, g_add, b_add;
+
+ for (i = num_values; i > 0; i--) {
+ a = *ayvu++;
+ y = *ayvu++;
+ cr = *ayvu++;
+ cb = *ayvu++;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
+ *argb++ = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+}
+
static int decode_run_2bit(GetBitContext *gb, int *color)
{
unsigned int v, t;
@@ -697,6 +715,12 @@ static av_cold int dvdsub_init(AVCodecContext *avctx)
parse_ifo_palette(ctx, ctx->ifo_str);
if (ctx->palette_str)
parse_palette(ctx, ctx->palette_str);
+
+ if (!ctx->has_palette && avctx->extradata_size == 64) {
+ ayvu_to_argb((uint8_t*)avctx->extradata, ctx->palette, 16);
+ ctx->has_palette = 1;
+ }
+
if (ctx->has_palette) {
int i;
av_log(avctx, AV_LOG_DEBUG, "palette:");
--
2.1.0

View File

@ -1,32 +0,0 @@
From 54200b3e6009c6870e33c02c8bbcf023fcd92cac Mon Sep 17 00:00:00 2001
From: Cory Fields <theuni-nospam-@xbmc.org>
Date: Mon, 28 Jun 2010 01:55:31 -0400
Subject: [PATCH 03/13] if av_read_packet returns AVERROR_IO, we are done.
ffmpeg's codecs might or might not handle returning any completed demuxed
packets correctly
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/utils.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libavformat/utils.c b/libavformat/utils.c
index ae6347a..3e8af50 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1304,6 +1304,8 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
if (ret < 0) {
if (ret == AVERROR(EAGAIN))
return ret;
+ if (ret == AVERROR(EIO))
+ return ret;
/* flush the parsers */
for (i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
--
2.1.0

View File

@ -1,47 +0,0 @@
From e9236f6fe3fae1ad4a3a2b6b63db493b083f0b21 Mon Sep 17 00:00:00 2001
From: Cory Fields <theuni-nospam-@xbmc.org>
Date: Mon, 28 Jun 2010 02:10:50 -0400
Subject: [PATCH 04/13] added: Ticket #7187, TV Teletext support for DVB EBU
Teletext streams
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavcodec/avcodec.h | 4 ++++
libavformat/mpegts.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index dabae1b..dd6ef3f 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -520,6 +520,10 @@ enum AVCodecID {
AV_CODEC_ID_PJS = MKBETAG('P','h','J','S'),
AV_CODEC_ID_ASS = MKBETAG('A','S','S',' '), ///< ASS as defined in Matroska
+ /* data codecs */
+ AV_CODEC_ID_VBI_DATA= 0x17500,
+ AV_CODEC_ID_VBI_TELETEXT,
+
/* other specific kind of codecs (generally used for attachments) */
AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
AV_CODEC_ID_TTF = 0x18000,
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 97da0a3..5dd28f1 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -729,6 +729,8 @@ static const StreamType DESC_types[] = {
{ 0x7b, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
{ 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT },
{ 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */
+ { 0x45, AVMEDIA_TYPE_DATA, AV_CODEC_ID_VBI_DATA }, /* VBI Data descriptor */
+ { 0x46, AVMEDIA_TYPE_DATA, AV_CODEC_ID_VBI_TELETEXT }, /* VBI Teletext descriptor */
{ 0 },
};
--
2.1.0

View File

@ -1,46 +0,0 @@
From 1f48ee2290e9041b0371eb9a9cb742e9568930a1 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Sun, 18 Sep 2011 19:16:34 +0200
Subject: [PATCH 05/13] Don't accept mpegts PMT that isn't current
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/mpegts.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 5dd28f1..9f85aed 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -572,6 +572,7 @@ typedef struct SectionHeader {
uint8_t tid;
uint16_t id;
uint8_t version;
+ uint8_t current;
uint8_t sec_num;
uint8_t last_sec_num;
} SectionHeader;
@@ -643,6 +644,7 @@ static int parse_section_header(SectionHeader *h,
val = get8(pp, p_end);
if (val < 0)
return val;
+ h->current = val & 0x1;
h->version = (val >> 1) & 0x1f;
val = get8(pp, p_end);
if (val < 0)
@@ -1968,6 +1970,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
return;
if (ts->skip_changes)
return;
+ if (!h->current)
+ return;
ts->stream->ts_id = h->id;
--
2.1.0

View File

@ -1,48 +0,0 @@
From db98fbe37f2f7175ff03b8d582e940518ddf3642 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Sun, 18 Sep 2011 19:17:23 +0200
Subject: [PATCH 06/13] Don't reparse PMT unless it's version has changed
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/mpegts.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 9f85aed..25007a6 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -88,6 +88,7 @@ struct MpegTSFilter {
int es_id;
int last_cc; /* last cc code (-1 if first packet) */
int64_t last_pcr;
+ int last_version; /* last version of data on this pid */
enum MpegTSFilterType type;
union {
MpegTSPESFilter pes_filter;
@@ -450,6 +451,7 @@ static MpegTSFilter *mpegts_open_filter(MpegTSContext *ts, unsigned int pid,
filter->es_id = -1;
filter->last_cc = -1;
filter->last_pcr= -1;
+ filter->last_version = -1;
return filter;
}
@@ -1972,6 +1974,10 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
return;
if (!h->current)
return;
+ if (h->version == filter->last_version)
+ return;
+ filter->last_version = h->version;
+ av_dlog(ts->stream, "version=%d\n", filter->last_version);
ts->stream->ts_id = h->id;
--
2.1.0

View File

@ -1,105 +0,0 @@
From fdd8caea6535434a877587f5325e914ba50ed17f Mon Sep 17 00:00:00 2001
From: Cory Fields <theuni-nospam-@xbmc.org>
Date: Fri, 9 Jul 2010 16:43:31 -0400
Subject: [PATCH 07/13] Read PID timestamps as well as PCR timestamps to find
location in mpegts stream
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/mpegts.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 25007a6..d5a8a45 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2459,6 +2459,44 @@ static void seek_back(AVFormatContext *s, AVIOContext *pb, int64_t pos) {
av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
}
+static int parse_timestamp(int64_t *ts, const uint8_t *buf)
+{
+ int afc, flags;
+ const uint8_t *p;
+
+ if(!(buf[1] & 0x40)) /* must be a start packet */
+ return -1;
+
+ afc = (buf[3] >> 4) & 3;
+ p = buf + 4;
+ if (afc == 0 || afc == 2) /* invalid or only adaption field */
+ return -1;
+ if (afc == 3)
+ p += p[0] + 1;
+ if (p >= buf + TS_PACKET_SIZE)
+ return -1;
+
+ if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01) /* packet_start_code_prefix */
+ return -1;
+
+ flags = p[3] | 0x100; /* stream type */
+ if (!((flags >= 0x1c0 && flags <= 0x1df) ||
+ (flags >= 0x1e0 && flags <= 0x1ef) ||
+ (flags == 0x1bd) || (flags == 0x1fd)))
+ return -1;
+
+ flags = p[7];
+ if ((flags & 0xc0) == 0x80) {
+ *ts = ff_parse_pes_pts(p+9);
+ return 0;
+ } else if ((flags & 0xc0) == 0xc0) {
+ *ts = ff_parse_pes_pts(p+9+5);
+ return 0;
+ }
+ return -1;
+}
+
+
static int mpegts_read_header(AVFormatContext *s)
{
MpegTSContext *ts = s->priv_data;
@@ -2658,6 +2696,7 @@ static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
uint8_t buf[TS_PACKET_SIZE];
int pcr_l, pcr_pid =
((PESContext *)s->streams[stream_index]->priv_data)->pcr_pid;
+ int pid = ((PESContext*)s->streams[stream_index]->priv_data)->pid;
int pos47 = ts->pos47_full % ts->raw_packet_size;
pos =
((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) *
@@ -2679,6 +2718,11 @@ static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
*ppos = pos;
return timestamp;
}
+ if ((pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pid) &&
+ parse_timestamp(&timestamp, buf) == 0) {
+ *ppos = pos;
+ return timestamp;
+ }
pos += ts->raw_packet_size;
}
@@ -2778,7 +2822,7 @@ AVInputFormat ff_mpegts_demuxer = {
.read_header = mpegts_read_header,
.read_packet = mpegts_read_packet,
.read_close = mpegts_read_close,
- .read_timestamp = mpegts_get_dts,
+ .read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
.priv_class = &mpegts_class,
};
@@ -2790,7 +2834,7 @@ AVInputFormat ff_mpegtsraw_demuxer = {
.read_header = mpegts_read_header,
.read_packet = mpegts_raw_read_packet,
.read_close = mpegts_read_close,
- .read_timestamp = mpegts_get_dts,
+ .read_timestamp = mpegts_get_pcr,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
.priv_class = &mpegtsraw_class,
};
--
2.1.0

View File

@ -1,74 +0,0 @@
From c57e5b8154f5fe1457f4c64e04885a2cdfb37f51 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Sat, 22 Oct 2011 19:01:38 +0200
Subject: [PATCH 08/13] Get stream durations using read_timestamp
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/utils.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3e8af50..f4fb172 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2356,6 +2356,41 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic)
#define DURATION_MAX_READ_SIZE 250000LL
#define DURATION_MAX_RETRY 4
+static void av_estimate_timings_from_pts2(AVFormatContext *ic, int64_t old_offset)
+{
+ AVStream *st;
+ int i, step= 1024;
+ int64_t ts, pos;
+
+ for(i=0;i<ic->nb_streams;i++) {
+ st = ic->streams[i];
+
+ pos = 0;
+ ts = ic->iformat->read_timestamp(ic, i, &pos, DURATION_MAX_READ_SIZE);
+ if (ts == AV_NOPTS_VALUE)
+ continue;
+ if (st->start_time > ts || st->start_time == AV_NOPTS_VALUE)
+ st->start_time = ts;
+
+ pos = avio_size(ic->pb) - 1;
+ do {
+ pos -= step;
+ ts = ic->iformat->read_timestamp(ic, i, &pos, pos + step);
+ step += step;
+ } while (ts == AV_NOPTS_VALUE && pos >= step && step < DURATION_MAX_READ_SIZE);
+
+ if (ts == AV_NOPTS_VALUE)
+ continue;
+
+ if (st->duration < ts - st->start_time || st->duration == AV_NOPTS_VALUE)
+ st->duration = ts - st->start_time;
+ }
+
+ fill_all_stream_timings(ic);
+
+ avio_seek(ic->pb, old_offset, SEEK_SET);
+}
+
/* only usable for MPEG-PS streams */
static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
{
@@ -2506,6 +2541,10 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
* the components */
fill_all_stream_timings(ic);
ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM;
+ } else if (ic->iformat->read_timestamp &&
+ file_size && ic->pb->seekable) {
+ /* get accurate estimate from the PTSes */
+ av_estimate_timings_from_pts2(ic, old_offset);
} else {
/* less precise: use bitrate info */
estimate_timings_from_bit_rate(ic);
--
2.1.0

View File

@ -1,33 +0,0 @@
From 4bcec3ef0042244b0ade00d132368d0872f73c72 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Wed, 8 Dec 2010 14:03:43 +0000
Subject: [PATCH 09/13] changed: allow 4 second skew between streams in mov
before attempting to seek
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/mov.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 8d66c0a..127ffd9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4028,8 +4028,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) ||
(s->pb->seekable &&
((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
- ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
- (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
+ ((FFABS(best_dts - dts) <= 4*AV_TIME_BASE && current_sample->pos < sample->pos) ||
+ (FFABS(best_dts - dts) > 4*AV_TIME_BASE && dts < best_dts)))))) {
sample = current_sample;
best_dts = dts;
*st = avst;
--
2.1.0

View File

@ -1,44 +0,0 @@
From cb7c19124165508ae5f38a385a14f9c13b096a27 Mon Sep 17 00:00:00 2001
From: Joakim Plate <elupus@ecce.se>
Date: Fri, 26 Nov 2010 20:56:48 +0000
Subject: [PATCH 10/13] fixed: memleak in mpegts demuxer on some malformed (??)
mpegts files with too large pes packets
at-visions sample file brokenStream.mpg
Patch part of the XBMC patch set for ffmpeg, downloaded from
https://github.com/xbmc/FFmpeg/.
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
libavformat/mpegts.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index d5a8a45..e070f1f 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -832,6 +832,10 @@ static void reset_pes_packet_state(PESContext *pes)
static void new_pes_packet(PESContext *pes, AVPacket *pkt)
{
+ if(pkt->data) {
+ av_log(pes->stream, AV_LOG_ERROR, "ignoring previously allocated packet on stream %d\n", pkt->stream_index);
+ av_free_packet(pkt);
+ }
av_init_packet(pkt);
pkt->buf = pes->buffer;
@@ -2649,6 +2653,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->size = -1;
ts->pkt = pkt;
+ ts->pkt->data = NULL;
+
ret = handle_packets(ts, 0);
if (ret < 0) {
av_free_packet(ts->pkt);
--
2.1.0

Some files were not shown because too many files have changed in this diff Show More