From 8df14d78dc753a5286bb6461a14d8baa1e13e3cd Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 2 May 2014 08:27:16 -0700 Subject: [PATCH] Use sigsetjmp/siglongjmp in opcodes sigsetjmp/siglongjmp without saving the signal mask is faster than setjmp/longjmp on systems where the signal mask is saved. This patch uses sigsetjmp/siglongjmp without saving the signal mask if possible. PR binutils/16886 * config.in: Regenerated. * configure: Likewise. * configure.in: Check if sigsetjmp is available. * h8500-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn_h8500): Replace setjmp with OPCODES_SIGSETJMP. * i386-dis.c (dis_private): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn): Replace setjmp with OPCODES_SIGSETJMP. * ns32k-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn_ns32k): Replace setjmp with OPCODES_SIGSETJMP. * sysdep.h (OPCODES_SIGJMP_BUF): New macro. (OPCODES_SIGSETJMP): Likewise. (OPCODES_SIGLONGJMP): Likewise. * vax-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn_vax): Replace setjmp with OPCODES_SIGSETJMP. * xtensa-dis.c (dis_private): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn_xtensa): Replace setjmp with OPCODES_SIGSETJMP. * z8k-dis.c(instr_data_s): Replace jmp_buf with OPCODES_SIGJMP_BUF. (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. (print_insn_z8k): Replace setjmp with OPCODES_SIGSETJMP. --- opcodes/ChangeLog | 29 +++++++++++++++++++++++++++++ opcodes/config.in | 3 +++ opcodes/configure | 35 +++++++++++++++++++++++++++++++++++ opcodes/configure.in | 11 +++++++++++ opcodes/h8500-dis.c | 6 +++--- opcodes/i386-dis.c | 6 +++--- opcodes/ns32k-dis.c | 6 +++--- opcodes/sysdep.h | 14 ++++++++++++++ opcodes/vax-dis.c | 6 +++--- opcodes/xtensa-dis.c | 6 +++--- opcodes/z8k-dis.c | 6 +++--- 11 files changed, 110 insertions(+), 18 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 747aa238b64..2e4affeb471 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,32 @@ +2014-05-02 H.J. Lu + + PR binutils/16886 + * config.in: Regenerated. + * configure: Likewise. + * configure.in: Check if sigsetjmp is available. + * h8500-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn_h8500): Replace setjmp with OPCODES_SIGSETJMP. + * i386-dis.c (dis_private): Replace jmp_buf with OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn): Replace setjmp with OPCODES_SIGSETJMP. + * ns32k-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn_ns32k): Replace setjmp with OPCODES_SIGSETJMP. + * sysdep.h (OPCODES_SIGJMP_BUF): New macro. + (OPCODES_SIGSETJMP): Likewise. + (OPCODES_SIGLONGJMP): Likewise. + * vax-dis.c (private): Replace jmp_buf with OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn_vax): Replace setjmp with OPCODES_SIGSETJMP. + * xtensa-dis.c (dis_private): Replace jmp_buf with + OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn_xtensa): Replace setjmp with OPCODES_SIGSETJMP. + * z8k-dis.c(instr_data_s): Replace jmp_buf with OPCODES_SIGJMP_BUF. + (fetch_data): Replace longjmp with OPCODES_SIGLONGJMP. + (print_insn_z8k): Replace setjmp with OPCODES_SIGSETJMP. + 2014-05-01 H.J. Lu PR binutils/16891 diff --git a/opcodes/config.in b/opcodes/config.in index 9555f7db7cf..ee1ddbbcbc4 100644 --- a/opcodes/config.in +++ b/opcodes/config.in @@ -31,6 +31,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define if sigsetjmp is available. */ +#undef HAVE_SIGSETJMP + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H diff --git a/opcodes/configure b/opcodes/configure index afe0cd13964..9379bbfcb88 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -12207,6 +12207,41 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't do +# since sigsetjmp might only be defined as a macro. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5 +$as_echo_n "checking for sigsetjmp... " >&6; } +if test "${gdb_cv_func_sigsetjmp+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ +sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + bfd_cv_func_sigsetjmp=yes +else + bfd_cv_func_sigsetjmp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_sigsetjmp" >&5 +$as_echo "$gdb_cv_func_sigsetjmp" >&6; } +if test $bfd_cv_func_sigsetjmp = yes; then + +$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h + +fi + cgen_maint=no cgendir='$(srcdir)/../cgen' diff --git a/opcodes/configure.in b/opcodes/configure.in index 00f9892e8a9..3ffcaa0ecd8 100644 --- a/opcodes/configure.in +++ b/opcodes/configure.in @@ -98,6 +98,17 @@ ACX_HEADER_STRING AC_CHECK_DECLS([basename, stpcpy]) +# Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't do +# since sigsetjmp might only be defined as a macro. +AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp, +[AC_TRY_COMPILE([ +#include +], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);], +bfd_cv_func_sigsetjmp=yes, bfd_cv_func_sigsetjmp=no)]) +if test $bfd_cv_func_sigsetjmp = yes; then + AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ]) +fi + cgen_maint=no cgendir='$(srcdir)/../cgen' diff --git a/opcodes/h8500-dis.c b/opcodes/h8500-dis.c index c94091c1c82..caa3020f17f 100644 --- a/opcodes/h8500-dis.c +++ b/opcodes/h8500-dis.c @@ -39,7 +39,7 @@ struct private bfd_byte *max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; }; /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) @@ -63,7 +63,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) if (status != 0) { (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); } else priv->max_fetched = addr; @@ -84,7 +84,7 @@ print_insn_h8500 (bfd_vma addr, disassemble_info *info) info->private_data = (PTR) & priv; priv.max_fetched = priv.the_buffer; priv.insn_start = addr; - if (setjmp (priv.bailout) != 0) + if (OPCODES_SIGSETJMP (priv.bailout) != 0) /* Error return. */ return -1; diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index c36c6323198..99bb4828333 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -131,7 +131,7 @@ struct dis_private { bfd_byte the_buffer[MAX_MNEM_SIZE]; bfd_vma insn_start; int orig_sizeflag; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; }; enum address_mode @@ -214,7 +214,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) STATUS. */ if (priv->max_fetched == priv->the_buffer) (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); } else priv->max_fetched = addr; @@ -12500,7 +12500,7 @@ print_insn (bfd_vma pc, disassemble_info *info) start_codep = priv.the_buffer; codep = priv.the_buffer; - if (setjmp (priv.bailout) != 0) + if (OPCODES_SIGSETJMP (priv.bailout) != 0) { const char *name; diff --git a/opcodes/ns32k-dis.c b/opcodes/ns32k-dis.c index b29eccc90a0..c6a42df4517 100644 --- a/opcodes/ns32k-dis.c +++ b/opcodes/ns32k-dis.c @@ -57,7 +57,7 @@ struct private bfd_byte *max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; }; @@ -82,7 +82,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) if (status != 0) { (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); } else priv->max_fetched = addr; @@ -745,7 +745,7 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info) info->private_data = & priv; priv.max_fetched = priv.the_buffer; priv.insn_start = memaddr; - if (setjmp (priv.bailout) != 0) + if (OPCODES_SIGSETJMP (priv.bailout) != 0) /* Error return. */ return -1; diff --git a/opcodes/sysdep.h b/opcodes/sysdep.h index cdd0fc08798..84811f169a6 100644 --- a/opcodes/sysdep.h +++ b/opcodes/sysdep.h @@ -55,3 +55,17 @@ #if !HAVE_DECL_STPCPY extern char *stpcpy (char *__dest, const char *__src); #endif + +/* Use sigsetjmp/siglongjmp without saving the signal mask if possible. + It is faster than setjmp/longjmp on systems where the signal mask is + saved. */ + +#if defined(HAVE_SIGSETJMP) +#define OPCODES_SIGJMP_BUF sigjmp_buf +#define OPCODES_SIGSETJMP(buf) sigsetjmp((buf), 0) +#define OPCODES_SIGLONGJMP(buf,val) siglongjmp((buf), (val)) +#else +#define OPCODES_SIGJMP_BUF jmp_buf +#define OPCODES_SIGSETJMP(buf) setjmp(buf) +#define OPCODES_SIGLONGJMP(buf,val) longjmp((buf), (val)) +#endif diff --git a/opcodes/vax-dis.c b/opcodes/vax-dis.c index 0b986877659..5f9f1e96e55 100644 --- a/opcodes/vax-dis.c +++ b/opcodes/vax-dis.c @@ -75,7 +75,7 @@ struct private bfd_byte * max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; }; /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) @@ -99,7 +99,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) if (status != 0) { (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); } else priv->max_fetched = addr; @@ -395,7 +395,7 @@ print_insn_vax (bfd_vma memaddr, disassemble_info *info) parsed_disassembler_options = TRUE; } - if (setjmp (priv.bailout) != 0) + if (OPCODES_SIGSETJMP (priv.bailout) != 0) /* Error return. */ return -1; diff --git a/opcodes/xtensa-dis.c b/opcodes/xtensa-dis.c index 705c1ca8189..338b810b5a8 100644 --- a/opcodes/xtensa-dis.c +++ b/opcodes/xtensa-dis.c @@ -42,7 +42,7 @@ int show_raw_fields; struct dis_private { bfd_byte *byte_buf; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; }; @@ -66,7 +66,7 @@ fetch_data (struct disassemble_info *info, bfd_vma memaddr) return length; } (*info->memory_error_func) (status, memaddr, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); /*NOTREACHED*/ } @@ -175,7 +175,7 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info) priv.byte_buf = byte_buf; info->private_data = (void *) &priv; - if (setjmp (priv.bailout) != 0) + if (OPCODES_SIGSETJMP (priv.bailout) != 0) /* Error return. */ return -1; diff --git a/opcodes/z8k-dis.c b/opcodes/z8k-dis.c index cc54fb5a629..ea7fd3bad16 100644 --- a/opcodes/z8k-dis.c +++ b/opcodes/z8k-dis.c @@ -37,7 +37,7 @@ typedef struct /* Nibble number of first word not yet fetched. */ int max_fetched; bfd_vma insn_start; - jmp_buf bailout; + OPCODES_SIGJMP_BUF bailout; int tabl_index; char instr_asmsrc[80]; @@ -76,7 +76,7 @@ fetch_data (struct disassemble_info *info, int nibble) if (status != 0) { (*info->memory_error_func) (status, priv->insn_start, info); - longjmp (priv->bailout, 1); + OPCODES_SIGLONGJMP (priv->bailout, 1); } { @@ -149,7 +149,7 @@ print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented) info->private_data = (PTR) &instr_data; instr_data.max_fetched = 0; instr_data.insn_start = addr; - if (setjmp (instr_data.bailout) != 0) + if (OPCODES_SIGSETJMP (instr_data.bailout) != 0) /* Error return. */ return -1; -- 2.30.2