diff options
Diffstat (limited to 'meta/recipes-devtools')
171 files changed, 18583 insertions, 1075 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.27.inc b/meta/recipes-devtools/binutils/binutils-2.27.inc index 0936d974d4..1311b65847 100644 --- a/meta/recipes-devtools/binutils/binutils-2.27.inc +++ b/meta/recipes-devtools/binutils/binutils-2.27.inc @@ -45,6 +45,64 @@ SRC_URI = "\ file://CVE-2017-6969_2.patch \ file://CVE-2017-7209.patch \ file://CVE-2017-7210.patch \ + file://CVE-2017-7614.patch \ + file://CVE-2017-9038.patch \ + file://CVE-2017-9039.patch \ + file://CVE-2017-9039_1.patch \ + file://CVE-2017-9040_and_9042.patch \ + file://CVE-2017-9041_1.patch \ + file://CVE-2017-9041_2.patch \ + file://CVE-2017-7226.patch \ + file://CVE-2017-12448.patch \ + file://CVE-2017-12449_12455_12457_1.patch \ + file://CVE-2017-12449_12455_12457.patch \ + file://CVE-2017-12451.patch \ + file://CVE-2017-12450_12452_12453_12454_12456_1.patch \ + file://CVE-2017-12450_12452_12453_12454_12456.patch \ + file://CVE-2017-7223.patch \ + file://CVE-2017-7224.patch \ + file://CVE-2017-7225.patch \ + file://CVE-2017-7227.patch \ + file://CVE-2017-7301.patch \ + file://CVE-2017-7302.patch \ + file://CVE-2017-7303.patch \ + file://CVE-2017-7304.patch \ + file://CVE-2017-8393.patch \ + file://CVE-2017-8395.patch \ + file://CVE-2017-8397.patch \ + file://CVE-2017-7300.patch \ + file://CVE-2017-8396.patch \ + file://CVE-2017-8421.patch \ + file://CVE-2017-8394_1.patch \ + file://CVE-2017-8394.patch \ + file://CVE-2017-8398.patch \ + file://CVE-2017-7299_1.patch \ + file://CVE-2017-7299_2.patch \ + file://CVE-2017-9751.patch \ + file://CVE-2017-9749.patch \ + file://CVE-2017-9746.patch \ + file://CVE-2017-9748.patch \ + file://CVE-2017-9747.patch \ + file://CVE-2017-9750.patch \ + file://CVE-2017-9752.patch \ + file://CVE-2017-9753_9754.patch \ + file://CVE-2017-9755_1.patch \ + file://CVE-2017-9755_2.patch \ + file://CVE-2017-9756.patch \ + file://CVE-2017-9745.patch \ + file://CVE-2017-9954.patch \ + file://CVE-2017-9955_1.patch \ + file://CVE-2017-9955_2.patch \ + file://CVE-2017-9955_3.patch \ + file://CVE-2017-9955_4.patch \ + file://CVE-2017-9955_5.patch \ + file://CVE-2017-9955_6.patch \ + file://CVE-2017-9955_7.patch \ + file://CVE-2017-9955_8.patch \ + file://CVE-2017-9955_9.patch \ + file://CVE-2017-14729.patch \ + file://CVE-2017-15024.patch \ + file://CVE-2017-15938.patch \ " S = "${WORKDIR}/git" diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12448.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12448.patch new file mode 100644 index 0000000000..039166cfb9 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12448.patch @@ -0,0 +1,49 @@ +commit 909e4e716c4d77e33357bbe9bc902bfaf2e1af24 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jul 19 14:49:12 2017 +0100 + + Fix use-after-free error when parsing a corrupt nested archive. + + PR 21787 + * archive.c (bfd_generic_archive_p): If the bfd does not have the + correct magic bytes at the start, set the error to wrong format + and clear the format selector before returning NULL. + +Upstream-Status: Backport + +CVE: CVE-2017-12448 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/archive.c +=================================================================== +--- git.orig/bfd/archive.c 2017-08-30 16:44:10.848601412 +0530 ++++ git/bfd/archive.c 2017-08-30 16:44:21.400855758 +0530 +@@ -834,7 +834,12 @@ + if (strncmp (armag, ARMAG, SARMAG) != 0 + && strncmp (armag, ARMAGB, SARMAG) != 0 + && ! bfd_is_thin_archive (abfd)) +- return NULL; ++ { ++ bfd_set_error (bfd_error_wrong_format); ++ if (abfd->format == bfd_archive) ++ abfd->format = bfd_unknown; ++ return NULL; ++ } + + tdata_hold = bfd_ardata (abfd); + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-30 16:44:21.340854320 +0530 ++++ git/bfd/ChangeLog 2017-08-30 16:46:48.716143277 +0530 +@@ -1,3 +1,10 @@ ++2017-07-19 Nick Clifton <nickc@redhat.com> ++ ++ PR 21787 ++ * archive.c (bfd_generic_archive_p): If the bfd does not have the ++ correct magic bytes at the start, set the error to wrong format ++ and clear the format selector before returning NULL. ++ + 2017-04-25 Maciej W. Rozycki <macro@imgtec.com> + + * readelf.c (process_mips_specific): Remove error reporting from diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch new file mode 100644 index 0000000000..d7512b3829 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457.patch @@ -0,0 +1,240 @@ +commit 8bdf0be19d2777565a8b1c88347f65d6a4b8c5fc +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jul 27 12:04:50 2017 +0100 + + Fix address violation issues encountered when parsing corrupt binaries. + + PR 21840 + * mach-o.c (bfd_mach_o_read_symtab_strtab): Fail if the symtab + size is -1. + * nlmcode.h (nlm_swap_auxiliary_headers_in): Replace assertion + with error return. + * section.c (bfd_make_section_with_flags): Fail if the name or bfd + are NULL. + * vms-alpha.c (bfd_make_section_with_flags): Correct computation + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + +Upstream-Status: Backport + +CVE: CVE-2017-12449_12455_12457 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/mach-o.c +=================================================================== +--- git.orig/bfd/mach-o.c 2017-08-30 17:21:59.684671218 +0530 ++++ git/bfd/mach-o.c 2017-08-30 17:22:19.136813620 +0530 +@@ -3739,6 +3739,9 @@ + } + else + { ++ /* See PR 21840 for a reproducer. */ ++ if ((sym->strsize + 1) == 0) ++ return FALSE; + sym->strtab = bfd_alloc (abfd, sym->strsize + 1); + if (sym->strtab == NULL) + return FALSE; +Index: git/bfd/nlmcode.h +=================================================================== +--- git.orig/bfd/nlmcode.h 2017-08-30 17:21:59.688671247 +0530 ++++ git/bfd/nlmcode.h 2017-08-30 17:22:19.140813649 +0530 +@@ -351,7 +351,9 @@ + bfd_byte *contents; + bfd_byte *p, *pend; + +- BFD_ASSERT (hdrLength == 0 && hdr == NULL); ++ /* See PR 21840 for a reproducer. */ ++ if (hdrLength != 0 || hdr != NULL) ++ return FALSE; + + pos = bfd_tell (abfd); + if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0) +Index: git/bfd/section.c +=================================================================== +--- git.orig/bfd/section.c 2017-08-30 17:21:59.708671392 +0530 ++++ git/bfd/section.c 2017-08-30 17:22:19.140813649 +0530 +@@ -1240,7 +1240,7 @@ + struct section_hash_entry *sh; + asection *newsect; + +- if (abfd->output_has_begun) ++ if (abfd == NULL || name == NULL || abfd->output_has_begun) + { + bfd_set_error (bfd_error_invalid_operation); + return NULL; +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-30 17:22:19.080813209 +0530 ++++ git/bfd/vms-alpha.c 2017-08-30 17:22:19.140813649 +0530 +@@ -5562,8 +5562,9 @@ + { + struct vms_emh_common *emh = (struct vms_emh_common *)rec; + unsigned int subtype; ++ int extra; + +- subtype = (unsigned)bfd_getl16 (emh->subtyp); ++ subtype = (unsigned) bfd_getl16 (emh->subtyp); + + fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); + +@@ -5573,58 +5574,82 @@ + fprintf (file, _(" Error: The length is less than the length of an EMH record\n")); + return; + } +- ++ extra = rec_len - sizeof (struct vms_emh_common); ++ + switch (subtype) + { + case EMH__C_MHD: + { +- struct vms_emh_mhd *mhd = (struct vms_emh_mhd *)rec; +- const char *name; ++ struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec; ++ const char * name; ++ const char * nextname; ++ const char * maxname; + ++ /* PR 21840: Check for invalid lengths. */ ++ if (rec_len < sizeof (* mhd)) ++ { ++ fprintf (file, _(" Error: The record length is less than the size of an EMH_MHD record\n")); ++ return; ++ } + fprintf (file, _("Module header\n")); + fprintf (file, _(" structure level: %u\n"), mhd->strlvl); + fprintf (file, _(" max record size: %u\n"), +- (unsigned)bfd_getl32 (mhd->recsiz)); ++ (unsigned) bfd_getl32 (mhd->recsiz)); + name = (char *)(mhd + 1); ++ maxname = (char *) rec + rec_len; ++ if (name > maxname - 2) ++ { ++ fprintf (file, _(" Error: The module name is missing\n")); ++ return; ++ } ++ nextname = name + name[0] + 1; ++ if (nextname >= maxname) ++ { ++ fprintf (file, _(" Error: The module name is too long\n")); ++ return; ++ } + fprintf (file, _(" module name : %.*s\n"), name[0], name + 1); +- name += name[0] + 1; ++ name = nextname; ++ if (name > maxname - 2) ++ { ++ fprintf (file, _(" Error: The module version is missing\n")); ++ return; ++ } ++ nextname = name + name[0] + 1; ++ if (nextname >= maxname) ++ { ++ fprintf (file, _(" Error: The module version is too long\n")); ++ return; ++ } + fprintf (file, _(" module version : %.*s\n"), name[0], name + 1); +- name += name[0] + 1; +- fprintf (file, _(" compile date : %.17s\n"), name); ++ name = nextname; ++ if ((maxname - name) < 17 && maxname[-1] != 0) ++ fprintf (file, _(" Error: The compile date is truncated\n")); ++ else ++ fprintf (file, _(" compile date : %.17s\n"), name); + } + break; ++ + case EMH__C_LNM: +- { +- fprintf (file, _("Language Processor Name\n")); +- fprintf (file, _(" language name: %.*s\n"), +- (int)(rec_len - sizeof (struct vms_emh_common)), +- (char *)rec + sizeof (struct vms_emh_common)); +- } ++ fprintf (file, _("Language Processor Name\n")); ++ fprintf (file, _(" language name: %.*s\n"), extra, (char *)(emh + 1)); + break; ++ + case EMH__C_SRC: +- { +- fprintf (file, _("Source Files Header\n")); +- fprintf (file, _(" file: %.*s\n"), +- (int)(rec_len - sizeof (struct vms_emh_common)), +- (char *)rec + sizeof (struct vms_emh_common)); +- } ++ fprintf (file, _("Source Files Header\n")); ++ fprintf (file, _(" file: %.*s\n"), extra, (char *)(emh + 1)); + break; ++ + case EMH__C_TTL: +- { +- fprintf (file, _("Title Text Header\n")); +- fprintf (file, _(" title: %.*s\n"), +- (int)(rec_len - sizeof (struct vms_emh_common)), +- (char *)rec + sizeof (struct vms_emh_common)); +- } ++ fprintf (file, _("Title Text Header\n")); ++ fprintf (file, _(" title: %.*s\n"), extra, (char *)(emh + 1)); + break; ++ + case EMH__C_CPR: +- { +- fprintf (file, _("Copyright Header\n")); +- fprintf (file, _(" copyright: %.*s\n"), +- (int)(rec_len - sizeof (struct vms_emh_common)), +- (char *)rec + sizeof (struct vms_emh_common)); +- } ++ fprintf (file, _("Copyright Header\n")); ++ fprintf (file, _(" copyright: %.*s\n"), extra, (char *)(emh + 1)); + break; ++ + default: + fprintf (file, _("unhandled emh subtype %u\n"), subtype); + break; +Index: git/bfd/vms-misc.c +=================================================================== +--- git.orig/bfd/vms-misc.c 2017-08-30 17:21:59.716671451 +0530 ++++ git/bfd/vms-misc.c 2017-08-30 17:22:19.140813649 +0530 +@@ -135,8 +135,8 @@ + #endif + + +-/* Copy sized string (string with fixed size) to new allocated area +- size is string size (size of record) */ ++/* Copy sized string (string with fixed size) to new allocated area. ++ Size is string size (size of record). */ + + char * + _bfd_vms_save_sized_string (unsigned char *str, int size) +@@ -151,8 +151,8 @@ + return newstr; + } + +-/* Copy counted string (string with size at first byte) to new allocated area +- ptr points to size byte on entry */ ++/* Copy counted string (string with size at first byte) to new allocated area. ++ PTR points to size byte on entry. */ + + char * + _bfd_vms_save_counted_string (unsigned char *ptr) +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-30 17:22:19.080813209 +0530 ++++ git/bfd/ChangeLog 2017-08-30 17:23:51.069502425 +0530 +@@ -1,3 +1,16 @@ ++2017-07-27 Nick Clifton <nickc@redhat.com> ++ ++ PR 21840 ++ * mach-o.c (bfd_mach_o_read_symtab_strtab): Fail if the symtab ++ size is -1. ++ * nlmcode.h (nlm_swap_auxiliary_headers_in): Replace assertion ++ with error return. ++ * section.c (bfd_make_section_with_flags): Fail if the name or bfd ++ are NULL. ++ * vms-alpha.c (bfd_make_section_with_flags): Correct computation ++ of end pointer. ++ (evax_bfd_print_emh): Check for invalid string lengths. ++ + 2017-07-19 Nick Clifton <nickc@redhat.com> + + PR 21787 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch new file mode 100644 index 0000000000..6dae0f6c24 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12449_12455_12457_1.patch @@ -0,0 +1,97 @@ +commit bc21b167eb0106eb31d946a0eb5acfb7e4d5d8a1 +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Jun 19 14:52:36 2017 +0100 + + Fix address violations when reading corrupt VMS records. + + PR binutils/21618 + * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record + length. + (evax_bfd_print_eeom): Likewise. + (evax_bfd_print_egsd): Check for an overlarge record length. + (evax_bfd_print_etir): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-12449_12455_12457 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-30 17:08:27.408159234 +0530 ++++ git/bfd/vms-alpha.c 2017-08-30 17:12:07.289044702 +0530 +@@ -5567,6 +5567,13 @@ + + fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len); + ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* emh)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EMH record\n")); ++ return; ++ } ++ + switch (subtype) + { + case EMH__C_MHD: +@@ -5630,6 +5637,14 @@ + struct vms_eeom *eeom = (struct vms_eeom *)rec; + + fprintf (file, _(" EEOM (len=%u):\n"), rec_len); ++ ++ /* PR 21618: Check for invalid lengths. */ ++ if (rec_len < sizeof (* eeom)) ++ { ++ fprintf (file, _(" Error: The length is less than the length of an EEOM record\n")); ++ return; ++ } ++ + fprintf (file, _(" number of cond linkage pairs: %u\n"), + (unsigned)bfd_getl32 (eeom->total_lps)); + fprintf (file, _(" completion code: %u\n"), +@@ -5718,6 +5733,12 @@ + n, type, len); + n++; + ++ if (off + len > rec_len || off + len < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ + switch (type) + { + case EGSD__C_PSC: +@@ -5958,6 +5979,12 @@ + size = bfd_getl16 (etir->size); + buf = rec + off + sizeof (struct vms_etir); + ++ if (off + size > rec_len || off + size < off) ++ { ++ fprintf (file, _(" Error: length larger than remaining space in record\n")); ++ return; ++ } ++ + fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4); + switch (type) + { +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-30 17:08:43.612213596 +0530 ++++ git/bfd/ChangeLog 2017-08-30 17:13:27.217438742 +0530 +@@ -5,6 +5,15 @@ + correct magic bytes at the start, set the error to wrong format + and clear the format selector before returning NULL. + ++ 2017-06-19 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21618 ++ * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record ++ length. ++ (evax_bfd_print_eeom): Likewise. ++ (evax_bfd_print_egsd): Check for an overlarge record length. ++ (evax_bfd_print_etir): Likewise. ++ + 2017-04-25 Maciej W. Rozycki <macro@imgtec.com> + + * readelf.c (process_mips_specific): Remove error reporting from diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch new file mode 100644 index 0000000000..503f655b61 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456.patch @@ -0,0 +1,375 @@ +commit ca4cf9b9c622a5695e01f7f5815a7382a31fcf51 +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Jul 24 13:49:22 2017 +0100 + + Fix address violation errors parsing corrupt binary files. + + PR 21813 + binutils* rddbg.c (read_symbol_stabs_debugging_info): Check for an empty + string whilst concatenating symbol names. + + bfd * mach-o.c (bfd_mach_o_canonicalize_relocs): Pass the base address + of the relocs to the canonicalize_one_reloc routine. + * mach-o.h (struct bfd_mach_o_backend_data): Update the prototype + for the _bfd_mach_o_canonicalize_one_reloc field. + * mach-o-arm.c (bfd_mach_o_arm_canonicalize_one_reloc): Add + res_base parameter. Use to check for corrupt pair relocs. + * mach-o-aarch64.c (bfd_mach_o_arm64_canonicalize_one_reloc): + Likewise. + * mach-o-i386.c (bfd_mach_o_i386_canonicalize_one_reloc): + Likewise. + * mach-o-x86-64.c (bfd_mach_o_x86_64_canonicalize_one_reloc): + Likewise. + + * vms-alpha.c (_bfd_vms_slurp_eihd): Make sure that there is + enough data in the record before attempting to parse it. + (_bfd_vms_slurp_eeom): Likewise. + + (_bfd_vms_slurp_egsd): Check for an invalid section index. + (image_set_ptr): Likewise. + (alpha_vms_slurp_relocs): Likewise. + + (alpha_vms_object_p): Check for a truncated record. + +Upstream-Status: Backport + +CVE: CVE-2017-12450, CVE-2017-12452, CVE-2017-12453, CVE-2017-12454, CVE-2017-12456 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/mach-o-aarch64.c +=================================================================== +--- git.orig/bfd/mach-o-aarch64.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-aarch64.c 2017-08-31 19:18:02.620442777 +0530 +@@ -147,9 +147,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_arm64_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_arm64_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base ATTRIBUTE_UNUSED) + { + bfd_mach_o_reloc_info reloc; + +Index: git/bfd/mach-o-i386.c +=================================================================== +--- git.orig/bfd/mach-o-i386.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-i386.c 2017-08-31 19:18:02.620442777 +0530 +@@ -112,9 +112,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_i386_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_i386_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base) + { + bfd_mach_o_reloc_info reloc; + +@@ -126,6 +128,9 @@ + switch (reloc.r_type) + { + case BFD_MACH_O_GENERIC_RELOC_PAIR: ++ /* PR 21813: Check for a corrupt PAIR reloc at the start. */ ++ if (res == res_base) ++ return FALSE; + if (reloc.r_length == 2) + { + res->howto = &i386_howto_table[7]; +@@ -391,9 +396,9 @@ + { NULL, NULL } + }; + +-#define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_i386_canonicalize_one_reloc +-#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out +-#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread ++#define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_i386_canonicalize_one_reloc ++#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out ++#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread + + #define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat + #define bfd_mach_o_section_type_valid_for_tgt NULL +Index: git/bfd/mach-o-x86-64.c +=================================================================== +--- git.orig/bfd/mach-o-x86-64.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-x86-64.c 2017-08-31 19:18:02.620442777 +0530 +@@ -120,9 +120,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_x86_64_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_x86_64_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base ATTRIBUTE_UNUSED) + { + bfd_mach_o_reloc_info reloc; + +Index: git/bfd/mach-o.c +=================================================================== +--- git.orig/bfd/mach-o.c 2017-08-31 19:18:02.440441869 +0530 ++++ git/bfd/mach-o.c 2017-08-31 19:18:02.620442777 +0530 +@@ -1496,7 +1496,7 @@ + for (i = 0; i < count; i++) + { + if (!(*bed->_bfd_mach_o_canonicalize_one_reloc)(abfd, &native_relocs[i], +- &res[i], syms)) ++ &res[i], syms, res)) + goto err; + } + free (native_relocs); +Index: git/bfd/mach-o.h +=================================================================== +--- git.orig/bfd/mach-o.h 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o.h 2017-08-31 19:18:02.620442777 +0530 +@@ -746,7 +746,7 @@ + enum bfd_architecture arch; + bfd_vma page_size; + bfd_boolean (*_bfd_mach_o_canonicalize_one_reloc) +- (bfd *, struct mach_o_reloc_info_external *, arelent *, asymbol **); ++ (bfd *, struct mach_o_reloc_info_external *, arelent *, asymbol **, arelent *); + bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *); + bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *, + void *, char *); +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-31 19:18:02.564442494 +0530 ++++ git/bfd/ChangeLog 2017-08-31 19:18:02.620442777 +0530 +@@ -11,6 +11,30 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++ 2017-07-24 Nick Clifton <nickc@redhat.com> ++ ++ PR 21813 ++ * mach-o.c (bfd_mach_o_canonicalize_relocs): Pass the base address ++ of the relocs to the canonicalize_one_reloc routine. ++ * mach-o.h (struct bfd_mach_o_backend_data): Update the prototype ++ for the _bfd_mach_o_canonicalize_one_reloc field. ++ * mach-o-arm.c (bfd_mach_o_arm_canonicalize_one_reloc): Add ++ res_base parameter. Use to check for corrupt pair relocs. ++ * mach-o-aarch64.c (bfd_mach_o_arm64_canonicalize_one_reloc): ++ Likewise. ++ * mach-o-i386.c (bfd_mach_o_i386_canonicalize_one_reloc): ++ Likewise. ++ * mach-o-x86-64.c (bfd_mach_o_x86_64_canonicalize_one_reloc): ++ Likewise. ++ ++ * vms-alpha.c (_bfd_vms_slurp_eihd): Make sure that there is ++ enough data in the record before attempting to parse it. ++ (_bfd_vms_slurp_eeom): Likewise. ++ ++ (_bfd_vms_slurp_egsd): Check for an invalid section index. ++ (image_set_ptr): Likewise. ++ (alpha_vms_slurp_relocs): Likewise. ++ + 2017-07-19 Nick Clifton <nickc@redhat.com> + + PR 21786 +Index: git/bfd/mach-o-arm.c +=================================================================== +--- git.orig/bfd/mach-o-arm.c 2017-08-31 19:17:51.264385450 +0530 ++++ git/bfd/mach-o-arm.c 2017-08-31 19:18:02.620442777 +0530 +@@ -30,7 +30,7 @@ + #define bfd_mach_o_mkobject bfd_mach_o_arm_mkobject + + #define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_arm_canonicalize_one_reloc +-#define bfd_mach_o_swap_reloc_out NULL ++#define bfd_mach_o_swap_reloc_out NULL + #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_arm_bfd_reloc_type_lookup + #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_arm_bfd_reloc_name_lookup + +@@ -147,9 +147,11 @@ + }; + + static bfd_boolean +-bfd_mach_o_arm_canonicalize_one_reloc (bfd *abfd, +- struct mach_o_reloc_info_external *raw, +- arelent *res, asymbol **syms) ++bfd_mach_o_arm_canonicalize_one_reloc (bfd * abfd, ++ struct mach_o_reloc_info_external * raw, ++ arelent * res, ++ asymbol ** syms, ++ arelent * res_base) + { + bfd_mach_o_reloc_info reloc; + +@@ -161,6 +163,9 @@ + switch (reloc.r_type) + { + case BFD_MACH_O_ARM_RELOC_PAIR: ++ /* PR 21813: Check for a corrupt PAIR reloc at the start. */ ++ if (res == res_base) ++ return FALSE; + if (reloc.r_length == 2) + { + res->howto = &arm_howto_table[7]; +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-31 19:18:02.556442454 +0530 ++++ git/bfd/vms-alpha.c 2017-08-31 19:20:56.233322607 +0530 +@@ -473,6 +473,14 @@ + + vms_debug2 ((8, "_bfd_vms_slurp_eihd\n")); + ++ /* PR 21813: Check for an undersized record. */ ++ if (PRIV (recrd.buf_size) < sizeof (* eihd)) ++ { ++ _bfd_error_handler (_("Corrupt EIHD record - size is too small")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ + size = bfd_getl32 (eihd->size); + imgtype = bfd_getl32 (eihd->imgtype); + +@@ -1255,19 +1263,39 @@ + if (old_flags & EGSY__V_DEF) + { + struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; ++ long psindx; + + entry->value = bfd_getl64 (esdf->value); + if (PRIV (sections) == NULL) + return FALSE; +- entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)]; ++ ++ psindx = bfd_getl32 (esdf->psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->section = PRIV (sections)[psindx]; + + if (old_flags & EGSY__V_NORM) + { + PRIV (norm_sym_count)++; + + entry->code_value = bfd_getl64 (esdf->code_address); +- entry->code_section = +- PRIV (sections)[bfd_getl32 (esdf->ca_psindx)]; ++ psindx = bfd_getl32 (esdf->ca_psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->code_section = PRIV (sections)[psindx]; ++ + } + } + } +@@ -1294,9 +1322,20 @@ + + if (old_flags & EGSY__V_REL) + { ++ long psindx; ++ + if (PRIV (sections) == NULL) + return FALSE; +- entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; ++ psindx = bfd_getl32 (egst->psindx); ++ /* PR 21813: Check for an out of range index. */ ++ if (psindx < 0 || psindx >= (int) PRIV (section_count)) ++ { ++ _bfd_error_handler (_("Corrupt EGSD record: its psindx field is too big (%#lx)"), ++ psindx); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ entry->section = PRIV (sections)[psindx]; + } + else + entry->section = bfd_abs_section_ptr; +@@ -1387,6 +1426,10 @@ + + if (PRIV (sections) == NULL) + return; ++ ++ if (sect < 0 || sect >= (int) PRIV (section_count)) ++ return; ++ + sec = PRIV (sections)[sect]; + + if (info) +@@ -2360,6 +2403,14 @@ + + vms_debug2 ((2, "EEOM\n")); + ++ /* PR 21813: Check for an undersized record. */ ++ if (PRIV (recrd.buf_size) < sizeof (* eeom)) ++ { ++ _bfd_error_handler (_("Corrupt EEOM record - size is too small")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ + PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps); + PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod); + if (PRIV (eom_data).eom_w_comcod > 1) +@@ -2540,6 +2591,10 @@ + PRIV (recrd.buf_size) = PRIV (recrd.rec_size); + } + ++ /* PR 21813: Check for a truncated record. */ ++ if (PRIV (recrd.rec_size < test_len)) ++ goto error_ret; ++ + /* Read the remaining record. */ + remaining = PRIV (recrd.rec_size) - test_len; + to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining); +@@ -5074,7 +5129,7 @@ + } + else if (cur_psidx >= 0) + { +- if (PRIV (sections) == NULL) ++ if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count)) + return FALSE; + reloc->sym_ptr_ptr = + PRIV (sections)[cur_psidx]->symbol_ptr_ptr; +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-08-31 19:18:01.816438718 +0530 ++++ git/binutils/ChangeLog 2017-08-31 19:18:02.624442798 +0530 +@@ -1,3 +1,9 @@ ++2017-07-24 Nick Clifton <nickc@redhat.com> ++ ++ PR 21813 ++ * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty ++ string whilst concatenating symbol names. ++ + 2017-02-14 Nick Clifton <nickc@redhat.com> + + PR binutils/21157 +Index: git/binutils/rddbg.c +=================================================================== +--- git.orig/binutils/rddbg.c 2017-08-31 19:17:51.596387126 +0530 ++++ git/binutils/rddbg.c 2017-08-31 19:18:02.624442798 +0530 +@@ -300,7 +300,8 @@ + + s = i.name; + f = NULL; +- while (s[strlen (s) - 1] == '\\' ++ while (strlen (s) > 0 ++ && s[strlen (s) - 1] == '\\' + && ps + 1 < symend) + { + char *sc, *n; diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch new file mode 100644 index 0000000000..208bbbafae --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12450_12452_12453_12454_12456_1.patch @@ -0,0 +1,113 @@ +commit cb06d03ad92ffcfaa09c3f065837cb39e9e1486d +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jun 21 11:13:49 2017 +0100 + + Fix address violation parsing a corrupt IEEE Alpha binary. + + PR binutils/21637 + * vms-alpha.c (_bfd_vms_slurp_egsd): Check for an empty section + list. + (image_set_ptr): Likewise. + (alpha_vms_fix_sec_rel): Likewise. + (alpha_vms_slurp_relocs): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-12450, CVE-2017-12452, CVE-2017-12453, CVE-2017-12454, CVE-2017-12456 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-08-31 18:01:00.742098130 +0530 ++++ git/bfd/vms-alpha.c 2017-08-31 18:01:06.000000000 +0530 +@@ -1257,6 +1257,8 @@ + struct vms_esdf *esdf = (struct vms_esdf *)vms_rec; + + entry->value = bfd_getl64 (esdf->value); ++ if (PRIV (sections) == NULL) ++ return FALSE; + entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)]; + + if (old_flags & EGSY__V_NORM) +@@ -1291,7 +1293,11 @@ + entry->symbol_vector = bfd_getl32 (egst->value); + + if (old_flags & EGSY__V_REL) +- entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; ++ { ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)]; ++ } + else + entry->section = bfd_abs_section_ptr; + +@@ -1379,6 +1385,8 @@ + + vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect)); + ++ if (PRIV (sections) == NULL) ++ return; + sec = PRIV (sections)[sect]; + + if (info) +@@ -1691,7 +1699,12 @@ + alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info, + unsigned int rel, bfd_vma vma) + { +- asection *sec = PRIV (sections)[rel & RELC_MASK]; ++ asection *sec; ++ ++ if (PRIV (sections) == NULL) ++ return 0; ++ ++ sec = PRIV (sections)[rel & RELC_MASK]; + + if (info) + { +@@ -5000,6 +5013,8 @@ + return FALSE; + } + ++ if (PRIV (sections) == NULL) ++ return FALSE; + sec = PRIV (sections)[cur_psect]; + if (sec == bfd_abs_section_ptr) + { +@@ -5058,8 +5073,12 @@ + reloc->sym_ptr_ptr = sym; + } + else if (cur_psidx >= 0) +- reloc->sym_ptr_ptr = +- PRIV (sections)[cur_psidx]->symbol_ptr_ptr; ++ { ++ if (PRIV (sections) == NULL) ++ return FALSE; ++ reloc->sym_ptr_ptr = ++ PRIV (sections)[cur_psidx]->symbol_ptr_ptr; ++ } + else + reloc->sym_ptr_ptr = NULL; + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-31 18:01:06.000000000 +0530 ++++ git/bfd/ChangeLog 2017-08-31 18:01:49.114384620 +0530 +@@ -31,7 +31,16 @@ + correct magic bytes at the start, set the error to wrong format + and clear the format selector before returning NULL. + +- 2017-06-19 Nick Clifton <nickc@redhat.com> ++ 2017-06-21 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21637 ++ * vms-alpha.c (_bfd_vms_slurp_egsd): Check for an empty section ++ list. ++ (image_set_ptr): Likewise. ++ (alpha_vms_fix_sec_rel): Likewise. ++ (alpha_vms_slurp_relocs): Likewise. ++ ++2017-06-19 Nick Clifton <nickc@redhat.com> + + PR binutils/21618 + * vms-alpha.c (evax_bfd_print_emh): Check for insufficient record diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch new file mode 100644 index 0000000000..23ddfcf1bc --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch @@ -0,0 +1,384 @@ +commit 29866fa186ee3ebda5242221607dba360b2e541e +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jul 19 11:07:43 2017 +0100 + + Fix address violation when attempting to read a corrupt field in a COFF archive header structure. + + PR 21786 + * coff-rs6000.c (_bfd_strntol): New function. + (_bfd_strntoll): New function. + (GET_VALUE_IN_FIELD): New macro. + (EQ_VALUE_IN_FIELD): new macro. + (_bfd_xcoff_slurp_armap): Use new macros. + (_bfd_xcoff_archive_p): Likewise. + (_bfd_xcoff_read_ar_hdr): Likewise. + (_bfd_xcoff_openr_next_archived_file): Likewise. + (_bfd_xcoff_stat_arch_elt): Likewise. + +commit 6c4e7b6bfbc4679f695106de2817ecf02b27c8be +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jul 19 16:14:02 2017 +0100 + + Extend previous fix to coff-rs6000.c to coff64-rs6000.c + + PR 21786 + * coff64-rs6000.c (_bfd_strntol): New function. + (_bfd_strntoll): New function. + (GET_VALUE_IN_FIELD): New macro. + (xcoff64_slurp_armap): Use new macros. + +Upstream-Status: backport + +CVE: CVE-2017-12451 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-31 16:07:20.966269193 +0530 ++++ git/bfd/ChangeLog 2017-08-31 16:25:04.423155789 +0530 +@@ -13,6 +13,19 @@ + + 2017-07-19 Nick Clifton <nickc@redhat.com> + ++ PR 21786 ++ * coff-rs6000.c (_bfd_strntol): New function. ++ (_bfd_strntoll): New function. ++ (GET_VALUE_IN_FIELD): New macro. ++ (EQ_VALUE_IN_FIELD): new macro. ++ (_bfd_xcoff_slurp_armap): Use new macros. ++ (_bfd_xcoff_archive_p): Likewise. ++ (_bfd_xcoff_read_ar_hdr): Likewise. ++ (_bfd_xcoff_openr_next_archived_file): Likewise. ++ (_bfd_xcoff_stat_arch_elt): Likewise. ++ ++2017-07-19 Nick Clifton <nickc@redhat.com> ++ + PR 21787 + * archive.c (bfd_generic_archive_p): If the bfd does not have the + correct magic bytes at the start, set the error to wrong format +Index: git/bfd/coff-rs6000.c +=================================================================== +--- git.orig/bfd/coff-rs6000.c 2017-08-31 16:07:14.278208353 +0530 ++++ git/bfd/coff-rs6000.c 2017-08-31 16:24:05.414696722 +0530 +@@ -203,7 +203,8 @@ + }; + + /* Information about one member of an archive. */ +-struct member_layout { ++struct member_layout ++{ + /* The archive member that this structure describes. */ + bfd *member; + +@@ -237,7 +238,8 @@ + }; + + /* A structure used for iterating over the members of an archive. */ +-struct archive_iterator { ++struct archive_iterator ++{ + /* The archive itself. */ + bfd *archive; + +@@ -654,8 +656,6 @@ + end: + return bfd_coff_auxesz (abfd); + } +- +- + + /* The XCOFF reloc table. Actually, XCOFF relocations specify the + bitsize and whether they are signed or not, along with a +@@ -663,7 +663,6 @@ + different algorithms for putting in the reloc. Many of these + relocs need special_function entries, which I have not written. */ + +- + reloc_howto_type xcoff_howto_table[] = + { + /* 0x00: Standard 32 bit relocation. */ +@@ -1185,6 +1184,51 @@ + /* bfd_xcoff_archive_set_magic (abfd, magic); */ + } + ++/* PR 21786: The PE/COFF standard does not require NUL termination for any of ++ the ASCII fields in the archive headers. So in order to be able to extract ++ numerical values we provide our own versions of strtol and strtoll which ++ take a maximum length as an additional parameter. Also - just to save space, ++ we omit the endptr return parameter, since we know that it is never used. */ ++ ++static long ++_bfd_strntol (const char * nptr, int base, unsigned int maxlen) ++{ ++ char buf[24]; /* Should be enough. */ ++ ++ BFD_ASSERT (maxlen < (sizeof (buf) - 1)); ++ ++ memcpy (buf, nptr, maxlen); ++ buf[maxlen] = 0; ++ return strtol (buf, NULL, base); ++} ++ ++static long long ++_bfd_strntoll (const char * nptr, int base, unsigned int maxlen) ++{ ++ char buf[32]; /* Should be enough. */ ++ ++ BFD_ASSERT (maxlen < (sizeof (buf) - 1)); ++ ++ memcpy (buf, nptr, maxlen); ++ buf[maxlen] = 0; ++ return strtoll (buf, NULL, base); ++} ++ ++/* Macro to read an ASCII value stored in an archive header field. */ ++#define GET_VALUE_IN_FIELD(VAR, FIELD) \ ++ do \ ++ { \ ++ (VAR) = sizeof (VAR) > sizeof (long) \ ++ ? _bfd_strntoll (FIELD, 10, sizeof FIELD) \ ++ : _bfd_strntol (FIELD, 10, sizeof FIELD); \ ++ } \ ++ while (0) ++ ++#define EQ_VALUE_IN_FIELD(VAR, FIELD) \ ++ (sizeof (VAR) > sizeof (long) \ ++ ? (VAR) ==_bfd_strntoll (FIELD, 10, sizeof FIELD) \ ++ : (VAR) == _bfd_strntol (FIELD, 10, sizeof FIELD)) ++ + /* Read in the armap of an XCOFF archive. */ + + bfd_boolean +@@ -1209,7 +1253,7 @@ + /* This is for the old format. */ + struct xcoff_ar_hdr hdr; + +- off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (off, xcoff_ardata (abfd)->symoff); + if (off == 0) + { + bfd_has_map (abfd) = FALSE; +@@ -1225,12 +1269,12 @@ + return FALSE; + + /* Skip the name (normally empty). */ +- namlen = strtol (hdr.namlen, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (namlen, hdr.namlen); + off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG; + if (bfd_seek (abfd, off, SEEK_CUR) != 0) + return FALSE; + +- sz = strtol (hdr.size, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (sz, hdr.size); + + /* Read in the entire symbol table. */ + contents = (bfd_byte *) bfd_alloc (abfd, sz); +@@ -1264,7 +1308,7 @@ + /* This is for the new format. */ + struct xcoff_ar_hdr_big hdr; + +- off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (off, xcoff_ardata_big (abfd)->symoff); + if (off == 0) + { + bfd_has_map (abfd) = FALSE; +@@ -1280,15 +1324,12 @@ + return FALSE; + + /* Skip the name (normally empty). */ +- namlen = strtol (hdr.namlen, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (namlen, hdr.namlen); + off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG; + if (bfd_seek (abfd, off, SEEK_CUR) != 0) + return FALSE; + +- /* XXX This actually has to be a call to strtoll (at least on 32-bit +- machines) since the field width is 20 and there numbers with more +- than 32 bits can be represented. */ +- sz = strtol (hdr.size, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (sz, hdr.size); + + /* Read in the entire symbol table. */ + contents = (bfd_byte *) bfd_alloc (abfd, sz); +@@ -1393,8 +1434,8 @@ + goto error_ret; + } + +- bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, +- (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (bfd_ardata (abfd)->first_file_filepos, ++ hdr.firstmemoff); + + amt = SIZEOF_AR_FILE_HDR; + bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt); +@@ -1469,7 +1510,7 @@ + return NULL; + } + +- namlen = strtol (hdr.namlen, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (namlen, hdr.namlen); + amt = SIZEOF_AR_HDR + namlen + 1; + hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt); + if (hdrp == NULL) +@@ -1486,7 +1527,7 @@ + ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; + + ret->arch_header = (char *) hdrp; +- ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size); + ret->filename = (char *) hdrp + SIZEOF_AR_HDR; + } + else +@@ -1501,7 +1542,7 @@ + return NULL; + } + +- namlen = strtol (hdr.namlen, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (namlen, hdr.namlen); + amt = SIZEOF_AR_HDR_BIG + namlen + 1; + hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt); + if (hdrp == NULL) +@@ -1518,10 +1559,7 @@ + ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0'; + + ret->arch_header = (char *) hdrp; +- /* XXX This actually has to be a call to strtoll (at least on 32-bit +- machines) since the field width is 20 and there numbers with more +- than 32 bits can be represented. */ +- ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size); + ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG; + } + +@@ -1550,14 +1588,11 @@ + if (last_file == NULL) + filestart = bfd_ardata (archive)->first_file_filepos; + else +- filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, +- 10); ++ GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff); + + if (filestart == 0 +- || filestart == strtol (xcoff_ardata (archive)->memoff, +- (char **) NULL, 10) +- || filestart == strtol (xcoff_ardata (archive)->symoff, +- (char **) NULL, 10)) ++ || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->memoff) ++ || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->symoff)) + { + bfd_set_error (bfd_error_no_more_archived_files); + return NULL; +@@ -1568,20 +1603,11 @@ + if (last_file == NULL) + filestart = bfd_ardata (archive)->first_file_filepos; + else +- /* XXX These actually have to be a calls to strtoll (at least +- on 32-bit machines) since the fields's width is 20 and +- there numbers with more than 32 bits can be represented. */ +- filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL, +- 10); +- +- /* XXX These actually have to be calls to strtoll (at least on 32-bit +- machines) since the fields's width is 20 and there numbers with more +- than 32 bits can be represented. */ ++ GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff); ++ + if (filestart == 0 +- || filestart == strtol (xcoff_ardata_big (archive)->memoff, +- (char **) NULL, 10) +- || filestart == strtol (xcoff_ardata_big (archive)->symoff, +- (char **) NULL, 10)) ++ || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->memoff) ++ || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->symoff)) + { + bfd_set_error (bfd_error_no_more_archived_files); + return NULL; +@@ -1606,20 +1632,20 @@ + { + struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd); + +- s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); +- s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); +- s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); +- s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); ++ GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date); ++ GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid); ++ GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid); ++ GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode); + s->st_size = arch_eltdata (abfd)->parsed_size; + } + else + { + struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd); + +- s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); +- s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); +- s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); +- s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); ++ GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date); ++ GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid); ++ GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid); ++ GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode); + s->st_size = arch_eltdata (abfd)->parsed_size; + } + +Index: git/bfd/coff64-rs6000.c +=================================================================== +--- git.orig/bfd/coff64-rs6000.c 2017-08-31 16:07:14.282208390 +0530 ++++ git/bfd/coff64-rs6000.c 2017-08-31 16:28:43.228864485 +0530 +@@ -1852,6 +1852,46 @@ + return NULL; + } + ++/* PR 21786: The PE/COFF standard does not require NUL termination for any of ++ the ASCII fields in the archive headers. So in order to be able to extract ++ numerical values we provide our own versions of strtol and strtoll which ++ take a maximum length as an additional parameter. Also - just to save space, ++ we omit the endptr return parameter, since we know that it is never used. */ ++ ++static long ++_bfd_strntol (const char * nptr, int base, unsigned int maxlen) ++{ ++ char buf[24]; /* Should be enough. */ ++ ++ BFD_ASSERT (maxlen < (sizeof (buf) - 1)); ++ ++ memcpy (buf, nptr, maxlen); ++ buf[maxlen] = 0; ++ return strtol (buf, NULL, base); ++} ++ ++static long long ++_bfd_strntoll (const char * nptr, int base, unsigned int maxlen) ++{ ++ char buf[32]; /* Should be enough. */ ++ ++ BFD_ASSERT (maxlen < (sizeof (buf) - 1)); ++ ++ memcpy (buf, nptr, maxlen); ++ buf[maxlen] = 0; ++ return strtoll (buf, NULL, base); ++} ++ ++/* Macro to read an ASCII value stored in an archive header field. */ ++#define GET_VALUE_IN_FIELD(VAR, FIELD) \ ++ do \ ++ { \ ++ (VAR) = sizeof (VAR) > sizeof (long) \ ++ ? _bfd_strntoll (FIELD, 10, sizeof FIELD) \ ++ : _bfd_strntol (FIELD, 10, sizeof FIELD); \ ++ } \ ++ while (0) ++ + /* Read in the armap of an XCOFF archive. */ + + static bfd_boolean +@@ -1892,7 +1932,7 @@ + return FALSE; + + /* Skip the name (normally empty). */ +- namlen = strtol (hdr.namlen, (char **) NULL, 10); ++ GET_VALUE_IN_FIELD (namlen, hdr.namlen); + pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG; + if (bfd_seek (abfd, pos, SEEK_CUR) != 0) + return FALSE; diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-14729.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-14729.patch new file mode 100644 index 0000000000..09d5143829 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-14729.patch @@ -0,0 +1,45 @@ +commit 61e3bf5f83f7e505b6bc51ef65426e5b31e6e360 +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Fri Sep 22 14:15:40 2017 -0700 + +x86: Guard against corrupted PLT + +There should be only one entry in PLT for a given symbol. Set howto to +NULL after processing a PLT entry to guard against corrupted PLT so that +the duplicated PLT entries are skipped. + +PR binutils/22170 + +Upstream-Status: Backport + +CVE: CVE-2017-14729 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> +Index: git/bfd/elf-ifunc.c +=================================================================== +--- git.orig/bfd/elf-ifunc.c 2017-11-08 12:34:22.063320490 +0530 ++++ git/bfd/elf-ifunc.c 2017-11-08 12:34:29.995404891 +0530 +@@ -473,6 +473,10 @@ + memcpy (names, "@plt", sizeof ("@plt")); + names += sizeof ("@plt"); + ++s, ++n; ++ /* There should be only one entry in PLT for a given ++ symbol. Set howto to NULL after processing a PLT ++ entry to guard against corrupted PLT. */ ++ p->howto = NULL; + } + + free (plt_sym_val); +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-11-08 12:34:29.939404297 +0530 ++++ git/bfd/ChangeLog 2017-11-08 12:35:55.660271599 +0530 +@@ -1,3 +1,9 @@ ++2017-09-22 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/22170 ++ * elf-ifunc.c (elf_get_synthetic_symtab): Guard against ++ corrupted PLT. ++ + 2017-07-27 Nick Clifton <nickc@redhat.com> + + PR 21840 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch new file mode 100644 index 0000000000..ef42b13597 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch @@ -0,0 +1,241 @@ +commit 52a93b95ec0771c97e26f0bb28630a271a667bd2 +Author: Alan Modra <amodra@gmail.com> +Date: Sun Sep 24 14:37:16 2017 +0930 + + PR22187, infinite loop in find_abstract_instance_name + + This patch prevents the simple case of infinite recursion in + find_abstract_instance_name by ensuring that the attributes being + processed are not the same as the previous call. + + The patch also does a little cleanup, and leaves in place some changes + to the nested_funcs array that I made when I wrongly thought looping + might occur in scan_unit_for_symbols. + + PR 22187 + * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and + pname param. Return status. Make name const. Don't abort, + return an error. Formatting. Exit if current info_ptr matches + orig_info_ptr. Update callers. + (scan_unit_for_symbols): Start at nesting_level of zero. Make + nested_funcs an array of structs for extensibility. Formatting. + +Upstream-Status: Backport + +CVE: CVE-2017-15024 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/dwarf2.c +=================================================================== +--- git.orig/bfd/dwarf2.c 2017-11-08 12:44:59.198052588 +0530 ++++ git/bfd/dwarf2.c 2017-11-08 12:45:10.670155730 +0530 +@@ -2273,9 +2273,11 @@ + return FALSE; + } + +-static char * ++static bfd_boolean + find_abstract_instance_name (struct comp_unit *unit, ++ bfd_byte *orig_info_ptr, + struct attribute *attr_ptr, ++ const char **pname, + bfd_boolean *is_linkage) + { + bfd *abfd = unit->abfd; +@@ -2285,7 +2287,7 @@ + struct abbrev_info *abbrev; + bfd_uint64_t die_ref = attr_ptr->u.val; + struct attribute attr; +- char *name = NULL; ++ const char *name = NULL; + + /* DW_FORM_ref_addr can reference an entry in a different CU. It + is an offset from the .debug_info section, not the current CU. */ +@@ -2294,7 +2296,12 @@ + /* We only support DW_FORM_ref_addr within the same file, so + any relocations should be resolved already. */ + if (!die_ref) +- abort (); ++ { ++ _bfd_error_handler ++ (_("Dwarf Error: Abstract instance DIE ref zero.")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } + + info_ptr = unit->sec_info_ptr + die_ref; + info_ptr_end = unit->end_ptr; +@@ -2329,9 +2336,10 @@ + (*_bfd_error_handler) + (_("Dwarf Error: Unable to read alt ref %u."), die_ref); + bfd_set_error (bfd_error_bad_value); +- return NULL; ++ return FALSE; + } +- info_ptr_end = unit->stash->alt_dwarf_info_buffer + unit->stash->alt_dwarf_info_size; ++ info_ptr_end = (unit->stash->alt_dwarf_info_buffer ++ + unit->stash->alt_dwarf_info_size); + + /* FIXME: Do we need to locate the correct CU, in a similar + fashion to the code in the DW_FORM_ref_addr case above ? */ +@@ -2353,6 +2361,7 @@ + (*_bfd_error_handler) + (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); + bfd_set_error (bfd_error_bad_value); ++ return FALSE; + } + else + { +@@ -2362,6 +2371,15 @@ + info_ptr, info_ptr_end); + if (info_ptr == NULL) + break; ++ /* It doesn't ever make sense for DW_AT_specification to ++ refer to the same DIE. Stop simple recursion. */ ++ if (info_ptr == orig_info_ptr) ++ { ++ _bfd_error_handler ++ (_("Dwarf Error: Abstract instance recursion detected.")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } + switch (attr.name) + { + case DW_AT_name: +@@ -2375,7 +2393,9 @@ + } + break; + case DW_AT_specification: +- name = find_abstract_instance_name (unit, &attr, is_linkage); ++ if (!find_abstract_instance_name (unit, info_ptr, &attr, ++ pname, is_linkage)) ++ return FALSE; + break; + case DW_AT_linkage_name: + case DW_AT_MIPS_linkage_name: +@@ -2393,7 +2413,8 @@ + } + } + } +- return name; ++ *pname = name; ++ return TRUE; + } + + static bfd_boolean +@@ -2454,20 +2475,22 @@ + bfd *abfd = unit->abfd; + bfd_byte *info_ptr = unit->first_child_die_ptr; + bfd_byte *info_ptr_end = unit->stash->info_ptr_end; +- int nesting_level = 1; +- struct funcinfo **nested_funcs; ++ int nesting_level = 0; ++ struct nest_funcinfo { ++ struct funcinfo *func; ++ } *nested_funcs; + int nested_funcs_size; + + /* Maintain a stack of in-scope functions and inlined functions, which we + can use to set the caller_func field. */ + nested_funcs_size = 32; +- nested_funcs = (struct funcinfo **) +- bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *)); ++ nested_funcs = (struct nest_funcinfo *) ++ bfd_malloc (nested_funcs_size * sizeof (*nested_funcs)); + if (nested_funcs == NULL) + return FALSE; +- nested_funcs[nesting_level] = 0; ++ nested_funcs[nesting_level].func = 0; + +- while (nesting_level) ++ while (nesting_level >= 0) + { + unsigned int abbrev_number, bytes_read, i; + struct abbrev_info *abbrev; +@@ -2516,13 +2539,13 @@ + BFD_ASSERT (!unit->cached); + + if (func->tag == DW_TAG_inlined_subroutine) +- for (i = nesting_level - 1; i >= 1; i--) +- if (nested_funcs[i]) ++ for (i = nesting_level; i-- != 0; ) ++ if (nested_funcs[i].func) + { +- func->caller_func = nested_funcs[i]; ++ func->caller_func = nested_funcs[i].func; + break; + } +- nested_funcs[nesting_level] = func; ++ nested_funcs[nesting_level].func = func; + } + else + { +@@ -2541,12 +2564,13 @@ + } + + /* No inline function in scope at this nesting level. */ +- nested_funcs[nesting_level] = 0; ++ nested_funcs[nesting_level].func = 0; + } + + for (i = 0; i < abbrev->num_attrs; ++i) + { +- info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, info_ptr_end); ++ info_ptr = read_attribute (&attr, &abbrev->attrs[i], ++ unit, info_ptr, info_ptr_end); + if (info_ptr == NULL) + goto fail; + +@@ -2565,8 +2589,10 @@ + + case DW_AT_abstract_origin: + case DW_AT_specification: +- func->name = find_abstract_instance_name (unit, &attr, +- &func->is_linkage); ++ if (!find_abstract_instance_name (unit, info_ptr, &attr, ++ &func->name, ++ &func->is_linkage)) ++ goto fail; + break; + + case DW_AT_name: +@@ -2691,17 +2717,17 @@ + + if (nesting_level >= nested_funcs_size) + { +- struct funcinfo **tmp; ++ struct nest_funcinfo *tmp; + + nested_funcs_size *= 2; +- tmp = (struct funcinfo **) ++ tmp = (struct nest_funcinfo *) + bfd_realloc (nested_funcs, +- nested_funcs_size * sizeof (struct funcinfo *)); ++ nested_funcs_size * sizeof (*nested_funcs)); + if (tmp == NULL) + goto fail; + nested_funcs = tmp; + } +- nested_funcs[nesting_level] = 0; ++ nested_funcs[nesting_level].func = 0; + } + } + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-11-08 12:45:10.614155229 +0530 ++++ git/bfd/ChangeLog 2017-11-08 12:46:55.791054918 +0530 +@@ -1,3 +1,13 @@ ++2017-09-24 Alan Modra <amodra@gmail.com> ++ ++ PR 22187 ++ * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and ++ pname param. Return status. Make name const. Don't abort, ++ return an error. Formatting. Exit if current info_ptr matches ++ orig_info_ptr. Update callers. ++ (scan_unit_for_symbols): Start at nesting_level of zero. Make ++ nested_funcs an array of structs for extensibility. Formatting. ++ + 2017-09-22 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/22170 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-15938.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-15938.patch new file mode 100644 index 0000000000..25d6f3a32a --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-15938.patch @@ -0,0 +1,153 @@ +commit 1b86808a86077722ee4f42ff97f836b12420bb2a +Author: Alan Modra <amodra@gmail.com> +Date: Tue Sep 26 21:47:24 2017 +0930 + + PR22209, invalid memory read in find_abstract_instance_name + + This patch adds bounds checking for DW_FORM_ref_addr die refs, and + calculates them relative to the first .debug_info section. See the + big comment for why calculating relative to the current .debug_info + section was wrong for relocatable object files. + + PR 22209 + * dwarf2.c (struct comp_unit): Delete sec_info_ptr field. + (find_abstract_instance_name): Calculate DW_FORM_ref_addr relative + to stash->info_ptr_memory, and check die_ref is within that memory. + Set info_ptr_end correctly when another CU is refd. Check die_ref + for DW_FORM_ref4 etc. is within CU. + +Upstream-Status: Backport + +CVE: CVE-2017-15938 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/dwarf2.c +=================================================================== +--- git.orig/bfd/dwarf2.c 2017-11-07 18:52:19.896253364 +0530 ++++ git/bfd/dwarf2.c 2017-11-07 18:52:19.952253802 +0530 +@@ -119,8 +119,7 @@ + + /* A pointer to the memory block allocated for info_ptr. Neither + info_ptr nor sec_info_ptr are guaranteed to stay pointing to the +- beginning of the malloc block. This is used only to free the +- memory later. */ ++ beginning of the malloc block. */ + bfd_byte *info_ptr_memory; + + /* Pointer to the symbol table. */ +@@ -238,9 +237,6 @@ + by its reference. */ + bfd_byte *info_ptr_unit; + +- /* Pointer to the start of the debug section, for DW_FORM_ref_addr. */ +- bfd_byte *sec_info_ptr; +- + /* The offset into .debug_line of the line number table. */ + unsigned long line_offset; + +@@ -2294,21 +2290,37 @@ + if (attr_ptr->form == DW_FORM_ref_addr) + { + /* We only support DW_FORM_ref_addr within the same file, so +- any relocations should be resolved already. */ +- if (!die_ref) ++ any relocations should be resolved already. Check this by ++ testing for a zero die_ref; There can't be a valid reference ++ to the header of a .debug_info section. ++ DW_FORM_ref_addr is an offset relative to .debug_info. ++ Normally when using the GNU linker this is accomplished by ++ emitting a symbolic reference to a label, because .debug_info ++ sections are linked at zero. When there are multiple section ++ groups containing .debug_info, as there might be in a ++ relocatable object file, it would be reasonable to assume that ++ a symbolic reference to a label in any .debug_info section ++ might be used. Since we lay out multiple .debug_info ++ sections at non-zero VMAs (see place_sections), and read ++ them contiguously into stash->info_ptr_memory, that means ++ the reference is relative to stash->info_ptr_memory. */ ++ size_t total; ++ ++ info_ptr = unit->stash->info_ptr_memory; ++ info_ptr_end = unit->stash->info_ptr_end; ++ total = info_ptr_end - info_ptr; ++ if (!die_ref || die_ref >= total) + { + _bfd_error_handler +- (_("Dwarf Error: Abstract instance DIE ref zero.")); ++ (_("Dwarf Error: Invalid abstract instance DIE ref.")); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } +- +- info_ptr = unit->sec_info_ptr + die_ref; +- info_ptr_end = unit->end_ptr; ++ info_ptr += die_ref; + + /* Now find the CU containing this pointer. */ + if (info_ptr >= unit->info_ptr_unit && info_ptr < unit->end_ptr) +- ; ++ info_ptr_end = unit->end_ptr; + else + { + /* Check other CUs to see if they contain the abbrev. */ +@@ -2324,7 +2336,10 @@ + break; + + if (u) +- unit = u; ++ { ++ unit = u; ++ info_ptr_end = unit->end_ptr; ++ } + /* else FIXME: What do we do now ? */ + } + } +@@ -2346,8 +2361,22 @@ + } + else + { +- info_ptr = unit->info_ptr_unit + die_ref; ++ /* DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8 or ++ DW_FORM_ref_udata. These are all references relative to the ++ start of the current CU. */ ++ size_t total; ++ ++ info_ptr = unit->info_ptr_unit; + info_ptr_end = unit->end_ptr; ++ total = info_ptr_end - info_ptr; ++ if (!die_ref || die_ref >= total) ++ { ++ _bfd_error_handler ++ (_("Dwarf Error: Invalid abstract instance DIE ref.")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ info_ptr += die_ref; + } + + abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end); +@@ -2846,7 +2875,6 @@ + unit->end_ptr = end_ptr; + unit->stash = stash; + unit->info_ptr_unit = info_ptr_unit; +- unit->sec_info_ptr = stash->sec_info_ptr; + + for (i = 0; i < abbrev->num_attrs; ++i) + { +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-11-07 18:52:19.900253395 +0530 ++++ git/bfd/ChangeLog 2017-11-07 18:53:29.668799630 +0530 +@@ -1,3 +1,12 @@ ++2017-09-26 Alan Modra <amodra@gmail.com> ++ ++ PR 22209 ++ * dwarf2.c (struct comp_unit): Delete sec_info_ptr field. ++ (find_abstract_instance_name): Calculate DW_FORM_ref_addr relative ++ to stash->info_ptr_memory, and check die_ref is within that memory. ++ Set info_ptr_end correctly when another CU is refd. Check die_ref ++ for DW_FORM_ref4 etc. is within CU. ++ + 2017-09-24 Alan Modra <amodra@gmail.com> + + PR 22187 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7223.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7223.patch new file mode 100644 index 0000000000..eb9fc6f36c --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7223.patch @@ -0,0 +1,40 @@ +commit 69ace2200106348a1b00d509a6a234337c104c17 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Dec 1 15:20:19 2016 +0000 + + Fix seg fault attempting to unget an EOF character. + + PR gas/20898 + * app.c (do_scrub_chars): Do not attempt to unget EOF. + +Upstream-Status: backport + +CVE: CVE-2017-7223 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/gas/ChangeLog +=================================================================== +--- git.orig/gas/ChangeLog 2017-09-04 12:42:08.941602299 +0530 ++++ git/gas/ChangeLog 2017-09-04 12:48:28.863820763 +0530 +@@ -1,3 +1,8 @@ ++2016-12-01 Nick Clifton <nickc@redhat.com> ++ ++ PR gas/20898 ++ * app.c (do_scrub_chars): Do not attempt to unget EOF. ++ + 2016-08-05 Nick Clifton <nickc@redhat.com> + + PR gas/20364 +Index: git/gas/app.c +=================================================================== +--- git.orig/gas/app.c 2017-09-04 12:42:05.261580103 +0530 ++++ git/gas/app.c 2017-09-04 12:47:19.923428673 +0530 +@@ -1187,7 +1187,7 @@ + state = -2; + break; + } +- else ++ else if (ch2 != EOF) + { + UNGET (ch2); + } diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7224.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7224.patch new file mode 100644 index 0000000000..fb9ce90740 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7224.patch @@ -0,0 +1,48 @@ +commit e82ab856bb4689330c29fb9f1c57a8555b26380e +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Dec 1 10:49:39 2016 +0000 + + Fix a seg-fault disassembling a corrupt binary. + + PR binutils/20892 + * aoutx.h (find_nearest_line): Handle the case where the function + name is empty. + +Upstream-Status: Backport + +CVE: CVE-2017-7224 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 12:54:37.513859864 +0530 ++++ git/bfd/ChangeLog 2017-09-04 13:00:22.891753836 +0530 +@@ -120,6 +120,10 @@ + * peicode.h (pe_ILF_object_p): Use strnlen to avoid running over + the end of the string buffer. + ++ PR binutils/20892 ++ * aoutx.h (find_nearest_line): Handle the case where the function ++ name is empty. ++ + 2016-08-02 Nick Clifton <nickc@redhat.com> + + PR ld/17739 +Index: git/bfd/aoutx.h +=================================================================== +--- git.orig/bfd/aoutx.h 2017-09-04 12:54:35.957851411 +0530 ++++ git/bfd/aoutx.h 2017-09-04 12:57:50.634902163 +0530 +@@ -2819,6 +2819,13 @@ + const char *function = func->name; + char *colon; + ++ if (buf == NULL) ++ { ++ /* PR binutils/20892: In a corrupt input file func can be empty. */ ++ * functionname_ptr = NULL; ++ return TRUE; ++ } ++ + /* The caller expects a symbol name. We actually have a + function name, without the leading underscore. Put the + underscore back in, so that the caller gets a symbol name. */ diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7225.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7225.patch new file mode 100644 index 0000000000..699905a4d0 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7225.patch @@ -0,0 +1,66 @@ +commit 50455f1ab2935f7321215dfa681745c9b1cb5b19 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Dec 1 10:15:07 2016 +0000 + + Fix seg-fault running addr2line on a corrupt binary. + + PR binutils/20891 + * aoutx.h (find_nearest_line): Handle the case where the main file + name and the directory name are both empty. + +Upstream-Status: backport + +CVE: CVE-2017-7225 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 13:04:20.941485636 +0530 ++++ git/bfd/ChangeLog 2017-09-04 13:08:05.003175703 +0530 +@@ -120,6 +120,12 @@ + * peicode.h (pe_ILF_object_p): Use strnlen to avoid running over + the end of the string buffer. + ++2016-12-01 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/20891 ++ * aoutx.h (find_nearest_line): Handle the case where the main file ++ name and the directory name are both empty. ++ + PR binutils/20892 + * aoutx.h (find_nearest_line): Handle the case where the function + name is empty. +Index: git/bfd/aoutx.h +=================================================================== +--- git.orig/bfd/aoutx.h 2017-09-04 13:04:20.941485636 +0530 ++++ git/bfd/aoutx.h 2017-09-04 13:10:55.856441243 +0530 +@@ -2663,7 +2663,7 @@ + char *buf; + + *filename_ptr = abfd->filename; +- *functionname_ptr = 0; ++ *functionname_ptr = NULL; + *line_ptr = 0; + if (disriminator_ptr) + *disriminator_ptr = 0; +@@ -2808,9 +2808,17 @@ + *filename_ptr = main_file_name; + else + { +- sprintf (buf, "%s%s", directory_name, main_file_name); +- *filename_ptr = buf; +- buf += filelen + 1; ++ if (buf == NULL) ++ /* PR binutils/20891: In a corrupt input file both ++ main_file_name and directory_name can be empty... */ ++ * filename_ptr = NULL; ++ else ++ { ++ snprintf (buf, filelen + 1, "%s%s", directory_name, ++ main_file_name); ++ *filename_ptr = buf; ++ buf += filelen + 1; ++ } + } + } + diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7226.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7226.patch new file mode 100644 index 0000000000..7525f34324 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7226.patch @@ -0,0 +1,42 @@ +Fix seg-fault in the binutils utilities when reading a corrupt input file. + +PR binutils/20905 +* peicode.h (pe_ILF_object_p): Use strnlen to avoid running over +the end of the string buffer. + +Upstream-Status: Backport + +CVE: CVE-2017-7226 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-08-23 13:59:16.868424171 +0530 ++++ git/bfd/ChangeLog 2017-08-23 14:03:22.683013823 +0530 +@@ -39,6 +39,12 @@ + (bfd_elf_final_link): Only initialize the extended symbol index + section if there are extended symbol tables to list. + ++2016-12-05 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/20905 ++ * peicode.h (pe_ILF_object_p): Use strnlen to avoid running over ++ the end of the string buffer. ++ + 2016-08-02 Nick Clifton <nickc@redhat.com> + + PR ld/17739 +Index: git/bfd/peicode.h +=================================================================== +--- git.orig/bfd/peicode.h 2017-08-23 13:59:06.948319100 +0530 ++++ git/bfd/peicode.h 2017-08-23 13:59:16.920424722 +0530 +@@ -1264,7 +1264,8 @@ + } + + symbol_name = (char *) ptr; +- source_dll = symbol_name + strlen (symbol_name) + 1; ++ /* See PR 20905 for an example of where the strnlen is necessary. */ ++ source_dll = symbol_name + strnlen (symbol_name, size - 1) + 1; + + /* Verify that the strings are null terminated. */ + if (ptr[size - 1] != 0 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7227.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7227.patch new file mode 100644 index 0000000000..1fa98e19be --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7227.patch @@ -0,0 +1,49 @@ +commit 406bd128dba2a59d0736839fc87a59bce319076c +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Dec 5 16:00:43 2016 +0000 + + Fix seg-fault in linker when passed a bogus input script. + + PR ld/20906 + * ldlex.l: Check for bogus strings in linker scripts. + +Upstream-Status: backport + +CVE: CVE-2017-7227 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/ld/ChangeLog +=================================================================== +--- git.orig/ld/ChangeLog 2017-09-04 13:18:09.660584245 +0530 ++++ git/ld/ChangeLog 2017-09-04 13:20:34.286155911 +0530 +@@ -1,3 +1,8 @@ ++2016-12-05 Nick Clifton <nickc@redhat.com> ++ ++ PR ld/20906 ++ * ldlex.l: Check for bogus strings in linker scripts. ++ + 2016-08-02 Nick Clifton <nickc@redhat.com> + + PR ld/17739 +Index: git/ld/ldlex.l +=================================================================== +--- git.orig/ld/ldlex.l 2017-09-04 13:18:09.692584605 +0530 ++++ git/ld/ldlex.l 2017-09-04 13:22:54.483583368 +0530 +@@ -416,9 +416,15 @@ + + <EXPRESSION,BOTH,SCRIPT,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" { + /* No matter the state, quotes +- give what's inside */ ++ give what's inside. */ ++ bfd_size_type len; + yylval.name = xstrdup (yytext + 1); +- yylval.name[yyleng - 2] = 0; ++ /* PR ld/20906. A corrupt input file ++ can contain bogus strings. */ ++ len = strlen (yylval.name); ++ if (len > yyleng - 2) ++ len = yyleng - 2; ++ yylval.name[len] = 0; + return NAME; + } + <BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;} diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_1.patch new file mode 100644 index 0000000000..50a48bc549 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_1.patch @@ -0,0 +1,47 @@ +commit d7f399a8de4c55eb841db6493597a587fac002de +Author: Nick Clifton <nickc@redhat.com> +Date: Fri Dec 2 17:46:26 2016 +0000 + + Fix seg-fault in linker when passed a corrupt binary input file. + + PR lf/20908 + * elflink.c (bfd_elf_final_link): Check for ELF flavour binaries + when following indirect links. + +Upstream-Status: Backport + +CVE: CVE-2017-7299 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/elflink.c +=================================================================== +--- git.orig/bfd/elflink.c 2017-09-20 14:15:26.337333504 +0530 ++++ git/bfd/elflink.c 2017-09-20 14:20:19.000000000 +0530 +@@ -11201,6 +11201,12 @@ + asection *sec; + + sec = p->u.indirect.section; ++ /* See PR 20908 for a reproducer. */ ++ if (bfd_get_flavour (sec->owner) != bfd_target_elf_flavour) ++ { ++ _bfd_error_handler (_("%B: not in ELF format"), sec->owner); ++ goto error_return; ++ } + esdi = elf_section_data (sec); + + /* Mark all sections which are to be included in the +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-20 14:20:19.000000000 +0530 ++++ git/bfd/ChangeLog 2017-09-20 14:23:48.743556932 +0530 +@@ -192,6 +192,10 @@ + + 2016-12-02 Nick Clifton <nickc@redhat.com> + ++ PR lf/20908 ++ * elflink.c (bfd_elf_final_link): Check for ELF flavour binaries ++ when following indirect links. ++ + PR ld/20909 + * aoutx.h (aout_link_add_symbols): Fix off-by-one error in check + for an illegal string offset. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_2.patch new file mode 100644 index 0000000000..7691b122ce --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7299_2.patch @@ -0,0 +1,120 @@ +commit a961cdd5f139d3c3e09170db52bd8df7dafae13f +Author: Alan Modra <amodra@gmail.com> +Date: Thu Dec 15 21:29:44 2016 +1030 + + Linking non-ELF file broken by PR20908 fix + + PR ld/20968 + PR ld/20908 + * elflink.c (bfd_elf_final_link): Revert 2016-12-02 change. Move + reloc counting code later after ELF flavour test. + +Upstream-Status: Backport + +CVE: CVE-2017-7299 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/elflink.c +=================================================================== +--- git.orig/bfd/elflink.c 2017-09-20 14:15:28.133343092 +0530 ++++ git/bfd/elflink.c 2017-09-20 14:15:28.189343391 +0530 +@@ -11201,13 +11201,6 @@ + asection *sec; + + sec = p->u.indirect.section; +- /* See PR 20908 for a reproducer. */ +- if (bfd_get_flavour (sec->owner) != bfd_target_elf_flavour) +- { +- _bfd_error_handler (_("%B: not in ELF format"), sec->owner); +- goto error_return; +- } +- esdi = elf_section_data (sec); + + /* Mark all sections which are to be included in the + link. This will normally be every section. We need +@@ -11218,37 +11211,18 @@ + if (sec->flags & SEC_MERGE) + merged = TRUE; + +- if (esdo->this_hdr.sh_type == SHT_REL +- || esdo->this_hdr.sh_type == SHT_RELA) +- /* Some backends use reloc_count in relocation sections +- to count particular types of relocs. Of course, +- reloc sections themselves can't have relocations. */ +- reloc_count = 0; +- else if (emit_relocs) +- { +- reloc_count = sec->reloc_count; +- if (bed->elf_backend_count_additional_relocs) +- { +- int c; +- c = (*bed->elf_backend_count_additional_relocs) (sec); +- additional_reloc_count += c; +- } +- } +- else if (bed->elf_backend_count_relocs) +- reloc_count = (*bed->elf_backend_count_relocs) (info, sec); +- + if (sec->rawsize > max_contents_size) + max_contents_size = sec->rawsize; + if (sec->size > max_contents_size) + max_contents_size = sec->size; + +- /* We are interested in just local symbols, not all +- symbols. */ + if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour + && (sec->owner->flags & DYNAMIC) == 0) + { + size_t sym_count; + ++ /* We are interested in just local symbols, not all ++ symbols. */ + if (elf_bad_symtab (sec->owner)) + sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size + / bed->s->sizeof_sym); +@@ -11262,6 +11236,27 @@ + && elf_symtab_shndx_list (sec->owner) != NULL) + max_sym_shndx_count = sym_count; + ++ if (esdo->this_hdr.sh_type == SHT_REL ++ || esdo->this_hdr.sh_type == SHT_RELA) ++ /* Some backends use reloc_count in relocation sections ++ to count particular types of relocs. Of course, ++ reloc sections themselves can't have relocations. */ ++ ; ++ else if (emit_relocs) ++ { ++ reloc_count = sec->reloc_count; ++ if (bed->elf_backend_count_additional_relocs) ++ { ++ int c; ++ c = (*bed->elf_backend_count_additional_relocs) (sec); ++ additional_reloc_count += c; ++ } ++ } ++ else if (bed->elf_backend_count_relocs) ++ reloc_count = (*bed->elf_backend_count_relocs) (info, sec); ++ ++ esdi = elf_section_data (sec); ++ + if ((sec->flags & SEC_RELOC) != 0) + { + size_t ext_size = 0; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-20 14:15:28.013342453 +0530 ++++ git/bfd/ChangeLog 2017-09-20 14:19:06.990419395 +0530 +@@ -156,6 +156,13 @@ + (bfd_elf_final_link): Only initialize the extended symbol index + section if there are extended symbol tables to list. + ++2016-12-15 Alan Modra <amodra@gmail.com> ++ ++ PR ld/20968 ++ PR ld/20908 ++ * elflink.c (bfd_elf_final_link): Revert 2016-12-02 change. Move ++ reloc counting code later after ELF flavour test. ++ + 2016-12-06 Nick Clifton <nickc@redhat.com> + + PR binutils/20931 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7300.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7300.patch new file mode 100644 index 0000000000..c4432e76b0 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7300.patch @@ -0,0 +1,55 @@ +From 531336e3a0b79ed60cfc36ad2d6579b6a71175da Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Fri, 2 Dec 2016 16:41:14 +0000 +Subject: [PATCH] Fix seg-fault in the linker when examining a corrupt binary. + + PR ld/20909 + * aoutx.h (aout_link_add_symbols): Fix off-by-one error in check + for an illegal string offset. + +Upstream-Status: Backport +CVE: CVE-2017-7300 +VER: < 2.27-r0.9.1 +Signed-off-by: Manjunath Matti <mmatti@mvista.com> + +--- + bfd/ChangeLog | 6 ++++++ + bfd/aoutx.h | 3 +-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/bfd/ChangeLog b/bfd/ChangeLog +index d061e66..c8085e7 100644 +--- a/bfd/ChangeLog ++++ b/bfd/ChangeLog +@@ -175,6 +175,12 @@ + * aoutx.h (find_nearest_line): Handle the case where the function + name is empty. + ++2016-12-02 Nick Clifton <nickc@redhat.com> ++ ++ PR ld/20909 ++ * aoutx.h (aout_link_add_symbols): Fix off-by-one error in check ++ for an illegal string offset. ++ + 2016-08-02 Nick Clifton <nickc@redhat.com> + + PR ld/17739 +diff --git a/bfd/aoutx.h b/bfd/aoutx.h +index 4308679..b9ac2b7 100644 +--- a/bfd/aoutx.h ++++ b/bfd/aoutx.h +@@ -3031,10 +3031,9 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) + continue; + + /* PR 19629: Corrupt binaries can contain illegal string offsets. */ +- if (GET_WORD (abfd, p->e_strx) > obj_aout_external_string_size (abfd)) ++ if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) + return FALSE; + name = strings + GET_WORD (abfd, p->e_strx); +- + value = GET_WORD (abfd, p->e_value); + flags = BSF_GLOBAL; + string = NULL; +-- +2.9.3 + diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7301.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7301.patch new file mode 100644 index 0000000000..36b4259fde --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7301.patch @@ -0,0 +1,52 @@ +commit daae68f4f372e0618d6b9c64ec0f1f74eae6ab3d +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Dec 5 12:25:34 2016 +0000 + + Fix seg-fault in linker parsing a corrupt input file. + + PR ld/20924 + (aout_link_add_symbols): Fix off by one error checking for + overflow of string offset. + +Upstream-Status: Backport + +CVE: CVE-2017-7301 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 15:42:15.244812577 +0530 ++++ git/bfd/ChangeLog 2017-09-04 15:51:36.573466525 +0530 +@@ -120,6 +120,10 @@ + * peicode.h (pe_ILF_object_p): Use strnlen to avoid running over + the end of the string buffer. + ++ PR ld/20924 ++ (aout_link_add_symbols): Fix off by one error checking for ++ overflow of string offset. ++ + 2016-12-01 Nick Clifton <nickc@redhat.com> + + PR binutils/20891 +Index: git/bfd/aoutx.h +=================================================================== +--- git.orig/bfd/aoutx.h 2017-09-04 15:42:15.244812577 +0530 ++++ git/bfd/aoutx.h 2017-09-04 15:49:36.500479341 +0530 +@@ -3091,7 +3091,7 @@ + BFD_ASSERT (p + 1 < pend); + ++p; + /* PR 19629: Corrupt binaries can contain illegal string offsets. */ +- if (GET_WORD (abfd, p->e_strx) > obj_aout_external_string_size (abfd)) ++ if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) + return FALSE; + string = strings + GET_WORD (abfd, p->e_strx); + section = bfd_ind_section_ptr; +@@ -3127,7 +3127,7 @@ + ++p; + string = name; + /* PR 19629: Corrupt binaries can contain illegal string offsets. */ +- if (GET_WORD (abfd, p->e_strx) > obj_aout_external_string_size (abfd)) ++ if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd)) + return FALSE; + name = strings + GET_WORD (abfd, p->e_strx); + section = bfd_und_section_ptr; diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7302.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7302.patch new file mode 100644 index 0000000000..a45de0e0ab --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7302.patch @@ -0,0 +1,81 @@ +commit e2996cc315d6ea242e1a954dc20246485ccc8512 +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Dec 5 14:32:30 2016 +0000 + + Fix seg-fault running strip on a corrupt binary. + + PR binutils/20921 + * aoutx.h (squirt_out_relocs): Check for and report any relocs + that could not be recognised. + +Upstream-Status: Backport + +CVE: CVE-2017-7302 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 15:57:38.564419146 +0530 ++++ git/bfd/ChangeLog 2017-09-04 16:02:31.994883900 +0530 +@@ -124,6 +124,10 @@ + (aout_link_add_symbols): Fix off by one error checking for + overflow of string offset. + ++ PR binutils/20921 ++ * aoutx.h (squirt_out_relocs): Check for and report any relocs ++ that could not be recognised. ++ + 2016-12-01 Nick Clifton <nickc@redhat.com> + + PR binutils/20891 +Index: git/bfd/aoutx.h +=================================================================== +--- git.orig/bfd/aoutx.h 2017-09-04 15:57:38.564419146 +0530 ++++ git/bfd/aoutx.h 2017-09-04 16:01:08.830188291 +0530 +@@ -1952,6 +1952,7 @@ + + PUT_WORD (abfd, g->address, natptr->r_address); + ++ BFD_ASSERT (g->howto != NULL); + r_length = g->howto->size ; /* Size as a power of two. */ + r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ + /* XXX This relies on relocs coming from a.out files. */ +@@ -2390,16 +2391,34 @@ + for (natptr = native; + count != 0; + --count, natptr += each_size, ++generic) +- MY_swap_ext_reloc_out (abfd, *generic, +- (struct reloc_ext_external *) natptr); ++ { ++ if ((*generic)->howto == NULL) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ _bfd_error_handler (_("%B: attempt to write out unknown reloc type"), abfd); ++ return FALSE; ++ } ++ MY_swap_ext_reloc_out (abfd, *generic, ++ (struct reloc_ext_external *) natptr); ++ } + } + else + { + for (natptr = native; + count != 0; + --count, natptr += each_size, ++generic) +- MY_swap_std_reloc_out (abfd, *generic, +- (struct reloc_std_external *) natptr); ++ { ++ /* PR 20921: If the howto field has not been initialised then skip ++ this reloc. */ ++ if ((*generic)->howto == NULL) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ _bfd_error_handler (_("%B: attempt to write out unknown reloc type"), abfd); ++ return FALSE; ++ } ++ MY_swap_std_reloc_out (abfd, *generic, ++ (struct reloc_std_external *) natptr); ++ } + } + + if (bfd_bwrite ((void *) native, natsize, abfd) != natsize) diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7303.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7303.patch new file mode 100644 index 0000000000..59a3b17461 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7303.patch @@ -0,0 +1,55 @@ +commit a55c9876bb111fd301b4762cf501de0040b8f9db +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Dec 5 13:35:50 2016 +0000 + + Fix seg-fault attempting to strip a corrupt binary. + + PR binutils/20922 + * elf.c (find_link): Check for null headers before attempting to + match them. + +Upstream-Status: Backport + +CVE: CVE-2017-7303 +Signed-off-by: Thiruvadi Rajaraman <tarjaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 16:06:08.996688391 +0530 ++++ git/bfd/ChangeLog 2017-09-04 16:09:26.810320541 +0530 +@@ -124,6 +124,10 @@ + (aout_link_add_symbols): Fix off by one error checking for + overflow of string offset. + ++ PR binutils/20922 ++ * elf.c (find_link): Check for null headers before attempting to ++ match them. ++ + PR binutils/20921 + * aoutx.h (squirt_out_relocs): Check for and report any relocs + that could not be recognised. +Index: git/bfd/elf.c +=================================================================== +--- git.orig/bfd/elf.c 2017-09-04 16:05:55.612577527 +0530 ++++ git/bfd/elf.c 2017-09-04 16:08:35.709900050 +0530 +@@ -1249,13 +1249,19 @@ + Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd); + unsigned int i; + +- if (section_match (oheaders[hint], iheader)) ++ BFD_ASSERT (iheader != NULL); ++ ++ /* See PR 20922 for a reproducer of the NULL test. */ ++ if (oheaders[hint] != NULL ++ && section_match (oheaders[hint], iheader)) + return hint; + + for (i = 1; i < elf_numsections (obfd); i++) + { + Elf_Internal_Shdr * oheader = oheaders[i]; + ++ if (oheader == NULL) ++ continue; + if (section_match (oheader, iheader)) + /* FIXME: Do we care if there is a potential for + multiple matches ? */ diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7304.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7304.patch new file mode 100644 index 0000000000..817a3f0176 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7304.patch @@ -0,0 +1,53 @@ +commit 4f3ca05b487e9755018b4c9a053a2e6c35d8a7df +Author: Nick Clifton <nickc@redhat.com> +Date: Tue Dec 6 16:53:57 2016 +0000 + + Fix seg-fault in strip when copying a corrupt binary. + + PR binutils/20931 + * elf.c (copy_special_section_fields): Check for an invalid + sh_link field before attempting to follow it. + +Upstream-Status: Backport + +CVE: CVE-2017-7304 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 16:13:03.512095249 +0530 ++++ git/bfd/ChangeLog 2017-09-04 16:16:25.173745111 +0530 +@@ -114,6 +114,12 @@ + (bfd_elf_final_link): Only initialize the extended symbol index + section if there are extended symbol tables to list. + ++ 2016-12-06 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/20931 ++ * elf.c (copy_special_section_fields): Check for an invalid ++ sh_link field before attempting to follow it. ++ + 2016-12-05 Nick Clifton <nickc@redhat.com> + + PR binutils/20905 +Index: git/bfd/elf.c +=================================================================== +--- git.orig/bfd/elf.c 2017-09-04 16:13:03.512095249 +0530 ++++ git/bfd/elf.c 2017-09-04 16:15:38.257359045 +0530 +@@ -1324,6 +1324,16 @@ + in the input bfd. */ + if (iheader->sh_link != SHN_UNDEF) + { ++ /* See PR 20931 for a reproducer. */ ++ if (iheader->sh_link >= elf_numsections (ibfd)) ++ { ++ (* _bfd_error_handler) ++ /* xgettext:c-format */ ++ (_("%B: Invalid sh_link field (%d) in section number %d"), ++ ibfd, iheader->sh_link, secnum); ++ return FALSE; ++ } ++ + sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link); + if (sh_link != SHN_UNDEF) + { diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-7614.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-7614.patch new file mode 100644 index 0000000000..0fb32b3e26 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-7614.patch @@ -0,0 +1,105 @@ +From ad32986fdf9da1c8748e47b8b45100398223dba8 Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Tue, 4 Apr 2017 11:23:36 +0100 +Subject: [PATCH] Fix null pointer dereferences when using a link built with + clang. + + PR binutils/21342 + * elflink.c (_bfd_elf_define_linkage_sym): Prevent null pointer + dereference. + (bfd_elf_final_link): Only initialize the extended symbol index + section if there are extended symbol tables to list. + +Upstream-Status: Backport +https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad32986fdf9da1c8748e47b8b45100398223dba8 + +CVE: CVE-2017-7614 + +Singed-off-by: Armin Kuster <akuster@mvista.com> + +--- + bfd/elflink.c | 35 +++++++++++++++++++++-------------- + 2 files changed, 29 insertions(+), 14 deletions(-) + +Index: git/bfd/elflink.c +=================================================================== +--- git.orig/bfd/elflink.c ++++ git/bfd/elflink.c +@@ -118,15 +118,18 @@ _bfd_elf_define_linkage_sym (bfd *abfd, + defined in shared libraries can't be overridden, because we + lose the link to the bfd which is via the symbol section. */ + h->root.type = bfd_link_hash_new; ++ bh = &h->root; + } ++ else ++ bh = NULL; + +- bh = &h->root; + bed = get_elf_backend_data (abfd); + if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL, + sec, 0, NULL, FALSE, bed->collect, + &bh)) + return NULL; + h = (struct elf_link_hash_entry *) bh; ++ BFD_ASSERT (h != NULL); + h->def_regular = 1; + h->non_elf = 0; + h->root.linker_def = 1; +@@ -11789,24 +11792,28 @@ bfd_elf_final_link (bfd *abfd, struct bf + { + /* Finish up and write out the symbol string table (.strtab) + section. */ +- Elf_Internal_Shdr *symstrtab_hdr; ++ Elf_Internal_Shdr *symstrtab_hdr = NULL; + file_ptr off = symtab_hdr->sh_offset + symtab_hdr->sh_size; + +- symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; +- if (symtab_shndx_hdr != NULL && symtab_shndx_hdr->sh_name != 0) ++ if (elf_symtab_shndx_list (abfd)) + { +- symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; +- symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); +- symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); +- amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); +- symtab_shndx_hdr->sh_size = amt; ++ symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; + +- off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, +- off, TRUE); ++ if (symtab_shndx_hdr != NULL && symtab_shndx_hdr->sh_name != 0) ++ { ++ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; ++ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); ++ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); ++ amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); ++ symtab_shndx_hdr->sh_size = amt; + +- if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 +- || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt)) +- return FALSE; ++ off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, ++ off, TRUE); ++ ++ if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 ++ || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt)) ++ return FALSE; ++ } + } + + symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,3 +1,11 @@ ++2017-04-04 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21342 ++ * elflink.c (_bfd_elf_define_linkage_sym): Prevent null pointer ++ dereference. ++ (bfd_elf_final_link): Only initialize the extended symbol index ++ section if there are extended symbol tables to list. ++ + 2016-08-02 Nick Clifton <nickc@redhat.com> + + PR ld/17739 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8393.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8393.patch new file mode 100644 index 0000000000..96fe9e34bd --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8393.patch @@ -0,0 +1,201 @@ +commit bce964aa6c777d236fbd641f2bc7bb931cfe4bf3 +Author: Alan Modra <amodra@gmail.com> +Date: Sun Apr 23 11:03:34 2017 +0930 + + PR 21412, get_reloc_section assumes .rel/.rela name for SHT_REL/RELA. + + This patch fixes an assumption made by code that runs for objcopy and + strip, that SHT_REL/SHR_RELA sections are always named starting with a + .rel/.rela prefix. I'm also modifying the interface for + elf_backend_get_reloc_section, so any backend function just needs to + handle name mapping. + + PR 21412 + * elf-bfd.h (struct elf_backend_data <get_reloc_section>): Change + parameters and comment. + (_bfd_elf_get_reloc_section): Delete. + (_bfd_elf_plt_get_reloc_section): Declare. + * elf.c (_bfd_elf_plt_get_reloc_section, elf_get_reloc_section): + New functions. Don't blindly skip over assumed .rel/.rela prefix. + Extracted from.. + (_bfd_elf_get_reloc_section): ..here. Delete. + (assign_section_numbers): Call elf_get_reloc_section. + * elf64-ppc.c (elf_backend_get_reloc_section): Define. + * elfxx-target.h (elf_backend_get_reloc_section): Update. + +Upstream-Status: Backport + +CVE: CVE-2017-8393 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/elf-bfd.h +=================================================================== +--- git.orig/bfd/elf-bfd.h 2017-09-04 17:43:22.156623008 +0530 ++++ git/bfd/elf-bfd.h 2017-09-04 17:43:33.836716941 +0530 +@@ -1298,8 +1298,10 @@ + bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec, + bfd_vma *code_off); + +- /* Return the section which RELOC_SEC applies to. */ +- asection *(*get_reloc_section) (asection *reloc_sec); ++ /* Given NAME, the name of a relocation section stripped of its ++ .rel/.rela prefix, return the section in ABFD to which the ++ relocations apply. */ ++ asection *(*get_reloc_section) (bfd *abfd, const char *name); + + /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which + has a type >= SHT_LOOS. Returns TRUE if the fields were initialised, +@@ -2358,7 +2360,7 @@ + extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *, + bfd_vma *); + +-extern asection *_bfd_elf_get_reloc_section (asection *); ++extern asection *_bfd_elf_plt_get_reloc_section (bfd *, const char *); + + extern int bfd_elf_get_default_section_type (flagword); + +Index: git/bfd/elf.c +=================================================================== +--- git.orig/bfd/elf.c 2017-09-04 17:43:33.780716491 +0530 ++++ git/bfd/elf.c 2017-09-04 17:43:33.836716941 +0530 +@@ -3493,17 +3493,39 @@ + H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc); + } + +-/* Return the section which RELOC_SEC applies to. */ ++/* Given NAME, the name of a relocation section stripped of its ++ .rel/.rela prefix, return the section in ABFD to which the ++ relocations apply. */ + + asection * +-_bfd_elf_get_reloc_section (asection *reloc_sec) ++_bfd_elf_plt_get_reloc_section (bfd *abfd, const char *name) ++{ ++ /* If a target needs .got.plt section, relocations in rela.plt/rel.plt ++ section likely apply to .got.plt or .got section. */ ++ if (get_elf_backend_data (abfd)->want_got_plt ++ && strcmp (name, ".plt") == 0) ++ { ++ asection *sec; ++ ++ name = ".got.plt"; ++ sec = bfd_get_section_by_name (abfd, name); ++ if (sec != NULL) ++ return sec; ++ name = ".got"; ++ } ++ ++ return bfd_get_section_by_name (abfd, name); ++} ++ ++/* Return the section to which RELOC_SEC applies. */ ++ ++static asection * ++elf_get_reloc_section (asection *reloc_sec) + { + const char *name; + unsigned int type; + bfd *abfd; +- +- if (reloc_sec == NULL) +- return NULL; ++ const struct elf_backend_data *bed; + + type = elf_section_data (reloc_sec)->this_hdr.sh_type; + if (type != SHT_REL && type != SHT_RELA) +@@ -3511,28 +3533,15 @@ + + /* We look up the section the relocs apply to by name. */ + name = reloc_sec->name; +- if (type == SHT_REL) +- name += 4; +- else +- name += 5; ++ if (strncmp (name, ".rel", 4) != 0) ++ return NULL; ++ name += 4; ++ if (type == SHT_RELA && *name++ != 'a') ++ return NULL; + +- /* If a target needs .got.plt section, relocations in rela.plt/rel.plt +- section apply to .got.plt section. */ + abfd = reloc_sec->owner; +- if (get_elf_backend_data (abfd)->want_got_plt +- && strcmp (name, ".plt") == 0) +- { +- /* .got.plt is a linker created input section. It may be mapped +- to some other output section. Try two likely sections. */ +- name = ".got.plt"; +- reloc_sec = bfd_get_section_by_name (abfd, name); +- if (reloc_sec != NULL) +- return reloc_sec; +- name = ".got"; +- } +- +- reloc_sec = bfd_get_section_by_name (abfd, name); +- return reloc_sec; ++ bed = get_elf_backend_data (abfd); ++ return bed->get_reloc_section (abfd, name); + } + + /* Assign all ELF section numbers. The dummy first section is handled here +@@ -3790,7 +3799,7 @@ + if (s != NULL) + d->this_hdr.sh_link = elf_section_data (s)->this_idx; + +- s = get_elf_backend_data (abfd)->get_reloc_section (sec); ++ s = elf_get_reloc_section (sec); + if (s != NULL) + { + d->this_hdr.sh_info = elf_section_data (s)->this_idx; +Index: git/bfd/elfxx-target.h +=================================================================== +--- git.orig/bfd/elfxx-target.h 2017-09-04 17:43:22.216623490 +0530 ++++ git/bfd/elfxx-target.h 2017-09-04 17:43:33.836716941 +0530 +@@ -686,7 +686,7 @@ + #endif + + #ifndef elf_backend_get_reloc_section +-#define elf_backend_get_reloc_section _bfd_elf_get_reloc_section ++#define elf_backend_get_reloc_section _bfd_elf_plt_get_reloc_section + #endif + + #ifndef elf_backend_copy_special_section_fields +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 17:43:33.780716491 +0530 ++++ git/bfd/ChangeLog 2017-09-04 17:45:58.349944078 +0530 +@@ -82,6 +82,21 @@ + + * readelf.c (process_mips_specific): Remove null GOT data check. + ++2017-04-23 Alan Modra <amodra@gmail.com> ++ ++ PR 21412 ++ * elf-bfd.h (struct elf_backend_data <get_reloc_section>): Change ++ parameters and comment. ++ (_bfd_elf_get_reloc_section): Delete. ++ (_bfd_elf_plt_get_reloc_section): Declare. ++ * elf.c (_bfd_elf_plt_get_reloc_section, elf_get_reloc_section): ++ New functions. Don't blindly skip over assumed .rel/.rela prefix. ++ Extracted from.. ++ (_bfd_elf_get_reloc_section): ..here. Delete. ++ (assign_section_numbers): Call elf_get_reloc_section. ++ * elf64-ppc.c (elf_backend_get_reloc_section): Define. ++ * elfxx-target.h (elf_backend_get_reloc_section): Update. ++ + 2017-04-13 Nick Clifton <nickc@redhat.com> + + PR binutils/21379 +Index: git/bfd/elf64-ppc.c +=================================================================== +--- git.orig/bfd/elf64-ppc.c 2017-09-04 17:43:22.200623362 +0530 ++++ git/bfd/elf64-ppc.c 2017-09-04 17:47:04.458511122 +0530 +@@ -117,6 +117,7 @@ + #define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook + #define elf_backend_special_sections ppc64_elf_special_sections + #define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute ++#define elf_backend_get_reloc_section bfd_get_section_by_name + + /* The name of the dynamic interpreter. This is put in the .interp + section. */ diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8394.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8394.patch new file mode 100644 index 0000000000..14ee1910f4 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8394.patch @@ -0,0 +1,114 @@ +commit 7eacd66b086cabb1daab20890d5481894d4f56b2 +Author: Alan Modra <amodra@gmail.com> +Date: Sun Apr 23 15:21:11 2017 +0930 + + PR 21414, null pointer deref of _bfd_elf_large_com_section sym + + PR 21414 + * section.c (GLOBAL_SYM_INIT): Make available in bfd.h. + * elf.c (lcomm_sym): New. + (_bfd_elf_large_com_section): Use lcomm_sym section symbol. + * bfd-in2.h: Regenerate. + +Upstream-Status: Backport + +CVE: CVE-2017-8394 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/bfd-in2.h +=================================================================== +--- git.orig/bfd/bfd-in2.h 2017-09-20 12:54:44.847475928 +0530 ++++ git/bfd/bfd-in2.h 2017-09-20 12:54:44.903476171 +0530 +@@ -1805,6 +1805,18 @@ + { NULL }, { NULL } \ + } + ++/* We use a macro to initialize the static asymbol structures because ++ traditional C does not permit us to initialize a union member while ++ gcc warns if we don't initialize it. ++ the_bfd, name, value, attr, section [, udata] */ ++#ifdef __STDC__ ++#define GLOBAL_SYM_INIT(NAME, SECTION) \ ++ { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }} ++#else ++#define GLOBAL_SYM_INIT(NAME, SECTION) \ ++ { 0, NAME, 0, BSF_SECTION_SYM, SECTION } ++#endif ++ + void bfd_section_list_clear (bfd *); + + asection *bfd_get_section_by_name (bfd *abfd, const char *name); +Index: git/bfd/section.c +=================================================================== +--- git.orig/bfd/section.c 2017-09-20 12:54:44.847475928 +0530 ++++ git/bfd/section.c 2017-09-20 12:54:44.903476171 +0530 +@@ -738,20 +738,20 @@ + . { NULL }, { NULL } \ + . } + . ++.{* We use a macro to initialize the static asymbol structures because ++. traditional C does not permit us to initialize a union member while ++. gcc warns if we don't initialize it. ++. the_bfd, name, value, attr, section [, udata] *} ++.#ifdef __STDC__ ++.#define GLOBAL_SYM_INIT(NAME, SECTION) \ ++. { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }} ++.#else ++.#define GLOBAL_SYM_INIT(NAME, SECTION) \ ++. { 0, NAME, 0, BSF_SECTION_SYM, SECTION } ++.#endif ++. + */ + +-/* We use a macro to initialize the static asymbol structures because +- traditional C does not permit us to initialize a union member while +- gcc warns if we don't initialize it. */ +- /* the_bfd, name, value, attr, section [, udata] */ +-#ifdef __STDC__ +-#define GLOBAL_SYM_INIT(NAME, SECTION) \ +- { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }} +-#else +-#define GLOBAL_SYM_INIT(NAME, SECTION) \ +- { 0, NAME, 0, BSF_SECTION_SYM, SECTION } +-#endif +- + /* These symbols are global, not specific to any BFD. Therefore, anything + that tries to change them is broken, and should be repaired. */ + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-20 12:54:44.735475444 +0530 ++++ git/bfd/ChangeLog 2017-09-20 12:54:44.903476171 +0530 +@@ -102,6 +102,14 @@ + * readelf.c (process_mips_specific): Remove null GOT data check. + + 2017-04-23 Alan Modra <amodra@gmail.com> ++ ++ PR 21414 ++ * section.c (GLOBAL_SYM_INIT): Make available in bfd.h. ++ * elf.c (lcomm_sym): New. ++ (_bfd_elf_large_com_section): Use lcomm_sym section symbol. ++ * bfd-in2.h: Regenerate. ++ ++2017-04-23 Alan Modra <amodra@gmail.com> + + PR 21412 + * elf-bfd.h (struct elf_backend_data <get_reloc_section>): Change +Index: git/bfd/elf.c +=================================================================== +--- git.orig/bfd/elf.c 2017-09-20 12:54:44.847475928 +0530 ++++ git/bfd/elf.c 2017-09-20 13:00:22.636091768 +0530 +@@ -10986,9 +10986,11 @@ + + /* It is only used by x86-64 so far. + ??? This repeats *COM* id of zero. sec->id is supposed to be unique, +- but current usage would allow all of _bfd_std_section to be zero. t*/ ++ but current usage would allow all of _bfd_std_section to be zero. */ ++static const asymbol lcomm_sym ++ = GLOBAL_SYM_INIT ("LARGE_COMMON", &_bfd_elf_large_com_section); + asection _bfd_elf_large_com_section +- = BFD_FAKE_SECTION (_bfd_elf_large_com_section, NULL, ++ = BFD_FAKE_SECTION (_bfd_elf_large_com_section, &lcomm_sym, + "LARGE_COMMON", 0, SEC_IS_COMMON); + + void diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8394_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8394_1.patch new file mode 100644 index 0000000000..e1dfd8bb40 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8394_1.patch @@ -0,0 +1,80 @@ +commit 821e6ff6299aa39e841ca50e1ae8a98e3554fd5f +Author: Alan Modra <amodra@gmail.com> +Date: Wed Oct 12 09:41:33 2016 +1030 + + BFD_FAKE_SECTION macro params + + Order NAME, IDX, FLAGS as per STD_SECTION macro. + + * section.c (BFD_FAKE_SECTION): Reorder parameters. Formatting. + (STD_SECTION): Adjust to suit. + * elf.c (_bfd_elf_large_com_section): Likewise. + * bfd-in2.h: Regenerate. + +Upstream-Status: Backport + +CVE: CVE-2017-8394 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + + +Index: git/bfd/bfd-in2.h +=================================================================== +--- git.orig/bfd/bfd-in2.h 2017-09-20 12:54:42.423465338 +0530 ++++ git/bfd/bfd-in2.h 2017-09-20 13:02:48.000000000 +0530 +@@ -1767,9 +1767,9 @@ + #define bfd_section_removed_from_list(ABFD, S) \ + ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) + +-#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ ++#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \ + /* name, id, index, next, prev, flags, user_set_vma, */ \ +- { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ ++ { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ + \ + /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ + 0, 0, 1, 0, \ +Index: git/bfd/elf.c +=================================================================== +--- git.orig/bfd/elf.c 2017-09-20 12:54:44.503474440 +0530 ++++ git/bfd/elf.c 2017-09-20 13:02:48.000000000 +0530 +@@ -10984,10 +10984,12 @@ + return n; + } + +-/* It is only used by x86-64 so far. */ ++/* It is only used by x86-64 so far. ++ ??? This repeats *COM* id of zero. sec->id is supposed to be unique, ++ but current usage would allow all of _bfd_std_section to be zero. t*/ + asection _bfd_elf_large_com_section +- = BFD_FAKE_SECTION (_bfd_elf_large_com_section, +- SEC_IS_COMMON, NULL, "LARGE_COMMON", 0); ++ = BFD_FAKE_SECTION (_bfd_elf_large_com_section, NULL, ++ "LARGE_COMMON", 0, SEC_IS_COMMON); + + void + _bfd_elf_post_process_headers (bfd * abfd, +Index: git/bfd/section.c +=================================================================== +--- git.orig/bfd/section.c 2017-09-20 12:54:43.815471454 +0530 ++++ git/bfd/section.c 2017-09-20 13:02:48.000000000 +0530 +@@ -700,9 +700,9 @@ + .#define bfd_section_removed_from_list(ABFD, S) \ + . ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) + . +-.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ ++.#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS) \ + . {* name, id, index, next, prev, flags, user_set_vma, *} \ +-. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ ++. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ + . \ + . {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \ + . 0, 0, 1, 0, \ +@@ -764,7 +764,7 @@ + }; + + #define STD_SECTION(NAME, IDX, FLAGS) \ +- BFD_FAKE_SECTION(_bfd_std_section[IDX], FLAGS, &global_syms[IDX], NAME, IDX) ++ BFD_FAKE_SECTION(_bfd_std_section[IDX], &global_syms[IDX], NAME, IDX, FLAGS) + + asection _bfd_std_section[] = { + STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON), diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8395.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8395.patch new file mode 100644 index 0000000000..42793e133b --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8395.patch @@ -0,0 +1,72 @@ +commit e63d123268f23a4cbc45ee55fb6dbc7d84729da3 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Apr 26 13:07:49 2017 +0100 + + Fix seg-fault attempting to compress a debug section in a corrupt binary. + + PR binutils/21431 + * compress.c (bfd_init_section_compress_status): Check the return + value from bfd_malloc. + +Upstream-Status: Backport + +CVE: CVE-2017-8395 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/compress.c +=================================================================== +--- git.orig/bfd/compress.c 2017-09-04 17:55:00.546577566 +0530 ++++ git/bfd/compress.c 2017-09-04 17:55:10.770664577 +0530 +@@ -534,7 +534,6 @@ + { + bfd_size_type uncompressed_size; + bfd_byte *uncompressed_buffer; +- bfd_boolean ret; + + /* Error if not opened for read. */ + if (abfd->direction != read_direction +@@ -550,18 +549,18 @@ + /* Read in the full section contents and compress it. */ + uncompressed_size = sec->size; + uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size); ++ /* PR 21431 */ ++ if (uncompressed_buffer == NULL) ++ return FALSE; ++ + if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer, + 0, uncompressed_size)) +- ret = FALSE; +- else +- { +- uncompressed_size = bfd_compress_section_contents (abfd, sec, +- uncompressed_buffer, +- uncompressed_size); +- ret = uncompressed_size != 0; +- } ++ return FALSE; + +- return ret; ++ uncompressed_size = bfd_compress_section_contents (abfd, sec, ++ uncompressed_buffer, ++ uncompressed_size); ++ return uncompressed_size != 0; + } + + /* +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 17:55:10.714664101 +0530 ++++ git/bfd/ChangeLog 2017-09-04 17:56:40.991431847 +0530 +@@ -73,6 +73,12 @@ + (evax_bfd_print_egsd): Check for an overlarge record length. + (evax_bfd_print_etir): Likewise. + ++2017-04-26 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21431 ++ * compress.c (bfd_init_section_compress_status): Check the return ++ value from bfd_malloc. ++ + 2017-04-25 Maciej W. Rozycki <macro@imgtec.com> + + * readelf.c (process_mips_specific): Remove error reporting from diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8396.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8396.patch new file mode 100644 index 0000000000..b1bf92f4dd --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8396.patch @@ -0,0 +1,102 @@ +commit a941291cab71b9ac356e1c03968c177c03e602ab +Author: Alan Modra <amodra@gmail.com> +Date: Sat Apr 29 14:48:16 2017 +0930 + + PR21432, buffer overflow in perform_relocation + + The existing reloc offset range tests didn't catch small negative + offsets less than the size of the reloc field. + + PR 21432 + * reloc.c (reloc_offset_in_range): New function. + (bfd_perform_relocation, bfd_install_relocation): Use it. + (_bfd_final_link_relocate): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-8396 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/reloc.c +=================================================================== +--- git.orig/bfd/reloc.c 2017-09-05 18:12:07.448886623 +0530 ++++ git/bfd/reloc.c 2017-09-05 18:12:07.564887511 +0530 +@@ -538,6 +538,22 @@ + return flag; + } + ++/* HOWTO describes a relocation, at offset OCTET. Return whether the ++ relocation field is within SECTION of ABFD. */ ++ ++static bfd_boolean ++reloc_offset_in_range (reloc_howto_type *howto, bfd *abfd, ++ asection *section, bfd_size_type octet) ++{ ++ bfd_size_type octet_end = bfd_get_section_limit_octets (abfd, section); ++ bfd_size_type reloc_size = bfd_get_reloc_size (howto); ++ ++ /* The reloc field must be contained entirely within the section. ++ Allow zero length fields (marker relocs or NONE relocs where no ++ relocation will be performed) at the end of the section. */ ++ return octet <= octet_end && octet + reloc_size <= octet_end; ++} ++ + /* + FUNCTION + bfd_perform_relocation +@@ -618,15 +634,9 @@ + return cont; + } + +- /* Is the address of the relocation really within the section? +- Include the size of the reloc in the test for out of range addresses. +- PR 17512: file: c146ab8b, 46dff27f, 38e53ebf. */ ++ /* Is the address of the relocation really within the section? */ + octets = reloc_entry->address * bfd_octets_per_byte (abfd); +- if (octets + bfd_get_reloc_size (howto) +- > bfd_get_section_limit_octets (abfd, input_section) +- /* Check for an overly large offset which +- masquerades as a negative value too. */ +- || (octets + bfd_get_reloc_size (howto) < bfd_get_reloc_size (howto))) ++ if (!reloc_offset_in_range (howto, abfd, input_section, octets)) + return bfd_reloc_outofrange; + + /* Work out which section the relocation is targeted at and the +@@ -1010,8 +1020,7 @@ + + /* Is the address of the relocation really within the section? */ + octets = reloc_entry->address * bfd_octets_per_byte (abfd); +- if (octets + bfd_get_reloc_size (howto) +- > bfd_get_section_limit_octets (abfd, input_section)) ++ if (!reloc_offset_in_range (howto, abfd, input_section, octets)) + return bfd_reloc_outofrange; + + /* Work out which section the relocation is targeted at and the +@@ -1349,8 +1358,7 @@ + bfd_size_type octets = address * bfd_octets_per_byte (input_bfd); + + /* Sanity check the address. */ +- if (octets + bfd_get_reloc_size (howto) +- > bfd_get_section_limit_octets (input_bfd, input_section)) ++ if (!reloc_offset_in_range (howto, input_bfd, input_section, octets)) + return bfd_reloc_outofrange; + + /* This function assumes that we are dealing with a basic relocation +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-05 18:12:07.448886623 +0530 ++++ git/bfd/ChangeLog 2017-09-05 18:13:46.745645897 +0530 +@@ -73,6 +73,13 @@ + (evax_bfd_print_egsd): Check for an overlarge record length. + (evax_bfd_print_etir): Likewise. + ++2017-04-29 Alan Modra <amodra@gmail.com> ++ ++ PR 21432 ++ * reloc.c (reloc_offset_in_range): New function. ++ (bfd_perform_relocation, bfd_install_relocation): Use it. ++ (_bfd_final_link_relocate): Likewise. ++ + 2017-04-26 Nick Clifton <nickc@redhat.com> + + PR binutils/21434 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8397.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8397.patch new file mode 100644 index 0000000000..f966c80c4e --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8397.patch @@ -0,0 +1,50 @@ +commit 04b31182bf3f8a1a76e995bdfaaaab4c009b9cb2 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Apr 26 16:30:22 2017 +0100 + + Fix a seg-fault when processing a corrupt binary containing reloc(s) with negative addresses. + + PR binutils/21434 + * reloc.c (bfd_perform_relocation): Check for a negative address + in the reloc. + +Upstream-Status: Backport + +CVE: CVE-2017-8397 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + + + +Index: git/bfd/reloc.c +=================================================================== +--- git.orig/bfd/reloc.c 2017-09-04 18:06:00.651987605 +0530 ++++ git/bfd/reloc.c 2017-09-04 18:06:10.740066291 +0530 +@@ -623,7 +623,10 @@ + PR 17512: file: c146ab8b, 46dff27f, 38e53ebf. */ + octets = reloc_entry->address * bfd_octets_per_byte (abfd); + if (octets + bfd_get_reloc_size (howto) +- > bfd_get_section_limit_octets (abfd, input_section)) ++ > bfd_get_section_limit_octets (abfd, input_section) ++ /* Check for an overly large offset which ++ masquerades as a negative value too. */ ++ || (octets + bfd_get_reloc_size (howto) < bfd_get_reloc_size (howto))) + return bfd_reloc_outofrange; + + /* Work out which section the relocation is targeted at and the +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-04 18:06:10.684065855 +0530 ++++ git/bfd/ChangeLog 2017-09-04 18:08:33.845183050 +0530 +@@ -75,6 +75,12 @@ + + 2017-04-26 Nick Clifton <nickc@redhat.com> + ++ PR binutils/21434 ++ * reloc.c (bfd_perform_relocation): Check for a negative address ++ in the reloc. ++ ++2017-04-26 Nick Clifton <nickc@redhat.com> ++ + PR binutils/21431 + * compress.c (bfd_init_section_compress_status): Check the return + value from bfd_malloc. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch new file mode 100644 index 0000000000..23d5085b16 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch @@ -0,0 +1,147 @@ +commit d949ff5607b9f595e0eed2ff15fbe5eb84eb3a34 +Author: Nick Clifton <nickc@redhat.com> +Date: Fri Apr 28 10:28:04 2017 +0100 + + Fix heap-buffer overflow bugs caused when dumping debug information from a corrupt binary. + + PR binutils/21438 + * dwarf.c (process_extended_line_op): Do not assume that the + string extracted from the section is NUL terminated. + (fetch_indirect_string): If the string retrieved from the section + is not NUL terminated, return an error message. + (fetch_indirect_line_string): Likewise. + (fetch_indexed_string): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-8398 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/binutils/dwarf.c +=================================================================== +--- git.orig/binutils/dwarf.c 2017-09-20 13:40:17.148898512 +0530 ++++ git/binutils/dwarf.c 2017-09-20 13:45:17.564730907 +0530 +@@ -472,15 +472,20 @@ + printf (_(" Entry\tDir\tTime\tSize\tName\n")); + printf (" %d\t", ++state_machine_regs.last_file_entry); + +- name = data; +- data += strnlen ((char *) data, end - data) + 1; +- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); +- data += bytes_read; +- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); +- data += bytes_read; +- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); +- data += bytes_read; +- printf ("%s\n\n", name); ++ { ++ size_t l; ++ ++ name = data; ++ l = strnlen ((char *) data, end - data); ++ data += len + 1; ++ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); ++ data += bytes_read; ++ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); ++ data += bytes_read; ++ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); ++ data += bytes_read; ++ printf ("%.*s\n\n", (int) l, name); ++ } + + if (((unsigned int) (data - orig_data) != len) || data == end) + warn (_("DW_LNE_define_file: Bad opcode length\n")); +@@ -597,18 +602,28 @@ + fetch_indirect_string (dwarf_vma offset) + { + struct dwarf_section *section = &debug_displays [str].section; ++ const unsigned char * ret; + + if (section->start == NULL) + return (const unsigned char *) _("<no .debug_str section>"); + +- if (offset > section->size) ++ if (offset >= section->size) + { + warn (_("DW_FORM_strp offset too big: %s\n"), + dwarf_vmatoa ("x", offset)); + return (const unsigned char *) _("<offset is too big>"); + } + +- return (const unsigned char *) section->start + offset; ++ ret = section->start + offset; ++ /* Unfortunately we cannot rely upon the .debug_str section ending with a ++ NUL byte. Since our caller is expecting to receive a well formed C ++ string we test for the lack of a terminating byte here. */ ++ if (strnlen ((const char *) ret, section->size - offset) ++ == section->size - offset) ++ ret = (const unsigned char *) ++ _("<no NUL byte at end of .debug_str section>"); ++ ++ return ret; + } + + static const char * +@@ -621,6 +636,7 @@ + struct dwarf_section *str_section = &debug_displays [str_sec_idx].section; + dwarf_vma index_offset = idx * offset_size; + dwarf_vma str_offset; ++ const char * ret; + + if (index_section->start == NULL) + return (dwo ? _("<no .debug_str_offsets.dwo section>") +@@ -628,7 +644,7 @@ + + if (this_set != NULL) + index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS]; +- if (index_offset > index_section->size) ++ if (index_offset >= index_section->size) + { + warn (_("DW_FORM_GNU_str_index offset too big: %s\n"), + dwarf_vmatoa ("x", index_offset)); +@@ -641,14 +657,22 @@ + + str_offset = byte_get (index_section->start + index_offset, offset_size); + str_offset -= str_section->address; +- if (str_offset > str_section->size) ++ if (str_offset >= str_section->size) + { + warn (_("DW_FORM_GNU_str_index indirect offset too big: %s\n"), + dwarf_vmatoa ("x", str_offset)); + return _("<indirect index offset is too big>"); + } + +- return (const char *) str_section->start + str_offset; ++ ret = (const char *) str_section->start + str_offset; ++ /* Unfortunately we cannot rely upon str_section ending with a NUL byte. ++ Since our caller is expecting to receive a well formed C string we test ++ for the lack of a terminating byte here. */ ++ if (strnlen (ret, str_section->size - str_offset) ++ == str_section->size - str_offset) ++ ret = (const char *) _("<no NUL byte at end of section>"); ++ ++ return ret; + } + + static const char * +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-09-20 13:40:18.900898599 +0530 ++++ git/binutils/ChangeLog 2017-09-20 13:48:02.976503560 +0530 +@@ -10,6 +10,16 @@ + * objdump.c (dump_relocs_in_section): Check for an excessive + number of relocs before attempting to dump them. + ++2017-04-28 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21438 ++ * dwarf.c (process_extended_line_op): Do not assume that the ++ string extracted from the section is NUL terminated. ++ (fetch_indirect_string): If the string retrieved from the section ++ is not NUL terminated, return an error message. ++ (fetch_indirect_line_string): Likewise. ++ (fetch_indexed_string): Likewise. ++ + 2017-02-14 Nick Clifton <nickc@redhat.com> + + PR binutils/21157 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8421.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8421.patch new file mode 100644 index 0000000000..da6e475828 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8421.patch @@ -0,0 +1,51 @@ +commit 39ff1b79f687b65f4144ddb379f22587003443fb +Author: Nick Clifton <nickc@redhat.com> +Date: Tue May 2 11:54:53 2017 +0100 + + Prevent memory exhaustion from a corrupt PE binary with an overlarge number of relocs. + + PR 21440 + * objdump.c (dump_relocs_in_section): Check for an excessive + number of relocs before attempting to dump them. + +Upstream-Status: Backport + +CVE: CVE-2017-8421 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-05 11:34:23.140802515 +0530 ++++ git/binutils/objdump.c 2017-09-05 11:34:28.716824776 +0530 +@@ -3238,6 +3238,14 @@ + return; + } + ++ if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0 ++ && relsize > get_file_size (bfd_get_filename (abfd))) ++ { ++ printf (" (too many: 0x%x)\n", section->reloc_count); ++ bfd_set_error (bfd_error_file_truncated); ++ bfd_fatal (bfd_get_filename (abfd)); ++ } ++ + relpp = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); + +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-09-05 11:34:28.040822070 +0530 ++++ git/binutils/ChangeLog 2017-09-05 11:36:02.413217129 +0530 +@@ -4,6 +4,12 @@ + * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty + string whilst concatenating symbol names. + ++2017-05-02 Nick Clifton <nickc@redhat.com> ++ ++ PR 21440 ++ * objdump.c (dump_relocs_in_section): Check for an excessive ++ number of relocs before attempting to dump them. ++ + 2017-02-14 Nick Clifton <nickc@redhat.com> + + PR binutils/21157 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9038.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9038.patch new file mode 100644 index 0000000000..afc14d1e14 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9038.patch @@ -0,0 +1,51 @@ +From f32ba72991d2406b21ab17edc234a2f3fa7fb23d Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Mon, 3 Apr 2017 11:01:45 +0100 +Subject: [PATCH] readelf: Update check for invalid word offsets in ARM unwind + information. + + PR binutils/21343 + * readelf.c (get_unwind_section_word): Fix snafu checking for + invalid word offsets in ARM unwind information. + +Upstream-Status: Backport +CVE: CVE-2017-9039 +Affects: binutils <= 2.28 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 6 ++++++ + binutils/readelf.c | 6 +++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -7745,9 +7745,9 @@ get_unwind_section_word (struct arm_unw_ + return FALSE; + + /* If the offset is invalid then fail. */ +- if (word_offset > (sec->sh_size - 4) +- /* PR 18879 */ +- || (sec->sh_size < 5 && word_offset >= sec->sh_size) ++ if (/* PR 21343 *//* PR 18879 */ ++ sec->sh_size < 4 ++ || word_offset > (sec->sh_size - 4) + || ((bfd_signed_vma) word_offset) < 0) + return FALSE; + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,3 +1,9 @@ ++2017-04-03 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21343 ++ * readelf.c (get_unwind_section_word): Fix snafu checking for ++ invalid word offsets in ARM unwind information. ++ + 2017-04-04 Nick Clifton <nickc@redhat.com> + + PR binutils/21342 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9039.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9039.patch new file mode 100644 index 0000000000..41f2b6e316 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9039.patch @@ -0,0 +1,72 @@ +From 75ec1fdbb797a389e4fe4aaf2e15358a070dcc19 Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Mon, 3 Apr 2017 11:13:21 +0100 +Subject: [PATCH] Fix runtime seg-fault in readelf when parsing a corrupt MIPS + binary. + + PR binutils/21344 + * readelf.c (process_mips_specific): Check for an out of range GOT + entry before reading the module pointer. + +Upstream-Status: Backport +CVE: CVE-2017-9039 supporting patch +VER: <= 2.28 +Signed-off-by: Armin kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 6 ++++++ + binutils/readelf.c | 26 ++++++++++++++++++-------- + 2 files changed, 24 insertions(+), 8 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -14987,14 +14987,24 @@ process_mips_specific (FILE * file) + printf (_(" Lazy resolver\n")); + if (ent == (bfd_vma) -1) + goto got_print_fail; +- if (data +- && (byte_get (data + ent - pltgot, addr_size) +- >> (addr_size * 8 - 1)) != 0) ++ ++ if (data) + { +- ent = print_mips_got_entry (data, pltgot, ent, data_end); +- printf (_(" Module pointer (GNU extension)\n")); +- if (ent == (bfd_vma) -1) +- goto got_print_fail; ++ /* PR 21344 */ ++ if (data + ent - pltgot > data_end - addr_size) ++ { ++ error (_("Invalid got entry - %#lx - overflows GOT table\n"), ent); ++ goto got_print_fail; ++ } ++ ++ if (byte_get (data + ent - pltgot, addr_size) ++ >> (addr_size * 8 - 1) != 0) ++ { ++ ent = print_mips_got_entry (data, pltgot, ent, data_end); ++ printf (_(" Module pointer (GNU extension)\n")); ++ if (ent == (bfd_vma) -1) ++ goto got_print_fail; ++ } + } + printf ("\n"); + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,5 +1,11 @@ + 2017-04-03 Nick Clifton <nickc@redhat.com> + ++ PR binutils/21344 ++ * readelf.c (process_mips_specific): Check for an out of range GOT ++ entry before reading the module pointer. ++ ++2017-04-03 Nick Clifton <nickc@redhat.com> ++ + PR binutils/21343 + * readelf.c (get_unwind_section_word): Fix snafu checking for + invalid word offsets in ARM unwind information. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9039_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9039_1.patch new file mode 100644 index 0000000000..ee827ee3e7 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9039_1.patch @@ -0,0 +1,56 @@ +From 82156ab704b08b124d319c0decdbd48b3ca2dac5 Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Mon, 3 Apr 2017 12:14:06 +0100 +Subject: [PATCH] readelf: Fix overlarge memory allocation when reading a + binary with an excessive number of program headers. + + PR binutils/21345 + * readelf.c (get_program_headers): Check for there being too many + program headers before attempting to allocate space for them. + +Upstream-Status: Backport +CVE: CVE-2017-9039 +VER: <= 2.28 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 6 ++++++ + binutils/readelf.c | 17 ++++++++++++++--- + 2 files changed, 20 insertions(+), 3 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -4705,9 +4705,19 @@ get_program_headers (FILE * file) + if (program_headers != NULL) + return 1; + +- phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum, +- sizeof (Elf_Internal_Phdr)); ++ /* Be kind to memory checkers by looking for ++ e_phnum values which we know must be invalid. */ ++ if (elf_header.e_phnum ++ * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr)) ++ >= current_file_size) ++ { ++ error (_("Too many program headers - %#x - the file is not that big\n"), ++ elf_header.e_phnum); ++ return FALSE; ++ } + ++ phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum, ++ sizeof (Elf_Internal_Phdr)); + if (phdrs == NULL) + { + error (_("Out of memory reading %u program headers\n"), +@@ -14993,7 +15003,8 @@ process_mips_specific (FILE * file) + /* PR 21344 */ + if (data + ent - pltgot > data_end - addr_size) + { +- error (_("Invalid got entry - %#lx - overflows GOT table\n"), ent); ++ error (_("Invalid got entry - %#lx - overflows GOT table\n"), ++ (long) ent); + goto got_print_fail; + } + diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9040_and_9042.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9040_and_9042.patch new file mode 100644 index 0000000000..d5089035e1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9040_and_9042.patch @@ -0,0 +1,83 @@ +From 7296a62a2a237f6b1ad8db8c38b090e9f592c8cf Mon Sep 17 00:00:00 2001 +From: Nick Clifton <nickc@redhat.com> +Date: Thu, 13 Apr 2017 16:06:30 +0100 +Subject: [PATCH] readelf: fix out of range subtraction, seg fault from a NULL + pointer and memory exhaustion, all from parsing corrupt binaries. + + PR binutils/21379 + * readelf.c (process_dynamic_section): Detect over large section + offsets in the DT_SYMTAB entry. + + PR binutils/21345 + * readelf.c (process_mips_specific): Catch an unfeasible memory + allocation before it happens and print a suitable error message. + +Upstream-Status: Backport + +did not include all the commit as affect code does not exists. it does contain the two +fixes above. +both cve's fixed by same comit. + +CVE: CVE-2017-9040 +CVE: CVE-2017-9042 +VER: <= 2.28 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 12 ++++++++++++ + binutils/readelf.c | 26 +++++++++++++++++++++----- + 2 files changed, 33 insertions(+), 5 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -9079,6 +9079,12 @@ process_dynamic_section (FILE * file) + processing that. This is overkill, I know, but it + should work. */ + section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0); ++ if ((bfd_size_type) section.sh_offset > current_file_size) ++ { ++ /* See PR 21379 for a reproducer. */ ++ error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset); ++ return FALSE; ++ } + + if (archive_file_offset != 0) + section.sh_size = archive_file_size - section.sh_offset; +@@ -14882,6 +14888,15 @@ process_mips_specific (FILE * file) + return 0; + } + ++ /* PR 21345 - print a slightly more helpful error message ++ if we are sure that the cmalloc will fail. */ ++ if (conflictsno * sizeof (* iconf) > current_file_size) ++ { ++ error (_("Overlarge number of conflicts detected: %lx\n"), ++ (long) conflictsno); ++ return FALSE; ++ } ++ + iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf)); + if (iconf == NULL) + { +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,3 +1,15 @@ ++2017-04-13 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21379 ++ * readelf.c (process_dynamic_section): Detect over large section ++ offsets in the DT_SYMTAB entry. ++ ++2017-04-13 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21345 ++ * readelf.c (process_mips_specific): Catch an unfeasible memory ++ allocation before it happens and print a suitable error message. ++ + 2017-04-03 Nick Clifton <nickc@redhat.com> + + PR binutils/21345 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_1.patch new file mode 100644 index 0000000000..857cd4af91 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_1.patch @@ -0,0 +1,51 @@ +From 919383ac718c2a3187ee2a9ad659daa22da26258 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@imgtec.com> +Date: Wed, 12 Apr 2017 00:02:13 +0100 +Subject: [PATCH] MIPS/readelf: Remove extraneous null GOT data check + +Null data is handled gracefully throughout in MIPS GOT processing, with +addresses printed normally and unavailable data shown as `<unknown>' by +`print_mips_got_entry', and special processing code for GOT[1] doing an +explicit check. Remove an unwanted null GOT data check then, introduced +with commit 592458412fb2 in the course of addressing PR binutils/12855. + + binutils/ + * readelf.c (process_mips_specific): Remove null GOT data check. + +Upstream-Status: Backport +CVE: CVE-2017-9041 patch #1 +VER: <= 2.28 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 4 ++++ + binutils/readelf.c | 3 +-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -14995,8 +14995,8 @@ process_mips_specific (FILE * file) + data = (unsigned char *) get_data (NULL, file, offset, + global_end - pltgot, 1, + _("Global Offset Table data")); +- if (data == NULL) +- return 0; ++ ++ /* PR 12855: Null data is handled gracefully throughout. */ + data_end = data + (global_end - pltgot); + + printf (_("\nPrimary GOT:\n")); +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,3 +1,7 @@ ++2017-04-25 Maciej W. Rozycki <macro@imgtec.com> ++ ++ * readelf.c (process_mips_specific): Remove null GOT data check. ++ + 2017-04-13 Nick Clifton <nickc@redhat.com> + + PR binutils/21379 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_2.patch new file mode 100644 index 0000000000..9c3cb8ca25 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9041_2.patch @@ -0,0 +1,84 @@ +From c4ab9505b53cdc899506ed421fddb7e1f8faf7a3 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" <macro@imgtec.com> +Date: Wed, 12 Apr 2017 00:03:41 +0100 +Subject: [PATCH] MIPS/readelf: Simplify GOT[1] data availability check + +Unavailable data is handled gracefully in MIPS GOT processing done by +`print_mips_got_entry', so all that is needed in special GOT[1] handling +is to verify whether data can be retrieved for the purpose of the GNU +marker check done with `byte_get'. Remove the extra error reporting +code then, introduced with commit 75ec1fdbb797 ("Fix runtime seg-fault +in readelf when parsing a corrupt MIPS binary.") in the course of +addressing PR binutils/21344, and defer the error case to regular local +GOT entry processing. + + binutils/ + * readelf.c (process_mips_specific): Remove error reporting from + GOT[1] processing. + +Upstream-Status: Backport +CVE: CVE-2017-9041 +VER: <= 2.28 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + binutils/ChangeLog | 5 +++++ + binutils/readelf.c | 32 ++++++++++++++------------------ + 2 files changed, 19 insertions(+), 18 deletions(-) + +Index: git/binutils/readelf.c +=================================================================== +--- git.orig/binutils/readelf.c ++++ git/binutils/readelf.c +@@ -15013,24 +15013,20 @@ process_mips_specific (FILE * file) + if (ent == (bfd_vma) -1) + goto got_print_fail; + +- if (data) ++ /* Check for the MSB of GOT[1] being set, denoting a GNU object. ++ This entry will be used by some runtime loaders, to store the ++ module pointer. Otherwise this is an ordinary local entry. ++ PR 21344: Check for the entry being fully available before ++ fetching it. */ ++ if (data ++ && data + ent - pltgot + addr_size <= data_end ++ && (byte_get (data + ent - pltgot, addr_size) ++ >> (addr_size * 8 - 1)) != 0) + { +- /* PR 21344 */ +- if (data + ent - pltgot > data_end - addr_size) +- { +- error (_("Invalid got entry - %#lx - overflows GOT table\n"), +- (long) ent); +- goto got_print_fail; +- } +- +- if (byte_get (data + ent - pltgot, addr_size) +- >> (addr_size * 8 - 1) != 0) +- { +- ent = print_mips_got_entry (data, pltgot, ent, data_end); +- printf (_(" Module pointer (GNU extension)\n")); +- if (ent == (bfd_vma) -1) +- goto got_print_fail; +- } ++ ent = print_mips_got_entry (data, pltgot, ent, data_end); ++ printf (_(" Module pointer (GNU extension)\n")); ++ if (ent == (bfd_vma) -1) ++ goto got_print_fail; + } + printf ("\n"); + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog ++++ git/bfd/ChangeLog +@@ -1,4 +1,9 @@ + 2017-04-25 Maciej W. Rozycki <macro@imgtec.com> ++ ++ * readelf.c (process_mips_specific): Remove error reporting from ++ GOT[1] processing. ++ ++2017-04-25 Maciej W. Rozycki <macro@imgtec.com> + + * readelf.c (process_mips_specific): Remove null GOT data check. + diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9745.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9745.patch new file mode 100644 index 0000000000..b80226f412 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9745.patch @@ -0,0 +1,62 @@ +commit 76800cba595efc3fe95a446c2d664e42ae4ee869 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 12:08:57 2017 +0100 + + Handle EITR records in VMS Alpha binaries with overlarge command length parameters. + + PR binutils/21579 + * vms-alpha.c (_bfd_vms_slurp_etir): Extend check of cmd_length. + +Upstream-Status: CVE-2017-9745 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-09-21 16:08:57.863375204 +0530 ++++ git/bfd/vms-alpha.c 2017-09-21 16:08:58.211377888 +0530 +@@ -1801,14 +1801,8 @@ + + ptr += 4; + +-#if VMS_DEBUG +- _bfd_vms_debug (4, "etir: %s(%d)\n", +- _bfd_vms_etir_name (cmd), cmd); +- _bfd_hexdump (8, ptr, cmd_length - 4, 0); +-#endif +- +- /* PR 21589: Check for a corrupt ETIR record. */ +- if (cmd_length < 4) ++ /* PR 21589 and 21579: Check for a corrupt ETIR record. */ ++ if (cmd_length < 4 || (ptr + cmd_length > maxptr + 4)) + { + corrupt_etir: + _bfd_error_handler (_("Corrupt ETIR record encountered")); +@@ -1816,6 +1810,12 @@ + return FALSE; + } + ++#if VMS_DEBUG ++ _bfd_vms_debug (4, "etir: %s(%d)\n", ++ _bfd_vms_etir_name (cmd), cmd); ++ _bfd_hexdump (8, ptr, cmd_length - 4, 0); ++#endif ++ + switch (cmd) + { + /* Stack global +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 16:08:57.927375697 +0530 ++++ git/bfd/ChangeLog 2017-09-21 16:11:35.192613756 +0530 +@@ -81,6 +81,11 @@ + PR binutils/21581 + (ieee_archive_p): Likewise. + ++2017-06-15 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21579 ++ * vms-alpha.c (_bfd_vms_slurp_etir): Extend check of cmd_length. ++ + 2017-06-14 Nick Clifton <nickc@redhat.com> + + PR binutils/21589 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9746.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9746.patch new file mode 100644 index 0000000000..e9efb7b89a --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9746.patch @@ -0,0 +1,88 @@ +commit ae87f7e73eba29bd38b3a9684a10b948ed715612 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jun 14 16:50:03 2017 +0100 + + Fix address violation when disassembling a corrupt binary. + + PR binutils/21580 + binutils * objdump.c (disassemble_bytes): Check for buffer overrun when + printing out rae insns. + + ld * testsuite/ld-nds32/diff.d: Adjust expected output. + +Upstream-Status: Backport + +CVE: CVE-2017-9746 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + + +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-21 13:54:00.187228032 +0530 ++++ git/binutils/objdump.c 2017-09-21 13:54:00.659231783 +0530 +@@ -1780,20 +1780,23 @@ + + for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc) + { +- int k; +- +- if (bpc > 1 && inf->display_endian == BFD_ENDIAN_LITTLE) +- { +- for (k = bpc - 1; k >= 0; k--) +- printf ("%02x", (unsigned) data[j + k]); +- putchar (' '); +- } +- else ++ /* PR 21580: Check for a buffer ending early. */ ++ if (j + bpc <= stop_offset * opb) + { +- for (k = 0; k < bpc; k++) +- printf ("%02x", (unsigned) data[j + k]); +- putchar (' '); ++ int k; ++ ++ if (inf->display_endian == BFD_ENDIAN_LITTLE) ++ { ++ for (k = bpc - 1; k >= 0; k--) ++ printf ("%02x", (unsigned) data[j + k]); ++ } ++ else ++ { ++ for (k = 0; k < bpc; k++) ++ printf ("%02x", (unsigned) data[j + k]); ++ } + } ++ putchar (' '); + } + + for (; pb < octets_per_line; pb += bpc) +Index: git/ld/testsuite/ld-nds32/diff.d +=================================================================== +--- git.orig/ld/testsuite/ld-nds32/diff.d 2017-09-21 13:53:52.395166097 +0530 ++++ git/ld/testsuite/ld-nds32/diff.d 2017-09-21 13:54:00.659231783 +0530 +@@ -7,9 +7,9 @@ + + Disassembly of section .data: + 00008000 <WORD> (7e 00 00 00|00 00 00 7e).* +-00008004 <HALF> (7e 00 7e fe|00 7e 7e fe).* +-00008006 <BYTE> 7e fe 00 fe.* +-00008007 <ULEB128> fe 00.* ++00008004 <HALF> (7e 00|00 7e).* ++00008006 <BYTE> 7e.* ++00008007 <ULEB128> fe.* + ... + 00008009 <ULEB128_2> fe 00.* + .* +Index: git/ld/ChangeLog +=================================================================== +--- git.orig/ld/ChangeLog 2017-09-21 13:53:59.611223454 +0530 ++++ git/ld/ChangeLog 2017-09-21 14:01:12.294643335 +0530 +@@ -1,3 +1,8 @@ ++2017-06-14 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21580 ++ * testsuite/ld-nds32/diff.d: Adjust expected output. ++ + 2016-12-05 Nick Clifton <nickc@redhat.com> + + PR ld/20906 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9747.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9747.patch new file mode 100644 index 0000000000..ee663b816e --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9747.patch @@ -0,0 +1,40 @@ +commit 62b76e4b6e0b4cb5b3e0053d1de4097b32577049 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 13:08:47 2017 +0100 + + Fix address violation parsing a corrupt ieee binary. + + PR binutils/21581 + (ieee_archive_p): Use a static buffer to avoid compiler bugs. + +Upstream-Status: Backport + +CVE: CVE-2017-9747 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ieee.c +=================================================================== +--- git.orig/bfd/ieee.c 2017-09-21 14:37:12.152903139 +0530 ++++ git/bfd/ieee.c 2017-09-21 14:37:12.208903477 +0530 +@@ -1353,7 +1353,7 @@ + { + char *library; + unsigned int i; +- unsigned char buffer[512]; ++ static unsigned char buffer[512]; + file_ptr buffer_offset = 0; + ieee_ar_data_type *save = abfd->tdata.ieee_ar_data; + ieee_ar_data_type *ieee; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 14:37:12.152903139 +0530 ++++ git/bfd/ChangeLog 2017-09-21 14:45:57.020150977 +0530 +@@ -78,6 +78,8 @@ + PR binutils/21582 + * ieee.c (ieee_object_p): Use a static buffer to avoid compiler + bugs. ++ PR binutils/21581 ++ (ieee_archive_p): Likewise. + + 2017-04-29 Alan Modra <amodra@gmail.com> + diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9748.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9748.patch new file mode 100644 index 0000000000..ea1f0dd62b --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9748.patch @@ -0,0 +1,45 @@ +commit 63634bb4a107877dd08b6282e28e11cfd1a1649e +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 12:44:23 2017 +0100 + + Avoid a possible compiler bug by using a static buffer instead of a stack local buffer. + + PR binutils/21582 + * ieee.c (ieee_object_p): Use a static buffer to avoid compiler + bugs. + +Upstream-Status: Backport + +CVE: CVE-2017-9748 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/ieee.c +=================================================================== +--- git.orig/bfd/ieee.c 2017-09-21 13:53:50.891154141 +0530 ++++ git/bfd/ieee.c 2017-09-21 13:54:00.715232229 +0530 +@@ -1871,7 +1871,7 @@ + char *processor; + unsigned int part; + ieee_data_type *ieee; +- unsigned char buffer[300]; ++ static unsigned char buffer[300]; + ieee_data_type *save = IEEE_DATA (abfd); + bfd_size_type amt; + +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 13:54:00.483230385 +0530 ++++ git/bfd/ChangeLog 2017-09-21 13:57:44.885008549 +0530 +@@ -73,6 +73,12 @@ + (evax_bfd_print_egsd): Check for an overlarge record length. + (evax_bfd_print_etir): Likewise. + ++2017-06-15 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21582 ++ * ieee.c (ieee_object_p): Use a static buffer to avoid compiler ++ bugs. ++ + 2017-04-29 Alan Modra <amodra@gmail.com> + + PR 21432 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9749.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9749.patch new file mode 100644 index 0000000000..a033d3dce6 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9749.patch @@ -0,0 +1,75 @@ +commit 08c7881b814c546efc3996fd1decdf0877f7a779 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 11:52:02 2017 +0100 + + Prevent invalid array accesses when disassembling a corrupt bfin binary. + + PR binutils/21586 + * bfin-dis.c (gregs): Clip index to prevent overflow. + (regs): Likewise. + (regs_lo): Likewise. + (regs_hi): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-9749 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/opcodes/bfin-dis.c +=================================================================== +--- git.orig/opcodes/bfin-dis.c 2017-09-21 13:53:52.667168259 +0530 ++++ git/opcodes/bfin-dis.c 2017-09-21 13:54:00.603231339 +0530 +@@ -350,7 +350,7 @@ + REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP, + }; + +-#define gregs(x, i) REGNAME (decode_gregs[((i) << 3) | (x)]) ++#define gregs(x, i) REGNAME (decode_gregs[(((i) << 3) | (x)) & 15]) + + /* [dregs pregs (iregs mregs) (bregs lregs)]. */ + static const enum machine_registers decode_regs[] = +@@ -361,7 +361,7 @@ + REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3, + }; + +-#define regs(x, i) REGNAME (decode_regs[((i) << 3) | (x)]) ++#define regs(x, i) REGNAME (decode_regs[(((i) << 3) | (x)) & 31]) + + /* [dregs pregs (iregs mregs) (bregs lregs) Low Half]. */ + static const enum machine_registers decode_regs_lo[] = +@@ -372,7 +372,7 @@ + REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3, + }; + +-#define regs_lo(x, i) REGNAME (decode_regs_lo[((i) << 3) | (x)]) ++#define regs_lo(x, i) REGNAME (decode_regs_lo[(((i) << 3) | (x)) & 31]) + + /* [dregs pregs (iregs mregs) (bregs lregs) High Half]. */ + static const enum machine_registers decode_regs_hi[] = +@@ -383,7 +383,7 @@ + REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3, + }; + +-#define regs_hi(x, i) REGNAME (decode_regs_hi[((i) << 3) | (x)]) ++#define regs_hi(x, i) REGNAME (decode_regs_hi[(((i) << 3) | (x)) & 31]) + + static const enum machine_registers decode_statbits[] = + { +Index: git/opcodes/ChangeLog +=================================================================== +--- git.orig/opcodes/ChangeLog 2017-09-21 13:54:00.543230862 +0530 ++++ git/opcodes/ChangeLog 2017-09-21 14:06:03.772928105 +0530 +@@ -1,5 +1,13 @@ + 2017-06-15 Nick Clifton <nickc@redhat.com> + ++ PR binutils/21586 ++ * bfin-dis.c (gregs): Clip index to prevent overflow. ++ (regs): Likewise. ++ (regs_lo): Likewise. ++ (regs_hi): Likewise. ++ ++2017-06-15 Nick Clifton <nickc@redhat.com> ++ + PR binutils/21588 + * rl78-decode.opc (OP_BUF_LEN): Define. + (GETBYTE): Check for the index exceeding OP_BUF_LEN. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9750.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9750.patch new file mode 100644 index 0000000000..3ea1725315 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9750.patch @@ -0,0 +1,262 @@ +commit db5fa770268baf8cc82cf9b141d69799fd485fe2 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jun 14 13:35:06 2017 +0100 + + Fix address violation problems when disassembling a corrupt RX binary. + + PR binutils/21587 + * rx-decode.opc: Include libiberty.h + (GET_SCALE): New macro - validates access to SCALE array. + (GET_PSCALE): New macro - validates access to PSCALE array. + (DIs, SIs, S2Is, rx_disp): Use new macros. + * rx-decode.c: Regenerate. + +Upstream-Status: Backport + +CVE: CVE-2017-9750 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/opcodes/rx-decode.c +=================================================================== +--- git.orig/opcodes/rx-decode.c 2017-09-21 14:41:57.478649861 +0530 ++++ git/opcodes/rx-decode.c 2017-09-21 14:41:57.458649736 +0530 +@@ -27,6 +27,7 @@ + #include <string.h> + #include "ansidecl.h" + #include "opcode/rx.h" ++#include "libiberty.h" + + #define RX_OPCODE_BIG_ENDIAN 0 + +@@ -45,7 +46,7 @@ + #define LSIZE 2 + + /* These are for when the upper bits are "don't care" or "undefined". */ +-static int bwl[] = ++static int bwl[4] = + { + RX_Byte, + RX_Word, +@@ -53,7 +54,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int sbwl[] = ++static int sbwl[4] = + { + RX_SByte, + RX_SWord, +@@ -61,7 +62,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int ubw[] = ++static int ubw[4] = + { + RX_UByte, + RX_UWord, +@@ -69,7 +70,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int memex[] = ++static int memex[4] = + { + RX_SByte, + RX_SWord, +@@ -89,6 +90,9 @@ + /* This is for the prefix size enum. */ + static int PSCALE[] = { 4, 1, 1, 1, 2, 2, 2, 3, 4 }; + ++#define GET_SCALE(_indx) ((unsigned)(_indx) < ARRAY_SIZE (SCALE) ? SCALE[(_indx)] : 0) ++#define GET_PSCALE(_indx) ((unsigned)(_indx) < ARRAY_SIZE (PSCALE) ? PSCALE[(_indx)] : 0) ++ + static int flagmap[] = {0, 1, 2, 3, 0, 0, 0, 0, + 16, 17, 0, 0, 0, 0, 0, 0 }; + +@@ -107,7 +111,7 @@ + #define DC(c) OP (0, RX_Operand_Immediate, 0, c) + #define DR(r) OP (0, RX_Operand_Register, r, 0) + #define DI(r,a) OP (0, RX_Operand_Indirect, r, a) +-#define DIs(r,a,s) OP (0, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define DIs(r,a,s) OP (0, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define DD(t,r,s) rx_disp (0, t, r, bwl[s], ld); + #define DF(r) OP (0, RX_Operand_Flag, flagmap[r], 0) + +@@ -115,7 +119,7 @@ + #define SR(r) OP (1, RX_Operand_Register, r, 0) + #define SRR(r) OP (1, RX_Operand_TwoReg, r, 0) + #define SI(r,a) OP (1, RX_Operand_Indirect, r, a) +-#define SIs(r,a,s) OP (1, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define SIs(r,a,s) OP (1, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define SD(t,r,s) rx_disp (1, t, r, bwl[s], ld); + #define SP(t,r) rx_disp (1, t, r, (t!=3) ? RX_UByte : RX_Long, ld); P(t, 1); + #define SPm(t,r,m) rx_disp (1, t, r, memex[m], ld); rx->op[1].size = memex[m]; +@@ -124,7 +128,7 @@ + #define S2C(i) OP (2, RX_Operand_Immediate, 0, i) + #define S2R(r) OP (2, RX_Operand_Register, r, 0) + #define S2I(r,a) OP (2, RX_Operand_Indirect, r, a) +-#define S2Is(r,a,s) OP (2, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define S2Is(r,a,s) OP (2, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define S2D(t,r,s) rx_disp (2, t, r, bwl[s], ld); + #define S2P(t,r) rx_disp (2, t, r, (t!=3) ? RX_UByte : RX_Long, ld); P(t, 2); + #define S2Pm(t,r,m) rx_disp (2, t, r, memex[m], ld); rx->op[2].size = memex[m]; +@@ -211,7 +215,7 @@ + } + + static void +-rx_disp (int n, int type, int reg, int size, LocalData * ld) ++rx_disp (int n, int type, int reg, unsigned int size, LocalData * ld) + { + int disp; + +@@ -228,7 +232,7 @@ + case 1: + ld->rx->op[n].type = RX_Operand_Indirect; + disp = GETBYTE (); +- ld->rx->op[n].addend = disp * PSCALE[size]; ++ ld->rx->op[n].addend = disp * GET_PSCALE (size); + break; + case 2: + ld->rx->op[n].type = RX_Operand_Indirect; +@@ -238,7 +242,7 @@ + #else + disp = disp + GETBYTE () * 256; + #endif +- ld->rx->op[n].addend = disp * PSCALE[size]; ++ ld->rx->op[n].addend = disp * GET_PSCALE (size); + break; + default: + abort (); +Index: git/opcodes/rx-decode.opc +=================================================================== +--- git.orig/opcodes/rx-decode.opc 2017-09-21 14:41:57.478649861 +0530 ++++ git/opcodes/rx-decode.opc 2017-09-21 14:41:57.458649736 +0530 +@@ -26,6 +26,7 @@ + #include <string.h> + #include "ansidecl.h" + #include "opcode/rx.h" ++#include "libiberty.h" + + #define RX_OPCODE_BIG_ENDIAN 0 + +@@ -44,7 +45,7 @@ + #define LSIZE 2 + + /* These are for when the upper bits are "don't care" or "undefined". */ +-static int bwl[] = ++static int bwl[4] = + { + RX_Byte, + RX_Word, +@@ -52,7 +53,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int sbwl[] = ++static int sbwl[4] = + { + RX_SByte, + RX_SWord, +@@ -60,7 +61,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int ubw[] = ++static int ubw[4] = + { + RX_UByte, + RX_UWord, +@@ -68,7 +69,7 @@ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ + }; + +-static int memex[] = ++static int memex[4] = + { + RX_SByte, + RX_SWord, +@@ -88,6 +89,9 @@ + /* This is for the prefix size enum. */ + static int PSCALE[] = { 4, 1, 1, 1, 2, 2, 2, 3, 4 }; + ++#define GET_SCALE(_indx) ((unsigned)(_indx) < ARRAY_SIZE (SCALE) ? SCALE[(_indx)] : 0) ++#define GET_PSCALE(_indx) ((unsigned)(_indx) < ARRAY_SIZE (PSCALE) ? PSCALE[(_indx)] : 0) ++ + static int flagmap[] = {0, 1, 2, 3, 0, 0, 0, 0, + 16, 17, 0, 0, 0, 0, 0, 0 }; + +@@ -106,7 +110,7 @@ + #define DC(c) OP (0, RX_Operand_Immediate, 0, c) + #define DR(r) OP (0, RX_Operand_Register, r, 0) + #define DI(r,a) OP (0, RX_Operand_Indirect, r, a) +-#define DIs(r,a,s) OP (0, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define DIs(r,a,s) OP (0, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define DD(t,r,s) rx_disp (0, t, r, bwl[s], ld); + #define DF(r) OP (0, RX_Operand_Flag, flagmap[r], 0) + +@@ -114,7 +118,7 @@ + #define SR(r) OP (1, RX_Operand_Register, r, 0) + #define SRR(r) OP (1, RX_Operand_TwoReg, r, 0) + #define SI(r,a) OP (1, RX_Operand_Indirect, r, a) +-#define SIs(r,a,s) OP (1, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define SIs(r,a,s) OP (1, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define SD(t,r,s) rx_disp (1, t, r, bwl[s], ld); + #define SP(t,r) rx_disp (1, t, r, (t!=3) ? RX_UByte : RX_Long, ld); P(t, 1); + #define SPm(t,r,m) rx_disp (1, t, r, memex[m], ld); rx->op[1].size = memex[m]; +@@ -123,7 +127,7 @@ + #define S2C(i) OP (2, RX_Operand_Immediate, 0, i) + #define S2R(r) OP (2, RX_Operand_Register, r, 0) + #define S2I(r,a) OP (2, RX_Operand_Indirect, r, a) +-#define S2Is(r,a,s) OP (2, RX_Operand_Indirect, r, (a) * SCALE[s]) ++#define S2Is(r,a,s) OP (2, RX_Operand_Indirect, r, (a) * GET_SCALE (s)) + #define S2D(t,r,s) rx_disp (2, t, r, bwl[s], ld); + #define S2P(t,r) rx_disp (2, t, r, (t!=3) ? RX_UByte : RX_Long, ld); P(t, 2); + #define S2Pm(t,r,m) rx_disp (2, t, r, memex[m], ld); rx->op[2].size = memex[m]; +@@ -210,7 +214,7 @@ + } + + static void +-rx_disp (int n, int type, int reg, int size, LocalData * ld) ++rx_disp (int n, int type, int reg, unsigned int size, LocalData * ld) + { + int disp; + +@@ -227,7 +231,7 @@ + case 1: + ld->rx->op[n].type = RX_Operand_Indirect; + disp = GETBYTE (); +- ld->rx->op[n].addend = disp * PSCALE[size]; ++ ld->rx->op[n].addend = disp * GET_PSCALE (size); + break; + case 2: + ld->rx->op[n].type = RX_Operand_Indirect; +@@ -237,7 +241,7 @@ + #else + disp = disp + GETBYTE () * 256; + #endif +- ld->rx->op[n].addend = disp * PSCALE[size]; ++ ld->rx->op[n].addend = disp * GET_PSCALE (size); + break; + default: + abort (); +Index: git/opcodes/ChangeLog +=================================================================== +--- git.orig/opcodes/ChangeLog 2017-09-21 14:40:17.000000000 +0530 ++++ git/opcodes/ChangeLog 2017-09-21 14:44:07.503461009 +0530 +@@ -15,6 +15,15 @@ + array. + * rl78-decode.c: Regenerate. + ++2017-06-14 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21587 ++ * rx-decode.opc: Include libiberty.h ++ (GET_SCALE): New macro - validates access to SCALE array. ++ (GET_PSCALE): New macro - validates access to PSCALE array. ++ (DIs, SIs, S2Is, rx_disp): Use new macros. ++ * rx-decode.c: Regenerate. ++ + 2016-08-03 Tristan Gingold <gingold@adacore.com> + + * configure: Regenerate. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9751.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9751.patch new file mode 100644 index 0000000000..0d525e8ac1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9751.patch @@ -0,0 +1,3738 @@ +commit 63323b5b23bd83fa7b04ea00dff593c933e9b0e3 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 12:37:01 2017 +0100 + + Fix address violation when disassembling a corrupt RL78 binary. + + PR binutils/21588 + * rl78-decode.opc (OP_BUF_LEN): Define. + (GETBYTE): Check for the index exceeding OP_BUF_LEN. + (rl78_decode_opcode): Use OP_BUF_LEN as the length of the op_buf + array. + * rl78-decode.c: Regenerate. + +Upstream-Status: Backport + +CVE: CVE-2017-9751 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/opcodes/rl78-decode.c +=================================================================== +--- git.orig/opcodes/rl78-decode.c 2017-09-21 13:14:42.256835775 +0530 ++++ git/opcodes/rl78-decode.c 2017-09-21 13:14:49.444888350 +0530 +@@ -51,7 +51,9 @@ + #define W() rl78->size = RL78_Word + + #define AU ATTRIBUTE_UNUSED +-#define GETBYTE() (ld->op [ld->rl78->n_bytes++] = ld->getbyte (ld->ptr)) ++ ++#define OP_BUF_LEN 20 ++#define GETBYTE() (ld->rl78->n_bytes < (OP_BUF_LEN - 1) ? ld->op [ld->rl78->n_bytes++] = ld->getbyte (ld->ptr): 0) + #define B ((unsigned long) GETBYTE()) + + #define SYNTAX(x) rl78->syntax = x +@@ -169,7 +171,7 @@ + RL78_Dis_Isa isa) + { + LocalData lds, * ld = &lds; +- unsigned char op_buf[20] = {0}; ++ unsigned char op_buf[OP_BUF_LEN] = {0}; + unsigned char *op = op_buf; + int op0, op1; + +@@ -201,7 +203,7 @@ + op[0]); + } + SYNTAX("nop"); +-#line 911 "rl78-decode.opc" ++#line 913 "rl78-decode.opc" + ID(nop); + + /*----------------------------------------------------------------------*/ +@@ -214,7 +216,7 @@ + case 0x07: + { + /** 0000 0rw1 addw %0, %1 */ +-#line 274 "rl78-decode.opc" ++#line 276 "rl78-decode.opc" + int rw AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -224,7 +226,7 @@ + printf (" rw = 0x%x\n", rw); + } + SYNTAX("addw %0, %1"); +-#line 274 "rl78-decode.opc" ++#line 276 "rl78-decode.opc" + ID(add); W(); DR(AX); SRW(rw); Fzac; + + } +@@ -239,7 +241,7 @@ + op[0]); + } + SYNTAX("addw %0, %e!1"); +-#line 265 "rl78-decode.opc" ++#line 267 "rl78-decode.opc" + ID(add); W(); DR(AX); SM(None, IMMU(2)); Fzac; + + } +@@ -254,7 +256,7 @@ + op[0]); + } + SYNTAX("addw %0, #%1"); +-#line 271 "rl78-decode.opc" ++#line 273 "rl78-decode.opc" + ID(add); W(); DR(AX); SC(IMMU(2)); Fzac; + + } +@@ -269,7 +271,7 @@ + op[0]); + } + SYNTAX("addw %0, %1"); +-#line 277 "rl78-decode.opc" ++#line 279 "rl78-decode.opc" + ID(add); W(); DR(AX); SM(None, SADDR); Fzac; + + } +@@ -284,7 +286,7 @@ + op[0]); + } + SYNTAX("xch a, x"); +-#line 1234 "rl78-decode.opc" ++#line 1236 "rl78-decode.opc" + ID(xch); DR(A); SR(X); + + /*----------------------------------------------------------------------*/ +@@ -301,7 +303,7 @@ + op[0]); + } + SYNTAX("mov %0, %e1"); +-#line 678 "rl78-decode.opc" ++#line 680 "rl78-decode.opc" + ID(mov); DR(A); SM(B, IMMU(2)); + + } +@@ -316,7 +318,7 @@ + op[0]); + } + SYNTAX("add %0, #%1"); +-#line 228 "rl78-decode.opc" ++#line 230 "rl78-decode.opc" + ID(add); DM(None, SADDR); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -333,7 +335,7 @@ + op[0]); + } + SYNTAX("add %0, %1"); +-#line 222 "rl78-decode.opc" ++#line 224 "rl78-decode.opc" + ID(add); DR(A); SM(None, SADDR); Fzac; + + } +@@ -348,7 +350,7 @@ + op[0]); + } + SYNTAX("add %0, #%1"); +-#line 216 "rl78-decode.opc" ++#line 218 "rl78-decode.opc" + ID(add); DR(A); SC(IMMU(1)); Fzac; + + } +@@ -363,7 +365,7 @@ + op[0]); + } + SYNTAX("add %0, %e1"); +-#line 204 "rl78-decode.opc" ++#line 206 "rl78-decode.opc" + ID(add); DR(A); SM(HL, 0); Fzac; + + } +@@ -378,7 +380,7 @@ + op[0]); + } + SYNTAX("add %0, %ea1"); +-#line 210 "rl78-decode.opc" ++#line 212 "rl78-decode.opc" + ID(add); DR(A); SM(HL, IMMU(1)); Fzac; + + } +@@ -393,7 +395,7 @@ + op[0]); + } + SYNTAX("add %0, %e!1"); +-#line 201 "rl78-decode.opc" ++#line 203 "rl78-decode.opc" + ID(add); DR(A); SM(None, IMMU(2)); Fzac; + + } +@@ -408,7 +410,7 @@ + op[0]); + } + SYNTAX("addw %0, #%1"); +-#line 280 "rl78-decode.opc" ++#line 282 "rl78-decode.opc" + ID(add); W(); DR(SP); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -425,7 +427,7 @@ + op[0]); + } + SYNTAX("es:"); +-#line 193 "rl78-decode.opc" ++#line 195 "rl78-decode.opc" + DE(); SE(); + op ++; + pc ++; +@@ -440,7 +442,7 @@ + case 0x16: + { + /** 0001 0ra0 movw %0, %1 */ +-#line 859 "rl78-decode.opc" ++#line 861 "rl78-decode.opc" + int ra AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -450,7 +452,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("movw %0, %1"); +-#line 859 "rl78-decode.opc" ++#line 861 "rl78-decode.opc" + ID(mov); W(); DRW(ra); SR(AX); + + } +@@ -460,7 +462,7 @@ + case 0x17: + { + /** 0001 0ra1 movw %0, %1 */ +-#line 856 "rl78-decode.opc" ++#line 858 "rl78-decode.opc" + int ra AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -470,7 +472,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("movw %0, %1"); +-#line 856 "rl78-decode.opc" ++#line 858 "rl78-decode.opc" + ID(mov); W(); DR(AX); SRW(ra); + + } +@@ -485,7 +487,7 @@ + op[0]); + } + SYNTAX("mov %e0, %1"); +-#line 729 "rl78-decode.opc" ++#line 731 "rl78-decode.opc" + ID(mov); DM(B, IMMU(2)); SR(A); + + } +@@ -500,7 +502,7 @@ + op[0]); + } + SYNTAX("mov %e0, #%1"); +-#line 726 "rl78-decode.opc" ++#line 728 "rl78-decode.opc" + ID(mov); DM(B, IMMU(2)); SC(IMMU(1)); + + } +@@ -515,7 +517,7 @@ + op[0]); + } + SYNTAX("addc %0, #%1"); +-#line 260 "rl78-decode.opc" ++#line 262 "rl78-decode.opc" + ID(addc); DM(None, SADDR); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -532,7 +534,7 @@ + op[0]); + } + SYNTAX("addc %0, %1"); +-#line 257 "rl78-decode.opc" ++#line 259 "rl78-decode.opc" + ID(addc); DR(A); SM(None, SADDR); Fzac; + + } +@@ -547,7 +549,7 @@ + op[0]); + } + SYNTAX("addc %0, #%1"); +-#line 248 "rl78-decode.opc" ++#line 250 "rl78-decode.opc" + ID(addc); DR(A); SC(IMMU(1)); Fzac; + + } +@@ -562,7 +564,7 @@ + op[0]); + } + SYNTAX("addc %0, %e1"); +-#line 236 "rl78-decode.opc" ++#line 238 "rl78-decode.opc" + ID(addc); DR(A); SM(HL, 0); Fzac; + + } +@@ -577,7 +579,7 @@ + op[0]); + } + SYNTAX("addc %0, %ea1"); +-#line 245 "rl78-decode.opc" ++#line 247 "rl78-decode.opc" + ID(addc); DR(A); SM(HL, IMMU(1)); Fzac; + + } +@@ -592,7 +594,7 @@ + op[0]); + } + SYNTAX("addc %0, %e!1"); +-#line 233 "rl78-decode.opc" ++#line 235 "rl78-decode.opc" + ID(addc); DR(A); SM(None, IMMU(2)); Fzac; + + } +@@ -607,7 +609,7 @@ + op[0]); + } + SYNTAX("subw %0, #%1"); +-#line 1198 "rl78-decode.opc" ++#line 1200 "rl78-decode.opc" + ID(sub); W(); DR(SP); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -620,7 +622,7 @@ + case 0x27: + { + /** 0010 0rw1 subw %0, %1 */ +-#line 1192 "rl78-decode.opc" ++#line 1194 "rl78-decode.opc" + int rw AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -630,7 +632,7 @@ + printf (" rw = 0x%x\n", rw); + } + SYNTAX("subw %0, %1"); +-#line 1192 "rl78-decode.opc" ++#line 1194 "rl78-decode.opc" + ID(sub); W(); DR(AX); SRW(rw); Fzac; + + } +@@ -645,7 +647,7 @@ + op[0]); + } + SYNTAX("subw %0, %e!1"); +-#line 1183 "rl78-decode.opc" ++#line 1185 "rl78-decode.opc" + ID(sub); W(); DR(AX); SM(None, IMMU(2)); Fzac; + + } +@@ -660,7 +662,7 @@ + op[0]); + } + SYNTAX("subw %0, #%1"); +-#line 1189 "rl78-decode.opc" ++#line 1191 "rl78-decode.opc" + ID(sub); W(); DR(AX); SC(IMMU(2)); Fzac; + + } +@@ -675,7 +677,7 @@ + op[0]); + } + SYNTAX("subw %0, %1"); +-#line 1195 "rl78-decode.opc" ++#line 1197 "rl78-decode.opc" + ID(sub); W(); DR(AX); SM(None, SADDR); Fzac; + + } +@@ -690,7 +692,7 @@ + op[0]); + } + SYNTAX("mov %e0, %1"); +-#line 741 "rl78-decode.opc" ++#line 743 "rl78-decode.opc" + ID(mov); DM(C, IMMU(2)); SR(A); + + } +@@ -705,7 +707,7 @@ + op[0]); + } + SYNTAX("mov %0, %e1"); +-#line 684 "rl78-decode.opc" ++#line 686 "rl78-decode.opc" + ID(mov); DR(A); SM(C, IMMU(2)); + + } +@@ -720,7 +722,7 @@ + op[0]); + } + SYNTAX("sub %0, #%1"); +-#line 1146 "rl78-decode.opc" ++#line 1148 "rl78-decode.opc" + ID(sub); DM(None, SADDR); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -737,7 +739,7 @@ + op[0]); + } + SYNTAX("sub %0, %1"); +-#line 1140 "rl78-decode.opc" ++#line 1142 "rl78-decode.opc" + ID(sub); DR(A); SM(None, SADDR); Fzac; + + } +@@ -752,7 +754,7 @@ + op[0]); + } + SYNTAX("sub %0, #%1"); +-#line 1134 "rl78-decode.opc" ++#line 1136 "rl78-decode.opc" + ID(sub); DR(A); SC(IMMU(1)); Fzac; + + } +@@ -767,7 +769,7 @@ + op[0]); + } + SYNTAX("sub %0, %e1"); +-#line 1122 "rl78-decode.opc" ++#line 1124 "rl78-decode.opc" + ID(sub); DR(A); SM(HL, 0); Fzac; + + } +@@ -782,7 +784,7 @@ + op[0]); + } + SYNTAX("sub %0, %ea1"); +-#line 1128 "rl78-decode.opc" ++#line 1130 "rl78-decode.opc" + ID(sub); DR(A); SM(HL, IMMU(1)); Fzac; + + } +@@ -797,7 +799,7 @@ + op[0]); + } + SYNTAX("sub %0, %e!1"); +-#line 1119 "rl78-decode.opc" ++#line 1121 "rl78-decode.opc" + ID(sub); DR(A); SM(None, IMMU(2)); Fzac; + + } +@@ -808,7 +810,7 @@ + case 0x36: + { + /** 0011 0rg0 movw %0, #%1 */ +-#line 853 "rl78-decode.opc" ++#line 855 "rl78-decode.opc" + int rg AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -818,7 +820,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("movw %0, #%1"); +-#line 853 "rl78-decode.opc" ++#line 855 "rl78-decode.opc" + ID(mov); W(); DRW(rg); SC(IMMU(2)); + + } +@@ -830,7 +832,7 @@ + case 0x00: + { + /** 0011 0001 0bit 0000 btclr %s1, $%a0 */ +-#line 416 "rl78-decode.opc" ++#line 418 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -840,7 +842,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("btclr %s1, $%a0"); +-#line 416 "rl78-decode.opc" ++#line 418 "rl78-decode.opc" + ID(branch_cond_clear); SM(None, SADDR); SB(bit); DC(pc+IMMS(1)+4); COND(T); + + /*----------------------------------------------------------------------*/ +@@ -850,7 +852,7 @@ + case 0x01: + { + /** 0011 0001 0bit 0001 btclr %1, $%a0 */ +-#line 410 "rl78-decode.opc" ++#line 412 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -860,7 +862,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("btclr %1, $%a0"); +-#line 410 "rl78-decode.opc" ++#line 412 "rl78-decode.opc" + ID(branch_cond_clear); DC(pc+IMMS(1)+3); SR(A); SB(bit); COND(T); + + } +@@ -868,7 +870,7 @@ + case 0x02: + { + /** 0011 0001 0bit 0010 bt %s1, $%a0 */ +-#line 402 "rl78-decode.opc" ++#line 404 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -878,7 +880,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bt %s1, $%a0"); +-#line 402 "rl78-decode.opc" ++#line 404 "rl78-decode.opc" + ID(branch_cond); SM(None, SADDR); SB(bit); DC(pc+IMMS(1)+4); COND(T); + + /*----------------------------------------------------------------------*/ +@@ -888,7 +890,7 @@ + case 0x03: + { + /** 0011 0001 0bit 0011 bt %1, $%a0 */ +-#line 396 "rl78-decode.opc" ++#line 398 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -898,7 +900,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bt %1, $%a0"); +-#line 396 "rl78-decode.opc" ++#line 398 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SR(A); SB(bit); COND(T); + + } +@@ -906,7 +908,7 @@ + case 0x04: + { + /** 0011 0001 0bit 0100 bf %s1, $%a0 */ +-#line 363 "rl78-decode.opc" ++#line 365 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -916,7 +918,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bf %s1, $%a0"); +-#line 363 "rl78-decode.opc" ++#line 365 "rl78-decode.opc" + ID(branch_cond); SM(None, SADDR); SB(bit); DC(pc+IMMS(1)+4); COND(F); + + /*----------------------------------------------------------------------*/ +@@ -926,7 +928,7 @@ + case 0x05: + { + /** 0011 0001 0bit 0101 bf %1, $%a0 */ +-#line 357 "rl78-decode.opc" ++#line 359 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -936,7 +938,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bf %1, $%a0"); +-#line 357 "rl78-decode.opc" ++#line 359 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SR(A); SB(bit); COND(F); + + } +@@ -944,7 +946,7 @@ + case 0x07: + { + /** 0011 0001 0cnt 0111 shl %0, %1 */ +-#line 1075 "rl78-decode.opc" ++#line 1077 "rl78-decode.opc" + int cnt AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -954,7 +956,7 @@ + printf (" cnt = 0x%x\n", cnt); + } + SYNTAX("shl %0, %1"); +-#line 1075 "rl78-decode.opc" ++#line 1077 "rl78-decode.opc" + ID(shl); DR(C); SC(cnt); + + } +@@ -962,7 +964,7 @@ + case 0x08: + { + /** 0011 0001 0cnt 1000 shl %0, %1 */ +-#line 1072 "rl78-decode.opc" ++#line 1074 "rl78-decode.opc" + int cnt AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -972,7 +974,7 @@ + printf (" cnt = 0x%x\n", cnt); + } + SYNTAX("shl %0, %1"); +-#line 1072 "rl78-decode.opc" ++#line 1074 "rl78-decode.opc" + ID(shl); DR(B); SC(cnt); + + } +@@ -980,7 +982,7 @@ + case 0x09: + { + /** 0011 0001 0cnt 1001 shl %0, %1 */ +-#line 1069 "rl78-decode.opc" ++#line 1071 "rl78-decode.opc" + int cnt AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -990,7 +992,7 @@ + printf (" cnt = 0x%x\n", cnt); + } + SYNTAX("shl %0, %1"); +-#line 1069 "rl78-decode.opc" ++#line 1071 "rl78-decode.opc" + ID(shl); DR(A); SC(cnt); + + } +@@ -998,7 +1000,7 @@ + case 0x0a: + { + /** 0011 0001 0cnt 1010 shr %0, %1 */ +-#line 1086 "rl78-decode.opc" ++#line 1088 "rl78-decode.opc" + int cnt AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1008,7 +1010,7 @@ + printf (" cnt = 0x%x\n", cnt); + } + SYNTAX("shr %0, %1"); +-#line 1086 "rl78-decode.opc" ++#line 1088 "rl78-decode.opc" + ID(shr); DR(A); SC(cnt); + + } +@@ -1016,7 +1018,7 @@ + case 0x0b: + { + /** 0011 0001 0cnt 1011 sar %0, %1 */ +-#line 1033 "rl78-decode.opc" ++#line 1035 "rl78-decode.opc" + int cnt AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1026,7 +1028,7 @@ + printf (" cnt = 0x%x\n", cnt); + } + SYNTAX("sar %0, %1"); +-#line 1033 "rl78-decode.opc" ++#line 1035 "rl78-decode.opc" + ID(sar); DR(A); SC(cnt); + + } +@@ -1035,7 +1037,7 @@ + case 0x8c: + { + /** 0011 0001 wcnt 1100 shlw %0, %1 */ +-#line 1081 "rl78-decode.opc" ++#line 1083 "rl78-decode.opc" + int wcnt AU = (op[1] >> 4) & 0x0f; + if (trace) + { +@@ -1045,7 +1047,7 @@ + printf (" wcnt = 0x%x\n", wcnt); + } + SYNTAX("shlw %0, %1"); +-#line 1081 "rl78-decode.opc" ++#line 1083 "rl78-decode.opc" + ID(shl); W(); DR(BC); SC(wcnt); + + /*----------------------------------------------------------------------*/ +@@ -1056,7 +1058,7 @@ + case 0x8d: + { + /** 0011 0001 wcnt 1101 shlw %0, %1 */ +-#line 1078 "rl78-decode.opc" ++#line 1080 "rl78-decode.opc" + int wcnt AU = (op[1] >> 4) & 0x0f; + if (trace) + { +@@ -1066,7 +1068,7 @@ + printf (" wcnt = 0x%x\n", wcnt); + } + SYNTAX("shlw %0, %1"); +-#line 1078 "rl78-decode.opc" ++#line 1080 "rl78-decode.opc" + ID(shl); W(); DR(AX); SC(wcnt); + + } +@@ -1075,7 +1077,7 @@ + case 0x8e: + { + /** 0011 0001 wcnt 1110 shrw %0, %1 */ +-#line 1089 "rl78-decode.opc" ++#line 1091 "rl78-decode.opc" + int wcnt AU = (op[1] >> 4) & 0x0f; + if (trace) + { +@@ -1085,7 +1087,7 @@ + printf (" wcnt = 0x%x\n", wcnt); + } + SYNTAX("shrw %0, %1"); +-#line 1089 "rl78-decode.opc" ++#line 1091 "rl78-decode.opc" + ID(shr); W(); DR(AX); SC(wcnt); + + /*----------------------------------------------------------------------*/ +@@ -1096,7 +1098,7 @@ + case 0x8f: + { + /** 0011 0001 wcnt 1111 sarw %0, %1 */ +-#line 1036 "rl78-decode.opc" ++#line 1038 "rl78-decode.opc" + int wcnt AU = (op[1] >> 4) & 0x0f; + if (trace) + { +@@ -1106,7 +1108,7 @@ + printf (" wcnt = 0x%x\n", wcnt); + } + SYNTAX("sarw %0, %1"); +-#line 1036 "rl78-decode.opc" ++#line 1038 "rl78-decode.opc" + ID(sar); W(); DR(AX); SC(wcnt); + + /*----------------------------------------------------------------------*/ +@@ -1116,7 +1118,7 @@ + case 0x80: + { + /** 0011 0001 1bit 0000 btclr %s1, $%a0 */ +-#line 413 "rl78-decode.opc" ++#line 415 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1126,7 +1128,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("btclr %s1, $%a0"); +-#line 413 "rl78-decode.opc" ++#line 415 "rl78-decode.opc" + ID(branch_cond_clear); SM(None, SFR); SB(bit); DC(pc+IMMS(1)+4); COND(T); + + } +@@ -1134,7 +1136,7 @@ + case 0x81: + { + /** 0011 0001 1bit 0001 btclr %e1, $%a0 */ +-#line 407 "rl78-decode.opc" ++#line 409 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1144,7 +1146,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("btclr %e1, $%a0"); +-#line 407 "rl78-decode.opc" ++#line 409 "rl78-decode.opc" + ID(branch_cond_clear); DC(pc+IMMS(1)+3); SM(HL,0); SB(bit); COND(T); + + } +@@ -1152,7 +1154,7 @@ + case 0x82: + { + /** 0011 0001 1bit 0010 bt %s1, $%a0 */ +-#line 399 "rl78-decode.opc" ++#line 401 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1162,7 +1164,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bt %s1, $%a0"); +-#line 399 "rl78-decode.opc" ++#line 401 "rl78-decode.opc" + ID(branch_cond); SM(None, SFR); SB(bit); DC(pc+IMMS(1)+4); COND(T); + + } +@@ -1170,7 +1172,7 @@ + case 0x83: + { + /** 0011 0001 1bit 0011 bt %e1, $%a0 */ +-#line 393 "rl78-decode.opc" ++#line 395 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1180,7 +1182,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bt %e1, $%a0"); +-#line 393 "rl78-decode.opc" ++#line 395 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SM(HL,0); SB(bit); COND(T); + + } +@@ -1188,7 +1190,7 @@ + case 0x84: + { + /** 0011 0001 1bit 0100 bf %s1, $%a0 */ +-#line 360 "rl78-decode.opc" ++#line 362 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1198,7 +1200,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bf %s1, $%a0"); +-#line 360 "rl78-decode.opc" ++#line 362 "rl78-decode.opc" + ID(branch_cond); SM(None, SFR); SB(bit); DC(pc+IMMS(1)+4); COND(F); + + } +@@ -1206,7 +1208,7 @@ + case 0x85: + { + /** 0011 0001 1bit 0101 bf %e1, $%a0 */ +-#line 354 "rl78-decode.opc" ++#line 356 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -1216,7 +1218,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("bf %e1, $%a0"); +-#line 354 "rl78-decode.opc" ++#line 356 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SM(HL,0); SB(bit); COND(F); + + } +@@ -1229,7 +1231,7 @@ + case 0x37: + { + /** 0011 0ra1 xchw %0, %1 */ +-#line 1239 "rl78-decode.opc" ++#line 1241 "rl78-decode.opc" + int ra AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -1239,7 +1241,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("xchw %0, %1"); +-#line 1239 "rl78-decode.opc" ++#line 1241 "rl78-decode.opc" + ID(xch); W(); DR(AX); SRW(ra); + + /*----------------------------------------------------------------------*/ +@@ -1256,7 +1258,7 @@ + op[0]); + } + SYNTAX("mov %e0, #%1"); +-#line 738 "rl78-decode.opc" ++#line 740 "rl78-decode.opc" + ID(mov); DM(C, IMMU(2)); SC(IMMU(1)); + + } +@@ -1271,7 +1273,7 @@ + op[0]); + } + SYNTAX("mov %e0, #%1"); +-#line 732 "rl78-decode.opc" ++#line 734 "rl78-decode.opc" + ID(mov); DM(BC, IMMU(2)); SC(IMMU(1)); + + } +@@ -1286,7 +1288,7 @@ + op[0]); + } + SYNTAX("subc %0, #%1"); +-#line 1178 "rl78-decode.opc" ++#line 1180 "rl78-decode.opc" + ID(subc); DM(None, SADDR); SC(IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -1303,7 +1305,7 @@ + op[0]); + } + SYNTAX("subc %0, %1"); +-#line 1175 "rl78-decode.opc" ++#line 1177 "rl78-decode.opc" + ID(subc); DR(A); SM(None, SADDR); Fzac; + + } +@@ -1318,7 +1320,7 @@ + op[0]); + } + SYNTAX("subc %0, #%1"); +-#line 1166 "rl78-decode.opc" ++#line 1168 "rl78-decode.opc" + ID(subc); DR(A); SC(IMMU(1)); Fzac; + + } +@@ -1333,7 +1335,7 @@ + op[0]); + } + SYNTAX("subc %0, %e1"); +-#line 1154 "rl78-decode.opc" ++#line 1156 "rl78-decode.opc" + ID(subc); DR(A); SM(HL, 0); Fzac; + + } +@@ -1348,7 +1350,7 @@ + op[0]); + } + SYNTAX("subc %0, %ea1"); +-#line 1163 "rl78-decode.opc" ++#line 1165 "rl78-decode.opc" + ID(subc); DR(A); SM(HL, IMMU(1)); Fzac; + + } +@@ -1363,7 +1365,7 @@ + op[0]); + } + SYNTAX("subc %0, %e!1"); +-#line 1151 "rl78-decode.opc" ++#line 1153 "rl78-decode.opc" + ID(subc); DR(A); SM(None, IMMU(2)); Fzac; + + } +@@ -1378,7 +1380,7 @@ + op[0]); + } + SYNTAX("cmp %e!0, #%1"); +-#line 480 "rl78-decode.opc" ++#line 482 "rl78-decode.opc" + ID(cmp); DM(None, IMMU(2)); SC(IMMU(1)); Fzac; + + } +@@ -1393,7 +1395,7 @@ + op[0]); + } + SYNTAX("mov %0, #%1"); +-#line 717 "rl78-decode.opc" ++#line 719 "rl78-decode.opc" + ID(mov); DR(ES); SC(IMMU(1)); + + } +@@ -1408,7 +1410,7 @@ + op[0]); + } + SYNTAX("cmpw %0, %e!1"); +-#line 531 "rl78-decode.opc" ++#line 533 "rl78-decode.opc" + ID(cmp); W(); DR(AX); SM(None, IMMU(2)); Fzac; + + } +@@ -1418,7 +1420,7 @@ + case 0x47: + { + /** 0100 0ra1 cmpw %0, %1 */ +-#line 540 "rl78-decode.opc" ++#line 542 "rl78-decode.opc" + int ra AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -1428,7 +1430,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("cmpw %0, %1"); +-#line 540 "rl78-decode.opc" ++#line 542 "rl78-decode.opc" + ID(cmp); W(); DR(AX); SRW(ra); Fzac; + + } +@@ -1443,7 +1445,7 @@ + op[0]); + } + SYNTAX("cmpw %0, #%1"); +-#line 537 "rl78-decode.opc" ++#line 539 "rl78-decode.opc" + ID(cmp); W(); DR(AX); SC(IMMU(2)); Fzac; + + } +@@ -1458,7 +1460,7 @@ + op[0]); + } + SYNTAX("cmpw %0, %1"); +-#line 543 "rl78-decode.opc" ++#line 545 "rl78-decode.opc" + ID(cmp); W(); DR(AX); SM(None, SADDR); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -1475,7 +1477,7 @@ + op[0]); + } + SYNTAX("mov %e0, %1"); +-#line 735 "rl78-decode.opc" ++#line 737 "rl78-decode.opc" + ID(mov); DM(BC, IMMU(2)); SR(A); + + } +@@ -1490,7 +1492,7 @@ + op[0]); + } + SYNTAX("mov %0, %e1"); +-#line 681 "rl78-decode.opc" ++#line 683 "rl78-decode.opc" + ID(mov); DR(A); SM(BC, IMMU(2)); + + } +@@ -1505,7 +1507,7 @@ + op[0]); + } + SYNTAX("cmp %0, #%1"); +-#line 483 "rl78-decode.opc" ++#line 485 "rl78-decode.opc" + ID(cmp); DM(None, SADDR); SC(IMMU(1)); Fzac; + + } +@@ -1520,7 +1522,7 @@ + op[0]); + } + SYNTAX("cmp %0, %1"); +-#line 510 "rl78-decode.opc" ++#line 512 "rl78-decode.opc" + ID(cmp); DR(A); SM(None, SADDR); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -1537,7 +1539,7 @@ + op[0]); + } + SYNTAX("cmp %0, #%1"); +-#line 501 "rl78-decode.opc" ++#line 503 "rl78-decode.opc" + ID(cmp); DR(A); SC(IMMU(1)); Fzac; + + } +@@ -1552,7 +1554,7 @@ + op[0]); + } + SYNTAX("cmp %0, %e1"); +-#line 489 "rl78-decode.opc" ++#line 491 "rl78-decode.opc" + ID(cmp); DR(A); SM(HL, 0); Fzac; + + } +@@ -1567,7 +1569,7 @@ + op[0]); + } + SYNTAX("cmp %0, %ea1"); +-#line 498 "rl78-decode.opc" ++#line 500 "rl78-decode.opc" + ID(cmp); DR(A); SM(HL, IMMU(1)); Fzac; + + } +@@ -1582,7 +1584,7 @@ + op[0]); + } + SYNTAX("cmp %0, %e!1"); +-#line 486 "rl78-decode.opc" ++#line 488 "rl78-decode.opc" + ID(cmp); DR(A); SM(None, IMMU(2)); Fzac; + + } +@@ -1597,7 +1599,7 @@ + case 0x57: + { + /** 0101 0reg mov %0, #%1 */ +-#line 669 "rl78-decode.opc" ++#line 671 "rl78-decode.opc" + int reg AU = op[0] & 0x07; + if (trace) + { +@@ -1607,7 +1609,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("mov %0, #%1"); +-#line 669 "rl78-decode.opc" ++#line 671 "rl78-decode.opc" + ID(mov); DRB(reg); SC(IMMU(1)); + + } +@@ -1622,7 +1624,7 @@ + op[0]); + } + SYNTAX("movw %e0, %1"); +-#line 871 "rl78-decode.opc" ++#line 873 "rl78-decode.opc" + ID(mov); W(); DM(B, IMMU(2)); SR(AX); + + } +@@ -1637,7 +1639,7 @@ + op[0]); + } + SYNTAX("movw %0, %e1"); +-#line 862 "rl78-decode.opc" ++#line 864 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(B, IMMU(2)); + + } +@@ -1652,7 +1654,7 @@ + op[0]); + } + SYNTAX("and %0, #%1"); +-#line 312 "rl78-decode.opc" ++#line 314 "rl78-decode.opc" + ID(and); DM(None, SADDR); SC(IMMU(1)); Fz; + + /*----------------------------------------------------------------------*/ +@@ -1669,7 +1671,7 @@ + op[0]); + } + SYNTAX("and %0, %1"); +-#line 309 "rl78-decode.opc" ++#line 311 "rl78-decode.opc" + ID(and); DR(A); SM(None, SADDR); Fz; + + } +@@ -1684,7 +1686,7 @@ + op[0]); + } + SYNTAX("and %0, #%1"); +-#line 300 "rl78-decode.opc" ++#line 302 "rl78-decode.opc" + ID(and); DR(A); SC(IMMU(1)); Fz; + + } +@@ -1699,7 +1701,7 @@ + op[0]); + } + SYNTAX("and %0, %e1"); +-#line 288 "rl78-decode.opc" ++#line 290 "rl78-decode.opc" + ID(and); DR(A); SM(HL, 0); Fz; + + } +@@ -1714,7 +1716,7 @@ + op[0]); + } + SYNTAX("and %0, %ea1"); +-#line 294 "rl78-decode.opc" ++#line 296 "rl78-decode.opc" + ID(and); DR(A); SM(HL, IMMU(1)); Fz; + + } +@@ -1729,7 +1731,7 @@ + op[0]); + } + SYNTAX("and %0, %e!1"); +-#line 285 "rl78-decode.opc" ++#line 287 "rl78-decode.opc" + ID(and); DR(A); SM(None, IMMU(2)); Fz; + + } +@@ -1743,7 +1745,7 @@ + case 0x67: + { + /** 0110 0rba mov %0, %1 */ +-#line 672 "rl78-decode.opc" ++#line 674 "rl78-decode.opc" + int rba AU = op[0] & 0x07; + if (trace) + { +@@ -1753,7 +1755,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("mov %0, %1"); +-#line 672 "rl78-decode.opc" ++#line 674 "rl78-decode.opc" + ID(mov); DR(A); SRB(rba); + + } +@@ -1772,7 +1774,7 @@ + case 0x07: + { + /** 0110 0001 0000 0reg add %0, %1 */ +-#line 225 "rl78-decode.opc" ++#line 227 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -1782,7 +1784,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("add %0, %1"); +-#line 225 "rl78-decode.opc" ++#line 227 "rl78-decode.opc" + ID(add); DRB(reg); SR(A); Fzac; + + } +@@ -1796,7 +1798,7 @@ + case 0x0f: + { + /** 0110 0001 0000 1rba add %0, %1 */ +-#line 219 "rl78-decode.opc" ++#line 221 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -1806,7 +1808,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("add %0, %1"); +-#line 219 "rl78-decode.opc" ++#line 221 "rl78-decode.opc" + ID(add); DR(A); SRB(rba); Fzac; + + } +@@ -1821,7 +1823,7 @@ + op[0], op[1]); + } + SYNTAX("addw %0, %ea1"); +-#line 268 "rl78-decode.opc" ++#line 270 "rl78-decode.opc" + ID(add); W(); DR(AX); SM(HL, IMMU(1)); Fzac; + + } +@@ -1836,7 +1838,7 @@ + case 0x17: + { + /** 0110 0001 0001 0reg addc %0, %1 */ +-#line 254 "rl78-decode.opc" ++#line 256 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -1846,7 +1848,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("addc %0, %1"); +-#line 254 "rl78-decode.opc" ++#line 256 "rl78-decode.opc" + ID(addc); DRB(reg); SR(A); Fzac; + + } +@@ -1860,7 +1862,7 @@ + case 0x1f: + { + /** 0110 0001 0001 1rba addc %0, %1 */ +-#line 251 "rl78-decode.opc" ++#line 253 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -1870,7 +1872,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("addc %0, %1"); +-#line 251 "rl78-decode.opc" ++#line 253 "rl78-decode.opc" + ID(addc); DR(A); SRB(rba); Fzac; + + } +@@ -1885,7 +1887,7 @@ + case 0x27: + { + /** 0110 0001 0010 0reg sub %0, %1 */ +-#line 1143 "rl78-decode.opc" ++#line 1145 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -1895,7 +1897,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("sub %0, %1"); +-#line 1143 "rl78-decode.opc" ++#line 1145 "rl78-decode.opc" + ID(sub); DRB(reg); SR(A); Fzac; + + } +@@ -1909,7 +1911,7 @@ + case 0x2f: + { + /** 0110 0001 0010 1rba sub %0, %1 */ +-#line 1137 "rl78-decode.opc" ++#line 1139 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -1919,7 +1921,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("sub %0, %1"); +-#line 1137 "rl78-decode.opc" ++#line 1139 "rl78-decode.opc" + ID(sub); DR(A); SRB(rba); Fzac; + + } +@@ -1934,7 +1936,7 @@ + op[0], op[1]); + } + SYNTAX("subw %0, %ea1"); +-#line 1186 "rl78-decode.opc" ++#line 1188 "rl78-decode.opc" + ID(sub); W(); DR(AX); SM(HL, IMMU(1)); Fzac; + + } +@@ -1949,7 +1951,7 @@ + case 0x37: + { + /** 0110 0001 0011 0reg subc %0, %1 */ +-#line 1172 "rl78-decode.opc" ++#line 1174 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -1959,7 +1961,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("subc %0, %1"); +-#line 1172 "rl78-decode.opc" ++#line 1174 "rl78-decode.opc" + ID(subc); DRB(reg); SR(A); Fzac; + + } +@@ -1973,7 +1975,7 @@ + case 0x3f: + { + /** 0110 0001 0011 1rba subc %0, %1 */ +-#line 1169 "rl78-decode.opc" ++#line 1171 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -1983,7 +1985,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("subc %0, %1"); +-#line 1169 "rl78-decode.opc" ++#line 1171 "rl78-decode.opc" + ID(subc); DR(A); SRB(rba); Fzac; + + } +@@ -1998,7 +2000,7 @@ + case 0x47: + { + /** 0110 0001 0100 0reg cmp %0, %1 */ +-#line 507 "rl78-decode.opc" ++#line 509 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -2008,7 +2010,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("cmp %0, %1"); +-#line 507 "rl78-decode.opc" ++#line 509 "rl78-decode.opc" + ID(cmp); DRB(reg); SR(A); Fzac; + + } +@@ -2022,7 +2024,7 @@ + case 0x4f: + { + /** 0110 0001 0100 1rba cmp %0, %1 */ +-#line 504 "rl78-decode.opc" ++#line 506 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -2032,7 +2034,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("cmp %0, %1"); +-#line 504 "rl78-decode.opc" ++#line 506 "rl78-decode.opc" + ID(cmp); DR(A); SRB(rba); Fzac; + + } +@@ -2047,7 +2049,7 @@ + op[0], op[1]); + } + SYNTAX("cmpw %0, %ea1"); +-#line 534 "rl78-decode.opc" ++#line 536 "rl78-decode.opc" + ID(cmp); W(); DR(AX); SM(HL, IMMU(1)); Fzac; + + } +@@ -2062,7 +2064,7 @@ + case 0x57: + { + /** 0110 0001 0101 0reg and %0, %1 */ +-#line 306 "rl78-decode.opc" ++#line 308 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -2072,7 +2074,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("and %0, %1"); +-#line 306 "rl78-decode.opc" ++#line 308 "rl78-decode.opc" + ID(and); DRB(reg); SR(A); Fz; + + } +@@ -2086,7 +2088,7 @@ + case 0x5f: + { + /** 0110 0001 0101 1rba and %0, %1 */ +-#line 303 "rl78-decode.opc" ++#line 305 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -2096,7 +2098,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("and %0, %1"); +-#line 303 "rl78-decode.opc" ++#line 305 "rl78-decode.opc" + ID(and); DR(A); SRB(rba); Fz; + + } +@@ -2111,7 +2113,7 @@ + op[0], op[1]); + } + SYNTAX("inc %ea0"); +-#line 584 "rl78-decode.opc" ++#line 586 "rl78-decode.opc" + ID(add); DM(HL, IMMU(1)); SC(1); Fza; + + } +@@ -2126,7 +2128,7 @@ + case 0x67: + { + /** 0110 0001 0110 0reg or %0, %1 */ +-#line 961 "rl78-decode.opc" ++#line 963 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -2136,7 +2138,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("or %0, %1"); +-#line 961 "rl78-decode.opc" ++#line 963 "rl78-decode.opc" + ID(or); DRB(reg); SR(A); Fz; + + } +@@ -2150,7 +2152,7 @@ + case 0x6f: + { + /** 0110 0001 0110 1rba or %0, %1 */ +-#line 958 "rl78-decode.opc" ++#line 960 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -2160,7 +2162,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("or %0, %1"); +-#line 958 "rl78-decode.opc" ++#line 960 "rl78-decode.opc" + ID(or); DR(A); SRB(rba); Fz; + + } +@@ -2175,7 +2177,7 @@ + op[0], op[1]); + } + SYNTAX("dec %ea0"); +-#line 551 "rl78-decode.opc" ++#line 553 "rl78-decode.opc" + ID(sub); DM(HL, IMMU(1)); SC(1); Fza; + + } +@@ -2190,7 +2192,7 @@ + case 0x77: + { + /** 0110 0001 0111 0reg xor %0, %1 */ +-#line 1265 "rl78-decode.opc" ++#line 1267 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -2200,7 +2202,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("xor %0, %1"); +-#line 1265 "rl78-decode.opc" ++#line 1267 "rl78-decode.opc" + ID(xor); DRB(reg); SR(A); Fz; + + } +@@ -2214,7 +2216,7 @@ + case 0x7f: + { + /** 0110 0001 0111 1rba xor %0, %1 */ +-#line 1262 "rl78-decode.opc" ++#line 1264 "rl78-decode.opc" + int rba AU = op[1] & 0x07; + if (trace) + { +@@ -2224,7 +2226,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("xor %0, %1"); +-#line 1262 "rl78-decode.opc" ++#line 1264 "rl78-decode.opc" + ID(xor); DR(A); SRB(rba); Fz; + + } +@@ -2239,7 +2241,7 @@ + op[0], op[1]); + } + SYNTAX("incw %ea0"); +-#line 598 "rl78-decode.opc" ++#line 600 "rl78-decode.opc" + ID(add); W(); DM(HL, IMMU(1)); SC(1); + + } +@@ -2255,7 +2257,7 @@ + op[0], op[1]); + } + SYNTAX("add %0, %e1"); +-#line 207 "rl78-decode.opc" ++#line 209 "rl78-decode.opc" + ID(add); DR(A); SM2(HL, B, 0); Fzac; + + } +@@ -2270,7 +2272,7 @@ + op[0], op[1]); + } + SYNTAX("add %0, %e1"); +-#line 213 "rl78-decode.opc" ++#line 215 "rl78-decode.opc" + ID(add); DR(A); SM2(HL, C, 0); Fzac; + + } +@@ -2309,9 +2311,9 @@ + case 0xf7: + { + /** 0110 0001 1nnn 01mm callt [%x0] */ +-#line 433 "rl78-decode.opc" ++#line 435 "rl78-decode.opc" + int nnn AU = (op[1] >> 4) & 0x07; +-#line 433 "rl78-decode.opc" ++#line 435 "rl78-decode.opc" + int mm AU = op[1] & 0x03; + if (trace) + { +@@ -2322,7 +2324,7 @@ + printf (" mm = 0x%x\n", mm); + } + SYNTAX("callt [%x0]"); +-#line 433 "rl78-decode.opc" ++#line 435 "rl78-decode.opc" + ID(call); DM(None, 0x80 + mm*16 + nnn*2); + + /*----------------------------------------------------------------------*/ +@@ -2338,7 +2340,7 @@ + case 0x8f: + { + /** 0110 0001 1000 1reg xch %0, %1 */ +-#line 1224 "rl78-decode.opc" ++#line 1226 "rl78-decode.opc" + int reg AU = op[1] & 0x07; + if (trace) + { +@@ -2348,7 +2350,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("xch %0, %1"); +-#line 1224 "rl78-decode.opc" ++#line 1226 "rl78-decode.opc" + /* Note: DECW uses reg == X, so this must follow DECW */ + ID(xch); DR(A); SRB(reg); + +@@ -2364,7 +2366,7 @@ + op[0], op[1]); + } + SYNTAX("decw %ea0"); +-#line 565 "rl78-decode.opc" ++#line 567 "rl78-decode.opc" + ID(sub); W(); DM(HL, IMMU(1)); SC(1); + + } +@@ -2379,7 +2381,7 @@ + op[0], op[1]); + } + SYNTAX("addc %0, %e1"); +-#line 239 "rl78-decode.opc" ++#line 241 "rl78-decode.opc" + ID(addc); DR(A); SM2(HL, B, 0); Fzac; + + } +@@ -2394,7 +2396,7 @@ + op[0], op[1]); + } + SYNTAX("addc %0, %e1"); +-#line 242 "rl78-decode.opc" ++#line 244 "rl78-decode.opc" + ID(addc); DR(A); SM2(HL, C, 0); Fzac; + + } +@@ -2410,7 +2412,7 @@ + op[0], op[1]); + } + SYNTAX("sub %0, %e1"); +-#line 1125 "rl78-decode.opc" ++#line 1127 "rl78-decode.opc" + ID(sub); DR(A); SM2(HL, B, 0); Fzac; + + } +@@ -2425,7 +2427,7 @@ + op[0], op[1]); + } + SYNTAX("sub %0, %e1"); +-#line 1131 "rl78-decode.opc" ++#line 1133 "rl78-decode.opc" + ID(sub); DR(A); SM2(HL, C, 0); Fzac; + + } +@@ -2440,7 +2442,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %1"); +-#line 1228 "rl78-decode.opc" ++#line 1230 "rl78-decode.opc" + ID(xch); DR(A); SM(None, SADDR); + + } +@@ -2455,7 +2457,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %e1"); +-#line 1221 "rl78-decode.opc" ++#line 1223 "rl78-decode.opc" + ID(xch); DR(A); SM2(HL, C, 0); + + } +@@ -2470,7 +2472,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %e!1"); +-#line 1203 "rl78-decode.opc" ++#line 1205 "rl78-decode.opc" + ID(xch); DR(A); SM(None, IMMU(2)); + + } +@@ -2485,7 +2487,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %s1"); +-#line 1231 "rl78-decode.opc" ++#line 1233 "rl78-decode.opc" + ID(xch); DR(A); SM(None, SFR); + + } +@@ -2500,7 +2502,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %e1"); +-#line 1212 "rl78-decode.opc" ++#line 1214 "rl78-decode.opc" + ID(xch); DR(A); SM(HL, 0); + + } +@@ -2515,7 +2517,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %ea1"); +-#line 1218 "rl78-decode.opc" ++#line 1220 "rl78-decode.opc" + ID(xch); DR(A); SM(HL, IMMU(1)); + + } +@@ -2530,7 +2532,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %e1"); +-#line 1206 "rl78-decode.opc" ++#line 1208 "rl78-decode.opc" + ID(xch); DR(A); SM(DE, 0); + + } +@@ -2545,7 +2547,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %ea1"); +-#line 1209 "rl78-decode.opc" ++#line 1211 "rl78-decode.opc" + ID(xch); DR(A); SM(DE, IMMU(1)); + + } +@@ -2560,7 +2562,7 @@ + op[0], op[1]); + } + SYNTAX("subc %0, %e1"); +-#line 1157 "rl78-decode.opc" ++#line 1159 "rl78-decode.opc" + ID(subc); DR(A); SM2(HL, B, 0); Fzac; + + } +@@ -2575,7 +2577,7 @@ + op[0], op[1]); + } + SYNTAX("subc %0, %e1"); +-#line 1160 "rl78-decode.opc" ++#line 1162 "rl78-decode.opc" + ID(subc); DR(A); SM2(HL, C, 0); Fzac; + + } +@@ -2590,7 +2592,7 @@ + op[0], op[1]); + } + SYNTAX("mov %0, %1"); +-#line 723 "rl78-decode.opc" ++#line 725 "rl78-decode.opc" + ID(mov); DR(ES); SM(None, SADDR); + + } +@@ -2605,7 +2607,7 @@ + op[0], op[1]); + } + SYNTAX("xch %0, %e1"); +-#line 1215 "rl78-decode.opc" ++#line 1217 "rl78-decode.opc" + ID(xch); DR(A); SM2(HL, B, 0); + + } +@@ -2620,7 +2622,7 @@ + op[0], op[1]); + } + SYNTAX("cmp %0, %e1"); +-#line 492 "rl78-decode.opc" ++#line 494 "rl78-decode.opc" + ID(cmp); DR(A); SM2(HL, B, 0); Fzac; + + } +@@ -2635,7 +2637,7 @@ + op[0], op[1]); + } + SYNTAX("cmp %0, %e1"); +-#line 495 "rl78-decode.opc" ++#line 497 "rl78-decode.opc" + ID(cmp); DR(A); SM2(HL, C, 0); Fzac; + + } +@@ -2650,7 +2652,7 @@ + op[0], op[1]); + } + SYNTAX("bh $%a0"); +-#line 340 "rl78-decode.opc" ++#line 342 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SR(None); COND(H); + + } +@@ -2665,7 +2667,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1094 "rl78-decode.opc" ++#line 1096 "rl78-decode.opc" + ID(skip); COND(C); + + } +@@ -2680,7 +2682,7 @@ + op[0], op[1]); + } + SYNTAX("mov %0, %e1"); +-#line 660 "rl78-decode.opc" ++#line 662 "rl78-decode.opc" + ID(mov); DR(A); SM2(HL, B, 0); + + } +@@ -2691,7 +2693,7 @@ + case 0xfa: + { + /** 0110 0001 11rg 1010 call %0 */ +-#line 430 "rl78-decode.opc" ++#line 432 "rl78-decode.opc" + int rg AU = (op[1] >> 4) & 0x03; + if (trace) + { +@@ -2701,7 +2703,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("call %0"); +-#line 430 "rl78-decode.opc" ++#line 432 "rl78-decode.opc" + ID(call); DRW(rg); + + } +@@ -2716,7 +2718,7 @@ + op[0], op[1]); + } + SYNTAX("br ax"); +-#line 380 "rl78-decode.opc" ++#line 382 "rl78-decode.opc" + ID(branch); DR(AX); + + /*----------------------------------------------------------------------*/ +@@ -2733,7 +2735,7 @@ + op[0], op[1]); + } + SYNTAX("brk"); +-#line 388 "rl78-decode.opc" ++#line 390 "rl78-decode.opc" + ID(break); + + /*----------------------------------------------------------------------*/ +@@ -2750,7 +2752,7 @@ + op[0], op[1]); + } + SYNTAX("pop %s0"); +-#line 989 "rl78-decode.opc" ++#line 991 "rl78-decode.opc" + ID(mov); W(); DR(PSW); SPOP(); + + /*----------------------------------------------------------------------*/ +@@ -2767,7 +2769,7 @@ + op[0], op[1]); + } + SYNTAX("movs %ea0, %1"); +-#line 811 "rl78-decode.opc" ++#line 813 "rl78-decode.opc" + ID(mov); DM(HL, IMMU(1)); SR(X); Fzc; + + /*----------------------------------------------------------------------*/ +@@ -2780,7 +2782,7 @@ + case 0xff: + { + /** 0110 0001 11rb 1111 sel rb%1 */ +-#line 1041 "rl78-decode.opc" ++#line 1043 "rl78-decode.opc" + int rb AU = (op[1] >> 4) & 0x03; + if (trace) + { +@@ -2790,7 +2792,7 @@ + printf (" rb = 0x%x\n", rb); + } + SYNTAX("sel rb%1"); +-#line 1041 "rl78-decode.opc" ++#line 1043 "rl78-decode.opc" + ID(sel); SC(rb); + + /*----------------------------------------------------------------------*/ +@@ -2807,7 +2809,7 @@ + op[0], op[1]); + } + SYNTAX("and %0, %e1"); +-#line 291 "rl78-decode.opc" ++#line 293 "rl78-decode.opc" + ID(and); DR(A); SM2(HL, B, 0); Fz; + + } +@@ -2822,7 +2824,7 @@ + op[0], op[1]); + } + SYNTAX("and %0, %e1"); +-#line 297 "rl78-decode.opc" ++#line 299 "rl78-decode.opc" + ID(and); DR(A); SM2(HL, C, 0); Fz; + + } +@@ -2837,7 +2839,7 @@ + op[0], op[1]); + } + SYNTAX("bnh $%a0"); +-#line 343 "rl78-decode.opc" ++#line 345 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+3); SR(None); COND(NH); + + } +@@ -2852,7 +2854,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1100 "rl78-decode.opc" ++#line 1102 "rl78-decode.opc" + ID(skip); COND(NC); + + } +@@ -2867,7 +2869,7 @@ + op[0], op[1]); + } + SYNTAX("mov %e0, %1"); +-#line 627 "rl78-decode.opc" ++#line 629 "rl78-decode.opc" + ID(mov); DM2(HL, B, 0); SR(A); + + } +@@ -2882,7 +2884,7 @@ + op[0], op[1]); + } + SYNTAX("ror %0, %1"); +-#line 1022 "rl78-decode.opc" ++#line 1024 "rl78-decode.opc" + ID(ror); DR(A); SC(1); + + } +@@ -2897,7 +2899,7 @@ + op[0], op[1]); + } + SYNTAX("rolc %0, %1"); +-#line 1016 "rl78-decode.opc" ++#line 1018 "rl78-decode.opc" + ID(rolc); DR(A); SC(1); + + } +@@ -2912,7 +2914,7 @@ + op[0], op[1]); + } + SYNTAX("push %s1"); +-#line 997 "rl78-decode.opc" ++#line 999 "rl78-decode.opc" + ID(mov); W(); DPUSH(); SR(PSW); + + /*----------------------------------------------------------------------*/ +@@ -2929,7 +2931,7 @@ + op[0], op[1]); + } + SYNTAX("cmps %0, %ea1"); +-#line 526 "rl78-decode.opc" ++#line 528 "rl78-decode.opc" + ID(cmp); DR(X); SM(HL, IMMU(1)); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -2946,7 +2948,7 @@ + op[0], op[1]); + } + SYNTAX("or %0, %e1"); +-#line 946 "rl78-decode.opc" ++#line 948 "rl78-decode.opc" + ID(or); DR(A); SM2(HL, B, 0); Fz; + + } +@@ -2961,7 +2963,7 @@ + op[0], op[1]); + } + SYNTAX("or %0, %e1"); +-#line 952 "rl78-decode.opc" ++#line 954 "rl78-decode.opc" + ID(or); DR(A); SM2(HL, C, 0); Fz; + + } +@@ -2976,7 +2978,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1097 "rl78-decode.opc" ++#line 1099 "rl78-decode.opc" + ID(skip); COND(H); + + } +@@ -2991,7 +2993,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1109 "rl78-decode.opc" ++#line 1111 "rl78-decode.opc" + ID(skip); COND(Z); + + /*----------------------------------------------------------------------*/ +@@ -3008,7 +3010,7 @@ + op[0], op[1]); + } + SYNTAX("mov %0, %e1"); +-#line 663 "rl78-decode.opc" ++#line 665 "rl78-decode.opc" + ID(mov); DR(A); SM2(HL, C, 0); + + } +@@ -3023,7 +3025,7 @@ + op[0], op[1]); + } + SYNTAX("rol %0, %1"); +-#line 1013 "rl78-decode.opc" ++#line 1015 "rl78-decode.opc" + ID(rol); DR(A); SC(1); + + } +@@ -3038,7 +3040,7 @@ + op[0], op[1]); + } + SYNTAX("retb"); +-#line 1008 "rl78-decode.opc" ++#line 1010 "rl78-decode.opc" + ID(reti); + + /*----------------------------------------------------------------------*/ +@@ -3055,7 +3057,7 @@ + op[0], op[1]); + } + SYNTAX("halt"); +-#line 576 "rl78-decode.opc" ++#line 578 "rl78-decode.opc" + ID(halt); + + /*----------------------------------------------------------------------*/ +@@ -3066,7 +3068,7 @@ + case 0xfe: + { + /** 0110 0001 111r 1110 rolwc %0, %1 */ +-#line 1019 "rl78-decode.opc" ++#line 1021 "rl78-decode.opc" + int r AU = (op[1] >> 4) & 0x01; + if (trace) + { +@@ -3076,7 +3078,7 @@ + printf (" r = 0x%x\n", r); + } + SYNTAX("rolwc %0, %1"); +-#line 1019 "rl78-decode.opc" ++#line 1021 "rl78-decode.opc" + ID(rolc); W(); DRW(r); SC(1); + + } +@@ -3091,7 +3093,7 @@ + op[0], op[1]); + } + SYNTAX("xor %0, %e1"); +-#line 1250 "rl78-decode.opc" ++#line 1252 "rl78-decode.opc" + ID(xor); DR(A); SM2(HL, B, 0); Fz; + + } +@@ -3106,7 +3108,7 @@ + op[0], op[1]); + } + SYNTAX("xor %0, %e1"); +-#line 1256 "rl78-decode.opc" ++#line 1258 "rl78-decode.opc" + ID(xor); DR(A); SM2(HL, C, 0); Fz; + + } +@@ -3121,7 +3123,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1103 "rl78-decode.opc" ++#line 1105 "rl78-decode.opc" + ID(skip); COND(NH); + + } +@@ -3136,7 +3138,7 @@ + op[0], op[1]); + } + SYNTAX("sk%c1"); +-#line 1106 "rl78-decode.opc" ++#line 1108 "rl78-decode.opc" + ID(skip); COND(NZ); + + } +@@ -3151,7 +3153,7 @@ + op[0], op[1]); + } + SYNTAX("mov %e0, %1"); +-#line 636 "rl78-decode.opc" ++#line 638 "rl78-decode.opc" + ID(mov); DM2(HL, C, 0); SR(A); + + } +@@ -3166,7 +3168,7 @@ + op[0], op[1]); + } + SYNTAX("rorc %0, %1"); +-#line 1025 "rl78-decode.opc" ++#line 1027 "rl78-decode.opc" + ID(rorc); DR(A); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -3186,7 +3188,7 @@ + op[0], op[1]); + } + SYNTAX("reti"); +-#line 1005 "rl78-decode.opc" ++#line 1007 "rl78-decode.opc" + ID(reti); + + } +@@ -3201,7 +3203,7 @@ + op[0], op[1]); + } + SYNTAX("stop"); +-#line 1114 "rl78-decode.opc" ++#line 1116 "rl78-decode.opc" + ID(stop); + + /*----------------------------------------------------------------------*/ +@@ -3221,7 +3223,7 @@ + op[0]); + } + SYNTAX("movw %e0, %1"); +-#line 874 "rl78-decode.opc" ++#line 876 "rl78-decode.opc" + ID(mov); W(); DM(C, IMMU(2)); SR(AX); + + } +@@ -3236,7 +3238,7 @@ + op[0]); + } + SYNTAX("movw %0, %e1"); +-#line 865 "rl78-decode.opc" ++#line 867 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(C, IMMU(2)); + + } +@@ -3251,7 +3253,7 @@ + op[0]); + } + SYNTAX("or %0, #%1"); +-#line 967 "rl78-decode.opc" ++#line 969 "rl78-decode.opc" + ID(or); DM(None, SADDR); SC(IMMU(1)); Fz; + + /*----------------------------------------------------------------------*/ +@@ -3268,7 +3270,7 @@ + op[0]); + } + SYNTAX("or %0, %1"); +-#line 964 "rl78-decode.opc" ++#line 966 "rl78-decode.opc" + ID(or); DR(A); SM(None, SADDR); Fz; + + } +@@ -3283,7 +3285,7 @@ + op[0]); + } + SYNTAX("or %0, #%1"); +-#line 955 "rl78-decode.opc" ++#line 957 "rl78-decode.opc" + ID(or); DR(A); SC(IMMU(1)); Fz; + + } +@@ -3298,7 +3300,7 @@ + op[0]); + } + SYNTAX("or %0, %e1"); +-#line 943 "rl78-decode.opc" ++#line 945 "rl78-decode.opc" + ID(or); DR(A); SM(HL, 0); Fz; + + } +@@ -3313,7 +3315,7 @@ + op[0]); + } + SYNTAX("or %0, %ea1"); +-#line 949 "rl78-decode.opc" ++#line 951 "rl78-decode.opc" + ID(or); DR(A); SM(HL, IMMU(1)); Fz; + + } +@@ -3328,7 +3330,7 @@ + op[0]); + } + SYNTAX("or %0, %e!1"); +-#line 940 "rl78-decode.opc" ++#line 942 "rl78-decode.opc" + ID(or); DR(A); SM(None, IMMU(2)); Fz; + + } +@@ -3342,7 +3344,7 @@ + case 0x77: + { + /** 0111 0rba mov %0, %1 */ +-#line 696 "rl78-decode.opc" ++#line 698 "rl78-decode.opc" + int rba AU = op[0] & 0x07; + if (trace) + { +@@ -3352,7 +3354,7 @@ + printf (" rba = 0x%x\n", rba); + } + SYNTAX("mov %0, %1"); +-#line 696 "rl78-decode.opc" ++#line 698 "rl78-decode.opc" + ID(mov); DRB(rba); SR(A); + + } +@@ -3371,7 +3373,7 @@ + case 0x70: + { + /** 0111 0001 0bit 0000 set1 %e!0 */ +-#line 1046 "rl78-decode.opc" ++#line 1048 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3381,7 +3383,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("set1 %e!0"); +-#line 1046 "rl78-decode.opc" ++#line 1048 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); DB(bit); SC(1); + + } +@@ -3396,7 +3398,7 @@ + case 0x71: + { + /** 0111 0001 0bit 0001 mov1 %0, cy */ +-#line 803 "rl78-decode.opc" ++#line 805 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3406,7 +3408,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 %0, cy"); +-#line 803 "rl78-decode.opc" ++#line 805 "rl78-decode.opc" + ID(mov); DM(None, SADDR); DB(bit); SCY(); + + } +@@ -3421,7 +3423,7 @@ + case 0x72: + { + /** 0111 0001 0bit 0010 set1 %0 */ +-#line 1064 "rl78-decode.opc" ++#line 1066 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3431,7 +3433,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("set1 %0"); +-#line 1064 "rl78-decode.opc" ++#line 1066 "rl78-decode.opc" + ID(mov); DM(None, SADDR); DB(bit); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -3448,7 +3450,7 @@ + case 0x73: + { + /** 0111 0001 0bit 0011 clr1 %0 */ +-#line 456 "rl78-decode.opc" ++#line 458 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3458,7 +3460,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("clr1 %0"); +-#line 456 "rl78-decode.opc" ++#line 458 "rl78-decode.opc" + ID(mov); DM(None, SADDR); DB(bit); SC(0); + + /*----------------------------------------------------------------------*/ +@@ -3475,7 +3477,7 @@ + case 0x74: + { + /** 0111 0001 0bit 0100 mov1 cy, %1 */ +-#line 797 "rl78-decode.opc" ++#line 799 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3485,7 +3487,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 cy, %1"); +-#line 797 "rl78-decode.opc" ++#line 799 "rl78-decode.opc" + ID(mov); DCY(); SM(None, SADDR); SB(bit); + + } +@@ -3500,7 +3502,7 @@ + case 0x75: + { + /** 0111 0001 0bit 0101 and1 cy, %s1 */ +-#line 326 "rl78-decode.opc" ++#line 328 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3510,7 +3512,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("and1 cy, %s1"); +-#line 326 "rl78-decode.opc" ++#line 328 "rl78-decode.opc" + ID(and); DCY(); SM(None, SADDR); SB(bit); + + /*----------------------------------------------------------------------*/ +@@ -3530,7 +3532,7 @@ + case 0x76: + { + /** 0111 0001 0bit 0110 or1 cy, %s1 */ +-#line 981 "rl78-decode.opc" ++#line 983 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3540,7 +3542,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("or1 cy, %s1"); +-#line 981 "rl78-decode.opc" ++#line 983 "rl78-decode.opc" + ID(or); DCY(); SM(None, SADDR); SB(bit); + + /*----------------------------------------------------------------------*/ +@@ -3557,7 +3559,7 @@ + case 0x77: + { + /** 0111 0001 0bit 0111 xor1 cy, %s1 */ +-#line 1285 "rl78-decode.opc" ++#line 1287 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3567,7 +3569,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("xor1 cy, %s1"); +-#line 1285 "rl78-decode.opc" ++#line 1287 "rl78-decode.opc" + ID(xor); DCY(); SM(None, SADDR); SB(bit); + + /*----------------------------------------------------------------------*/ +@@ -3584,7 +3586,7 @@ + case 0x78: + { + /** 0111 0001 0bit 1000 clr1 %e!0 */ +-#line 438 "rl78-decode.opc" ++#line 440 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3594,7 +3596,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("clr1 %e!0"); +-#line 438 "rl78-decode.opc" ++#line 440 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); DB(bit); SC(0); + + } +@@ -3609,7 +3611,7 @@ + case 0x79: + { + /** 0111 0001 0bit 1001 mov1 %s0, cy */ +-#line 806 "rl78-decode.opc" ++#line 808 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3619,7 +3621,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 %s0, cy"); +-#line 806 "rl78-decode.opc" ++#line 808 "rl78-decode.opc" + ID(mov); DM(None, SFR); DB(bit); SCY(); + + /*----------------------------------------------------------------------*/ +@@ -3636,7 +3638,7 @@ + case 0x7a: + { + /** 0111 0001 0bit 1010 set1 %s0 */ +-#line 1058 "rl78-decode.opc" ++#line 1060 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3646,7 +3648,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("set1 %s0"); +-#line 1058 "rl78-decode.opc" ++#line 1060 "rl78-decode.opc" + op0 = SFR; + ID(mov); DM(None, op0); DB(bit); SC(1); + if (op0 == RL78_SFR_PSW && bit == 7) +@@ -3664,7 +3666,7 @@ + case 0x7b: + { + /** 0111 0001 0bit 1011 clr1 %s0 */ +-#line 450 "rl78-decode.opc" ++#line 452 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3674,7 +3676,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("clr1 %s0"); +-#line 450 "rl78-decode.opc" ++#line 452 "rl78-decode.opc" + op0 = SFR; + ID(mov); DM(None, op0); DB(bit); SC(0); + if (op0 == RL78_SFR_PSW && bit == 7) +@@ -3692,7 +3694,7 @@ + case 0x7c: + { + /** 0111 0001 0bit 1100 mov1 cy, %s1 */ +-#line 800 "rl78-decode.opc" ++#line 802 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3702,7 +3704,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 cy, %s1"); +-#line 800 "rl78-decode.opc" ++#line 802 "rl78-decode.opc" + ID(mov); DCY(); SM(None, SFR); SB(bit); + + } +@@ -3717,7 +3719,7 @@ + case 0x7d: + { + /** 0111 0001 0bit 1101 and1 cy, %s1 */ +-#line 323 "rl78-decode.opc" ++#line 325 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3727,7 +3729,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("and1 cy, %s1"); +-#line 323 "rl78-decode.opc" ++#line 325 "rl78-decode.opc" + ID(and); DCY(); SM(None, SFR); SB(bit); + + } +@@ -3742,7 +3744,7 @@ + case 0x7e: + { + /** 0111 0001 0bit 1110 or1 cy, %s1 */ +-#line 978 "rl78-decode.opc" ++#line 980 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3752,7 +3754,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("or1 cy, %s1"); +-#line 978 "rl78-decode.opc" ++#line 980 "rl78-decode.opc" + ID(or); DCY(); SM(None, SFR); SB(bit); + + } +@@ -3767,7 +3769,7 @@ + case 0x7f: + { + /** 0111 0001 0bit 1111 xor1 cy, %s1 */ +-#line 1282 "rl78-decode.opc" ++#line 1284 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3777,7 +3779,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("xor1 cy, %s1"); +-#line 1282 "rl78-decode.opc" ++#line 1284 "rl78-decode.opc" + ID(xor); DCY(); SM(None, SFR); SB(bit); + + } +@@ -3792,7 +3794,7 @@ + op[0], op[1]); + } + SYNTAX("set1 cy"); +-#line 1055 "rl78-decode.opc" ++#line 1057 "rl78-decode.opc" + ID(mov); DCY(); SC(1); + + } +@@ -3807,7 +3809,7 @@ + case 0xf1: + { + /** 0111 0001 1bit 0001 mov1 %e0, cy */ +-#line 785 "rl78-decode.opc" ++#line 787 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3817,7 +3819,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 %e0, cy"); +-#line 785 "rl78-decode.opc" ++#line 787 "rl78-decode.opc" + ID(mov); DM(HL, 0); DB(bit); SCY(); + + } +@@ -3832,7 +3834,7 @@ + case 0xf2: + { + /** 0111 0001 1bit 0010 set1 %e0 */ +-#line 1049 "rl78-decode.opc" ++#line 1051 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3842,7 +3844,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("set1 %e0"); +-#line 1049 "rl78-decode.opc" ++#line 1051 "rl78-decode.opc" + ID(mov); DM(HL, 0); DB(bit); SC(1); + + } +@@ -3857,7 +3859,7 @@ + case 0xf3: + { + /** 0111 0001 1bit 0011 clr1 %e0 */ +-#line 441 "rl78-decode.opc" ++#line 443 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3867,7 +3869,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("clr1 %e0"); +-#line 441 "rl78-decode.opc" ++#line 443 "rl78-decode.opc" + ID(mov); DM(HL, 0); DB(bit); SC(0); + + } +@@ -3882,7 +3884,7 @@ + case 0xf4: + { + /** 0111 0001 1bit 0100 mov1 cy, %e1 */ +-#line 791 "rl78-decode.opc" ++#line 793 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3892,7 +3894,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 cy, %e1"); +-#line 791 "rl78-decode.opc" ++#line 793 "rl78-decode.opc" + ID(mov); DCY(); SM(HL, 0); SB(bit); + + } +@@ -3907,7 +3909,7 @@ + case 0xf5: + { + /** 0111 0001 1bit 0101 and1 cy, %e1 */ +-#line 317 "rl78-decode.opc" ++#line 319 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3917,7 +3919,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("and1 cy, %e1"); +-#line 317 "rl78-decode.opc" ++#line 319 "rl78-decode.opc" + ID(and); DCY(); SM(HL, 0); SB(bit); + + } +@@ -3932,7 +3934,7 @@ + case 0xf6: + { + /** 0111 0001 1bit 0110 or1 cy, %e1 */ +-#line 972 "rl78-decode.opc" ++#line 974 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3942,7 +3944,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("or1 cy, %e1"); +-#line 972 "rl78-decode.opc" ++#line 974 "rl78-decode.opc" + ID(or); DCY(); SM(HL, 0); SB(bit); + + } +@@ -3957,7 +3959,7 @@ + case 0xf7: + { + /** 0111 0001 1bit 0111 xor1 cy, %e1 */ +-#line 1276 "rl78-decode.opc" ++#line 1278 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -3967,7 +3969,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("xor1 cy, %e1"); +-#line 1276 "rl78-decode.opc" ++#line 1278 "rl78-decode.opc" + ID(xor); DCY(); SM(HL, 0); SB(bit); + + } +@@ -3982,7 +3984,7 @@ + op[0], op[1]); + } + SYNTAX("clr1 cy"); +-#line 447 "rl78-decode.opc" ++#line 449 "rl78-decode.opc" + ID(mov); DCY(); SC(0); + + } +@@ -3997,7 +3999,7 @@ + case 0xf9: + { + /** 0111 0001 1bit 1001 mov1 %e0, cy */ +-#line 788 "rl78-decode.opc" ++#line 790 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4007,7 +4009,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 %e0, cy"); +-#line 788 "rl78-decode.opc" ++#line 790 "rl78-decode.opc" + ID(mov); DR(A); DB(bit); SCY(); + + } +@@ -4022,7 +4024,7 @@ + case 0xfa: + { + /** 0111 0001 1bit 1010 set1 %0 */ +-#line 1052 "rl78-decode.opc" ++#line 1054 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4032,7 +4034,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("set1 %0"); +-#line 1052 "rl78-decode.opc" ++#line 1054 "rl78-decode.opc" + ID(mov); DR(A); DB(bit); SC(1); + + } +@@ -4047,7 +4049,7 @@ + case 0xfb: + { + /** 0111 0001 1bit 1011 clr1 %0 */ +-#line 444 "rl78-decode.opc" ++#line 446 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4057,7 +4059,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("clr1 %0"); +-#line 444 "rl78-decode.opc" ++#line 446 "rl78-decode.opc" + ID(mov); DR(A); DB(bit); SC(0); + + } +@@ -4072,7 +4074,7 @@ + case 0xfc: + { + /** 0111 0001 1bit 1100 mov1 cy, %e1 */ +-#line 794 "rl78-decode.opc" ++#line 796 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4082,7 +4084,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("mov1 cy, %e1"); +-#line 794 "rl78-decode.opc" ++#line 796 "rl78-decode.opc" + ID(mov); DCY(); SR(A); SB(bit); + + } +@@ -4097,7 +4099,7 @@ + case 0xfd: + { + /** 0111 0001 1bit 1101 and1 cy, %1 */ +-#line 320 "rl78-decode.opc" ++#line 322 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4107,7 +4109,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("and1 cy, %1"); +-#line 320 "rl78-decode.opc" ++#line 322 "rl78-decode.opc" + ID(and); DCY(); SR(A); SB(bit); + + } +@@ -4122,7 +4124,7 @@ + case 0xfe: + { + /** 0111 0001 1bit 1110 or1 cy, %1 */ +-#line 975 "rl78-decode.opc" ++#line 977 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4132,7 +4134,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("or1 cy, %1"); +-#line 975 "rl78-decode.opc" ++#line 977 "rl78-decode.opc" + ID(or); DCY(); SR(A); SB(bit); + + } +@@ -4147,7 +4149,7 @@ + case 0xff: + { + /** 0111 0001 1bit 1111 xor1 cy, %1 */ +-#line 1279 "rl78-decode.opc" ++#line 1281 "rl78-decode.opc" + int bit AU = (op[1] >> 4) & 0x07; + if (trace) + { +@@ -4157,7 +4159,7 @@ + printf (" bit = 0x%x\n", bit); + } + SYNTAX("xor1 cy, %1"); +-#line 1279 "rl78-decode.opc" ++#line 1281 "rl78-decode.opc" + ID(xor); DCY(); SR(A); SB(bit); + + } +@@ -4172,7 +4174,7 @@ + op[0], op[1]); + } + SYNTAX("not1 cy"); +-#line 916 "rl78-decode.opc" ++#line 918 "rl78-decode.opc" + ID(xor); DCY(); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -4192,7 +4194,7 @@ + op[0]); + } + SYNTAX("movw %e0, %1"); +-#line 877 "rl78-decode.opc" ++#line 879 "rl78-decode.opc" + ID(mov); W(); DM(BC, IMMU(2)); SR(AX); + + } +@@ -4207,7 +4209,7 @@ + op[0]); + } + SYNTAX("movw %0, %e1"); +-#line 868 "rl78-decode.opc" ++#line 870 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(BC, IMMU(2)); + + } +@@ -4222,7 +4224,7 @@ + op[0]); + } + SYNTAX("xor %0, #%1"); +-#line 1271 "rl78-decode.opc" ++#line 1273 "rl78-decode.opc" + ID(xor); DM(None, SADDR); SC(IMMU(1)); Fz; + + /*----------------------------------------------------------------------*/ +@@ -4239,7 +4241,7 @@ + op[0]); + } + SYNTAX("xor %0, %1"); +-#line 1268 "rl78-decode.opc" ++#line 1270 "rl78-decode.opc" + ID(xor); DR(A); SM(None, SADDR); Fz; + + } +@@ -4254,7 +4256,7 @@ + op[0]); + } + SYNTAX("xor %0, #%1"); +-#line 1259 "rl78-decode.opc" ++#line 1261 "rl78-decode.opc" + ID(xor); DR(A); SC(IMMU(1)); Fz; + + } +@@ -4269,7 +4271,7 @@ + op[0]); + } + SYNTAX("xor %0, %e1"); +-#line 1247 "rl78-decode.opc" ++#line 1249 "rl78-decode.opc" + ID(xor); DR(A); SM(HL, 0); Fz; + + } +@@ -4284,7 +4286,7 @@ + op[0]); + } + SYNTAX("xor %0, %ea1"); +-#line 1253 "rl78-decode.opc" ++#line 1255 "rl78-decode.opc" + ID(xor); DR(A); SM(HL, IMMU(1)); Fz; + + } +@@ -4299,7 +4301,7 @@ + op[0]); + } + SYNTAX("xor %0, %e!1"); +-#line 1244 "rl78-decode.opc" ++#line 1246 "rl78-decode.opc" + ID(xor); DR(A); SM(None, IMMU(2)); Fz; + + } +@@ -4314,7 +4316,7 @@ + case 0x87: + { + /** 1000 0reg inc %0 */ +-#line 587 "rl78-decode.opc" ++#line 589 "rl78-decode.opc" + int reg AU = op[0] & 0x07; + if (trace) + { +@@ -4324,7 +4326,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("inc %0"); +-#line 587 "rl78-decode.opc" ++#line 589 "rl78-decode.opc" + ID(add); DRB(reg); SC(1); Fza; + + } +@@ -4339,7 +4341,7 @@ + op[0]); + } + SYNTAX("mov %0, %ea1"); +-#line 666 "rl78-decode.opc" ++#line 668 "rl78-decode.opc" + ID(mov); DR(A); SM(SP, IMMU(1)); + + } +@@ -4354,7 +4356,7 @@ + op[0]); + } + SYNTAX("mov %0, %e1"); +-#line 648 "rl78-decode.opc" ++#line 650 "rl78-decode.opc" + ID(mov); DR(A); SM(DE, 0); + + } +@@ -4369,7 +4371,7 @@ + op[0]); + } + SYNTAX("mov %0, %ea1"); +-#line 651 "rl78-decode.opc" ++#line 653 "rl78-decode.opc" + ID(mov); DR(A); SM(DE, IMMU(1)); + + } +@@ -4384,7 +4386,7 @@ + op[0]); + } + SYNTAX("mov %0, %e1"); +-#line 654 "rl78-decode.opc" ++#line 656 "rl78-decode.opc" + ID(mov); DR(A); SM(HL, 0); + + } +@@ -4399,7 +4401,7 @@ + op[0]); + } + SYNTAX("mov %0, %ea1"); +-#line 657 "rl78-decode.opc" ++#line 659 "rl78-decode.opc" + ID(mov); DR(A); SM(HL, IMMU(1)); + + } +@@ -4414,7 +4416,7 @@ + op[0]); + } + SYNTAX("mov %0, %1"); +-#line 690 "rl78-decode.opc" ++#line 692 "rl78-decode.opc" + ID(mov); DR(A); SM(None, SADDR); + + } +@@ -4429,7 +4431,7 @@ + op[0]); + } + SYNTAX("mov %0, %s1"); +-#line 687 "rl78-decode.opc" ++#line 689 "rl78-decode.opc" + ID(mov); DR(A); SM(None, SFR); + + } +@@ -4444,7 +4446,7 @@ + op[0]); + } + SYNTAX("mov %0, %e!1"); +-#line 645 "rl78-decode.opc" ++#line 647 "rl78-decode.opc" + ID(mov); DR(A); SM(None, IMMU(2)); + + } +@@ -4459,7 +4461,7 @@ + case 0x97: + { + /** 1001 0reg dec %0 */ +-#line 554 "rl78-decode.opc" ++#line 556 "rl78-decode.opc" + int reg AU = op[0] & 0x07; + if (trace) + { +@@ -4469,7 +4471,7 @@ + printf (" reg = 0x%x\n", reg); + } + SYNTAX("dec %0"); +-#line 554 "rl78-decode.opc" ++#line 556 "rl78-decode.opc" + ID(sub); DRB(reg); SC(1); Fza; + + } +@@ -4484,7 +4486,7 @@ + op[0]); + } + SYNTAX("mov %a0, %1"); +-#line 642 "rl78-decode.opc" ++#line 644 "rl78-decode.opc" + ID(mov); DM(SP, IMMU(1)); SR(A); + + } +@@ -4499,7 +4501,7 @@ + op[0]); + } + SYNTAX("mov %e0, %1"); +-#line 615 "rl78-decode.opc" ++#line 617 "rl78-decode.opc" + ID(mov); DM(DE, 0); SR(A); + + } +@@ -4514,7 +4516,7 @@ + op[0]); + } + SYNTAX("mov %ea0, %1"); +-#line 621 "rl78-decode.opc" ++#line 623 "rl78-decode.opc" + ID(mov); DM(DE, IMMU(1)); SR(A); + + } +@@ -4529,7 +4531,7 @@ + op[0]); + } + SYNTAX("mov %e0, %1"); +-#line 624 "rl78-decode.opc" ++#line 626 "rl78-decode.opc" + ID(mov); DM(HL, 0); SR(A); + + } +@@ -4544,7 +4546,7 @@ + op[0]); + } + SYNTAX("mov %ea0, %1"); +-#line 633 "rl78-decode.opc" ++#line 635 "rl78-decode.opc" + ID(mov); DM(HL, IMMU(1)); SR(A); + + } +@@ -4559,7 +4561,7 @@ + op[0]); + } + SYNTAX("mov %0, %1"); +-#line 747 "rl78-decode.opc" ++#line 749 "rl78-decode.opc" + ID(mov); DM(None, SADDR); SR(A); + + } +@@ -4574,7 +4576,7 @@ + op[0]); + } + SYNTAX("mov %s0, %1"); +-#line 780 "rl78-decode.opc" ++#line 782 "rl78-decode.opc" + ID(mov); DM(None, SFR); SR(A); + + /*----------------------------------------------------------------------*/ +@@ -4591,7 +4593,7 @@ + op[0]); + } + SYNTAX("mov %e!0, %1"); +-#line 612 "rl78-decode.opc" ++#line 614 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); SR(A); + + } +@@ -4606,7 +4608,7 @@ + op[0]); + } + SYNTAX("inc %e!0"); +-#line 581 "rl78-decode.opc" ++#line 583 "rl78-decode.opc" + ID(add); DM(None, IMMU(2)); SC(1); Fza; + + } +@@ -4617,7 +4619,7 @@ + case 0xa7: + { + /** 1010 0rg1 incw %0 */ +-#line 601 "rl78-decode.opc" ++#line 603 "rl78-decode.opc" + int rg AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -4627,7 +4629,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("incw %0"); +-#line 601 "rl78-decode.opc" ++#line 603 "rl78-decode.opc" + ID(add); W(); DRW(rg); SC(1); + + } +@@ -4642,7 +4644,7 @@ + op[0]); + } + SYNTAX("incw %e!0"); +-#line 595 "rl78-decode.opc" ++#line 597 "rl78-decode.opc" + ID(add); W(); DM(None, IMMU(2)); SC(1); + + } +@@ -4657,7 +4659,7 @@ + op[0]); + } + SYNTAX("inc %0"); +-#line 590 "rl78-decode.opc" ++#line 592 "rl78-decode.opc" + ID(add); DM(None, SADDR); SC(1); Fza; + + /*----------------------------------------------------------------------*/ +@@ -4674,7 +4676,7 @@ + op[0]); + } + SYNTAX("incw %0"); +-#line 604 "rl78-decode.opc" ++#line 606 "rl78-decode.opc" + ID(add); W(); DM(None, SADDR); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -4691,7 +4693,7 @@ + op[0]); + } + SYNTAX("movw %0, %a1"); +-#line 850 "rl78-decode.opc" ++#line 852 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(SP, IMMU(1)); + + } +@@ -4706,7 +4708,7 @@ + op[0]); + } + SYNTAX("movw %0, %e1"); +-#line 838 "rl78-decode.opc" ++#line 840 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(DE, 0); + + } +@@ -4721,7 +4723,7 @@ + op[0]); + } + SYNTAX("movw %0, %ea1"); +-#line 841 "rl78-decode.opc" ++#line 843 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(DE, IMMU(1)); + + } +@@ -4736,7 +4738,7 @@ + op[0]); + } + SYNTAX("movw %0, %e1"); +-#line 844 "rl78-decode.opc" ++#line 846 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(HL, 0); + + } +@@ -4751,7 +4753,7 @@ + op[0]); + } + SYNTAX("movw %0, %ea1"); +-#line 847 "rl78-decode.opc" ++#line 849 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(HL, IMMU(1)); + + } +@@ -4766,7 +4768,7 @@ + op[0]); + } + SYNTAX("movw %0, %1"); +-#line 880 "rl78-decode.opc" ++#line 882 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(None, SADDR); + + } +@@ -4781,7 +4783,7 @@ + op[0]); + } + SYNTAX("movw %0, %s1"); +-#line 883 "rl78-decode.opc" ++#line 885 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(None, SFR); + + } +@@ -4796,7 +4798,7 @@ + op[0]); + } + SYNTAX("movw %0, %e!1"); +-#line 834 "rl78-decode.opc" ++#line 836 "rl78-decode.opc" + ID(mov); W(); DR(AX); SM(None, IMMU(2)); + + +@@ -4812,7 +4814,7 @@ + op[0]); + } + SYNTAX("dec %e!0"); +-#line 548 "rl78-decode.opc" ++#line 550 "rl78-decode.opc" + ID(sub); DM(None, IMMU(2)); SC(1); Fza; + + } +@@ -4823,7 +4825,7 @@ + case 0xb7: + { + /** 1011 0rg1 decw %0 */ +-#line 568 "rl78-decode.opc" ++#line 570 "rl78-decode.opc" + int rg AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -4833,7 +4835,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("decw %0"); +-#line 568 "rl78-decode.opc" ++#line 570 "rl78-decode.opc" + ID(sub); W(); DRW(rg); SC(1); + + } +@@ -4848,7 +4850,7 @@ + op[0]); + } + SYNTAX("decw %e!0"); +-#line 562 "rl78-decode.opc" ++#line 564 "rl78-decode.opc" + ID(sub); W(); DM(None, IMMU(2)); SC(1); + + } +@@ -4863,7 +4865,7 @@ + op[0]); + } + SYNTAX("dec %0"); +-#line 557 "rl78-decode.opc" ++#line 559 "rl78-decode.opc" + ID(sub); DM(None, SADDR); SC(1); Fza; + + /*----------------------------------------------------------------------*/ +@@ -4880,7 +4882,7 @@ + op[0]); + } + SYNTAX("decw %0"); +-#line 571 "rl78-decode.opc" ++#line 573 "rl78-decode.opc" + ID(sub); W(); DM(None, SADDR); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -4897,7 +4899,7 @@ + op[0]); + } + SYNTAX("movw %a0, %1"); +-#line 831 "rl78-decode.opc" ++#line 833 "rl78-decode.opc" + ID(mov); W(); DM(SP, IMMU(1)); SR(AX); + + } +@@ -4912,7 +4914,7 @@ + op[0]); + } + SYNTAX("movw %e0, %1"); +-#line 819 "rl78-decode.opc" ++#line 821 "rl78-decode.opc" + ID(mov); W(); DM(DE, 0); SR(AX); + + } +@@ -4927,7 +4929,7 @@ + op[0]); + } + SYNTAX("movw %ea0, %1"); +-#line 822 "rl78-decode.opc" ++#line 824 "rl78-decode.opc" + ID(mov); W(); DM(DE, IMMU(1)); SR(AX); + + } +@@ -4942,7 +4944,7 @@ + op[0]); + } + SYNTAX("movw %e0, %1"); +-#line 825 "rl78-decode.opc" ++#line 827 "rl78-decode.opc" + ID(mov); W(); DM(HL, 0); SR(AX); + + } +@@ -4957,7 +4959,7 @@ + op[0]); + } + SYNTAX("movw %ea0, %1"); +-#line 828 "rl78-decode.opc" ++#line 830 "rl78-decode.opc" + ID(mov); W(); DM(HL, IMMU(1)); SR(AX); + + } +@@ -4972,7 +4974,7 @@ + op[0]); + } + SYNTAX("movw %0, %1"); +-#line 895 "rl78-decode.opc" ++#line 897 "rl78-decode.opc" + ID(mov); W(); DM(None, SADDR); SR(AX); + + } +@@ -4987,7 +4989,7 @@ + op[0]); + } + SYNTAX("movw %s0, %1"); +-#line 901 "rl78-decode.opc" ++#line 903 "rl78-decode.opc" + ID(mov); W(); DM(None, SFR); SR(AX); + + /*----------------------------------------------------------------------*/ +@@ -5004,7 +5006,7 @@ + op[0]); + } + SYNTAX("movw %e!0, %1"); +-#line 816 "rl78-decode.opc" ++#line 818 "rl78-decode.opc" + ID(mov); W(); DM(None, IMMU(2)); SR(AX); + + } +@@ -5015,7 +5017,7 @@ + case 0xc6: + { + /** 1100 0rg0 pop %0 */ +-#line 986 "rl78-decode.opc" ++#line 988 "rl78-decode.opc" + int rg AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -5025,7 +5027,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("pop %0"); +-#line 986 "rl78-decode.opc" ++#line 988 "rl78-decode.opc" + ID(mov); W(); DRW(rg); SPOP(); + + } +@@ -5036,7 +5038,7 @@ + case 0xc7: + { + /** 1100 0rg1 push %1 */ +-#line 994 "rl78-decode.opc" ++#line 996 "rl78-decode.opc" + int rg AU = (op[0] >> 1) & 0x03; + if (trace) + { +@@ -5046,7 +5048,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("push %1"); +-#line 994 "rl78-decode.opc" ++#line 996 "rl78-decode.opc" + ID(mov); W(); DPUSH(); SRW(rg); + + } +@@ -5061,7 +5063,7 @@ + op[0]); + } + SYNTAX("mov %a0, #%1"); +-#line 639 "rl78-decode.opc" ++#line 641 "rl78-decode.opc" + ID(mov); DM(SP, IMMU(1)); SC(IMMU(1)); + + } +@@ -5076,7 +5078,7 @@ + op[0]); + } + SYNTAX("movw %0, #%1"); +-#line 892 "rl78-decode.opc" ++#line 894 "rl78-decode.opc" + ID(mov); W(); DM(None, SADDR); SC(IMMU(2)); + + } +@@ -5091,7 +5093,7 @@ + op[0]); + } + SYNTAX("mov %ea0, #%1"); +-#line 618 "rl78-decode.opc" ++#line 620 "rl78-decode.opc" + ID(mov); DM(DE, IMMU(1)); SC(IMMU(1)); + + } +@@ -5106,7 +5108,7 @@ + op[0]); + } + SYNTAX("movw %s0, #%1"); +-#line 898 "rl78-decode.opc" ++#line 900 "rl78-decode.opc" + ID(mov); W(); DM(None, SFR); SC(IMMU(2)); + + } +@@ -5121,7 +5123,7 @@ + op[0]); + } + SYNTAX("mov %ea0, #%1"); +-#line 630 "rl78-decode.opc" ++#line 632 "rl78-decode.opc" + ID(mov); DM(HL, IMMU(1)); SC(IMMU(1)); + + } +@@ -5136,7 +5138,7 @@ + op[0]); + } + SYNTAX("mov %0, #%1"); +-#line 744 "rl78-decode.opc" ++#line 746 "rl78-decode.opc" + ID(mov); DM(None, SADDR); SC(IMMU(1)); + + } +@@ -5151,7 +5153,7 @@ + op[0]); + } + SYNTAX("mov %s0, #%1"); +-#line 750 "rl78-decode.opc" ++#line 752 "rl78-decode.opc" + op0 = SFR; + op1 = IMMU(1); + ID(mov); DM(None, op0); SC(op1); +@@ -5193,7 +5195,7 @@ + op[0]); + } + SYNTAX("mov %e!0, #%1"); +-#line 609 "rl78-decode.opc" ++#line 611 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); SC(IMMU(1)); + + } +@@ -5204,7 +5206,7 @@ + case 0xd3: + { + /** 1101 00rg cmp0 %0 */ +-#line 518 "rl78-decode.opc" ++#line 520 "rl78-decode.opc" + int rg AU = op[0] & 0x03; + if (trace) + { +@@ -5214,7 +5216,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("cmp0 %0"); +-#line 518 "rl78-decode.opc" ++#line 520 "rl78-decode.opc" + ID(cmp); DRB(rg); SC(0); Fzac; + + } +@@ -5229,7 +5231,7 @@ + op[0]); + } + SYNTAX("cmp0 %0"); +-#line 521 "rl78-decode.opc" ++#line 523 "rl78-decode.opc" + ID(cmp); DM(None, SADDR); SC(0); Fzac; + + /*----------------------------------------------------------------------*/ +@@ -5246,7 +5248,7 @@ + op[0]); + } + SYNTAX("cmp0 %e!0"); +-#line 515 "rl78-decode.opc" ++#line 517 "rl78-decode.opc" + ID(cmp); DM(None, IMMU(2)); SC(0); Fzac; + + } +@@ -5261,7 +5263,7 @@ + op[0]); + } + SYNTAX("mulu x"); +-#line 906 "rl78-decode.opc" ++#line 908 "rl78-decode.opc" + ID(mulu); + + /*----------------------------------------------------------------------*/ +@@ -5278,7 +5280,7 @@ + op[0]); + } + SYNTAX("ret"); +-#line 1002 "rl78-decode.opc" ++#line 1004 "rl78-decode.opc" + ID(ret); + + } +@@ -5293,7 +5295,7 @@ + op[0]); + } + SYNTAX("mov %0, %1"); +-#line 711 "rl78-decode.opc" ++#line 713 "rl78-decode.opc" + ID(mov); DR(X); SM(None, SADDR); + + } +@@ -5308,7 +5310,7 @@ + op[0]); + } + SYNTAX("mov %0, %e!1"); +-#line 708 "rl78-decode.opc" ++#line 710 "rl78-decode.opc" + ID(mov); DR(X); SM(None, IMMU(2)); + + } +@@ -5318,7 +5320,7 @@ + case 0xfa: + { + /** 11ra 1010 movw %0, %1 */ +-#line 889 "rl78-decode.opc" ++#line 891 "rl78-decode.opc" + int ra AU = (op[0] >> 4) & 0x03; + if (trace) + { +@@ -5328,7 +5330,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("movw %0, %1"); +-#line 889 "rl78-decode.opc" ++#line 891 "rl78-decode.opc" + ID(mov); W(); DRW(ra); SM(None, SADDR); + + } +@@ -5338,7 +5340,7 @@ + case 0xfb: + { + /** 11ra 1011 movw %0, %es!1 */ +-#line 886 "rl78-decode.opc" ++#line 888 "rl78-decode.opc" + int ra AU = (op[0] >> 4) & 0x03; + if (trace) + { +@@ -5348,7 +5350,7 @@ + printf (" ra = 0x%x\n", ra); + } + SYNTAX("movw %0, %es!1"); +-#line 886 "rl78-decode.opc" ++#line 888 "rl78-decode.opc" + ID(mov); W(); DRW(ra); SM(None, IMMU(2)); + + } +@@ -5363,7 +5365,7 @@ + op[0]); + } + SYNTAX("bc $%a0"); +-#line 334 "rl78-decode.opc" ++#line 336 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+2); SR(None); COND(C); + + } +@@ -5378,7 +5380,7 @@ + op[0]); + } + SYNTAX("bz $%a0"); +-#line 346 "rl78-decode.opc" ++#line 348 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+2); SR(None); COND(Z); + + } +@@ -5393,7 +5395,7 @@ + op[0]); + } + SYNTAX("bnc $%a0"); +-#line 337 "rl78-decode.opc" ++#line 339 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+2); SR(None); COND(NC); + + } +@@ -5408,7 +5410,7 @@ + op[0]); + } + SYNTAX("bnz $%a0"); +-#line 349 "rl78-decode.opc" ++#line 351 "rl78-decode.opc" + ID(branch_cond); DC(pc+IMMS(1)+2); SR(None); COND(NZ); + + /*----------------------------------------------------------------------*/ +@@ -5421,7 +5423,7 @@ + case 0xe3: + { + /** 1110 00rg oneb %0 */ +-#line 924 "rl78-decode.opc" ++#line 926 "rl78-decode.opc" + int rg AU = op[0] & 0x03; + if (trace) + { +@@ -5431,7 +5433,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("oneb %0"); +-#line 924 "rl78-decode.opc" ++#line 926 "rl78-decode.opc" + ID(mov); DRB(rg); SC(1); + + } +@@ -5446,7 +5448,7 @@ + op[0]); + } + SYNTAX("oneb %0"); +-#line 927 "rl78-decode.opc" ++#line 929 "rl78-decode.opc" + ID(mov); DM(None, SADDR); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -5463,7 +5465,7 @@ + op[0]); + } + SYNTAX("oneb %e!0"); +-#line 921 "rl78-decode.opc" ++#line 923 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); SC(1); + + } +@@ -5478,7 +5480,7 @@ + op[0]); + } + SYNTAX("onew %0"); +-#line 932 "rl78-decode.opc" ++#line 934 "rl78-decode.opc" + ID(mov); DR(AX); SC(1); + + } +@@ -5493,7 +5495,7 @@ + op[0]); + } + SYNTAX("onew %0"); +-#line 935 "rl78-decode.opc" ++#line 937 "rl78-decode.opc" + ID(mov); DR(BC); SC(1); + + /*----------------------------------------------------------------------*/ +@@ -5510,7 +5512,7 @@ + op[0]); + } + SYNTAX("mov %0, %1"); +-#line 699 "rl78-decode.opc" ++#line 701 "rl78-decode.opc" + ID(mov); DR(B); SM(None, SADDR); + + } +@@ -5525,7 +5527,7 @@ + op[0]); + } + SYNTAX("mov %0, %e!1"); +-#line 693 "rl78-decode.opc" ++#line 695 "rl78-decode.opc" + ID(mov); DR(B); SM(None, IMMU(2)); + + } +@@ -5540,7 +5542,7 @@ + op[0]); + } + SYNTAX("br !%!a0"); +-#line 368 "rl78-decode.opc" ++#line 370 "rl78-decode.opc" + ID(branch); DC(IMMU(3)); + + } +@@ -5555,7 +5557,7 @@ + op[0]); + } + SYNTAX("br %!a0"); +-#line 371 "rl78-decode.opc" ++#line 373 "rl78-decode.opc" + ID(branch); DC(IMMU(2)); + + } +@@ -5570,7 +5572,7 @@ + op[0]); + } + SYNTAX("br $%!a0"); +-#line 374 "rl78-decode.opc" ++#line 376 "rl78-decode.opc" + ID(branch); DC(pc+IMMS(2)+3); + + } +@@ -5585,7 +5587,7 @@ + op[0]); + } + SYNTAX("br $%a0"); +-#line 377 "rl78-decode.opc" ++#line 379 "rl78-decode.opc" + ID(branch); DC(pc+IMMS(1)+2); + + } +@@ -5596,7 +5598,7 @@ + case 0xf3: + { + /** 1111 00rg clrb %0 */ +-#line 464 "rl78-decode.opc" ++#line 466 "rl78-decode.opc" + int rg AU = op[0] & 0x03; + if (trace) + { +@@ -5606,7 +5608,7 @@ + printf (" rg = 0x%x\n", rg); + } + SYNTAX("clrb %0"); +-#line 464 "rl78-decode.opc" ++#line 466 "rl78-decode.opc" + ID(mov); DRB(rg); SC(0); + + } +@@ -5621,7 +5623,7 @@ + op[0]); + } + SYNTAX("clrb %0"); +-#line 467 "rl78-decode.opc" ++#line 469 "rl78-decode.opc" + ID(mov); DM(None, SADDR); SC(0); + + /*----------------------------------------------------------------------*/ +@@ -5638,7 +5640,7 @@ + op[0]); + } + SYNTAX("clrb %e!0"); +-#line 461 "rl78-decode.opc" ++#line 463 "rl78-decode.opc" + ID(mov); DM(None, IMMU(2)); SC(0); + + } +@@ -5653,7 +5655,7 @@ + op[0]); + } + SYNTAX("clrw %0"); +-#line 472 "rl78-decode.opc" ++#line 474 "rl78-decode.opc" + ID(mov); DR(AX); SC(0); + + } +@@ -5668,7 +5670,7 @@ + op[0]); + } + SYNTAX("clrw %0"); +-#line 475 "rl78-decode.opc" ++#line 477 "rl78-decode.opc" + ID(mov); DR(BC); SC(0); + + /*----------------------------------------------------------------------*/ +@@ -5685,7 +5687,7 @@ + op[0]); + } + SYNTAX("mov %0, %1"); +-#line 705 "rl78-decode.opc" ++#line 707 "rl78-decode.opc" + ID(mov); DR(C); SM(None, SADDR); + + } +@@ -5700,7 +5702,7 @@ + op[0]); + } + SYNTAX("mov %0, %e!1"); +-#line 702 "rl78-decode.opc" ++#line 704 "rl78-decode.opc" + ID(mov); DR(C); SM(None, IMMU(2)); + + } +@@ -5715,7 +5717,7 @@ + op[0]); + } + SYNTAX("call !%!a0"); +-#line 421 "rl78-decode.opc" ++#line 423 "rl78-decode.opc" + ID(call); DC(IMMU(3)); + + } +@@ -5730,7 +5732,7 @@ + op[0]); + } + SYNTAX("call %!a0"); +-#line 424 "rl78-decode.opc" ++#line 426 "rl78-decode.opc" + ID(call); DC(IMMU(2)); + + } +@@ -5745,7 +5747,7 @@ + op[0]); + } + SYNTAX("call $%!a0"); +-#line 427 "rl78-decode.opc" ++#line 429 "rl78-decode.opc" + ID(call); DC(pc+IMMS(2)+3); + + } +@@ -5760,13 +5762,13 @@ + op[0]); + } + SYNTAX("brk1"); +-#line 385 "rl78-decode.opc" ++#line 387 "rl78-decode.opc" + ID(break); + + } + break; + } +-#line 1290 "rl78-decode.opc" ++#line 1292 "rl78-decode.opc" + + return rl78->n_bytes; + } +Index: git/opcodes/rl78-decode.opc +=================================================================== +--- git.orig/opcodes/rl78-decode.opc 2017-09-21 13:14:42.256835775 +0530 ++++ git/opcodes/rl78-decode.opc 2017-09-21 13:14:49.444888350 +0530 +@@ -50,7 +50,9 @@ + #define W() rl78->size = RL78_Word + + #define AU ATTRIBUTE_UNUSED +-#define GETBYTE() (ld->op [ld->rl78->n_bytes++] = ld->getbyte (ld->ptr)) ++ ++#define OP_BUF_LEN 20 ++#define GETBYTE() (ld->rl78->n_bytes < (OP_BUF_LEN - 1) ? ld->op [ld->rl78->n_bytes++] = ld->getbyte (ld->ptr): 0) + #define B ((unsigned long) GETBYTE()) + + #define SYNTAX(x) rl78->syntax = x +@@ -168,7 +170,7 @@ + RL78_Dis_Isa isa) + { + LocalData lds, * ld = &lds; +- unsigned char op_buf[20] = {0}; ++ unsigned char op_buf[OP_BUF_LEN] = {0}; + unsigned char *op = op_buf; + int op0, op1; + +Index: git/opcodes/ChangeLog +=================================================================== +--- git.orig/opcodes/ChangeLog 2017-09-21 13:14:41.676831533 +0530 ++++ git/opcodes/ChangeLog 2017-09-21 13:16:51.065779064 +0530 +@@ -1,3 +1,12 @@ ++2017-06-15 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21588 ++ * rl78-decode.opc (OP_BUF_LEN): Define. ++ (GETBYTE): Check for the index exceeding OP_BUF_LEN. ++ (rl78_decode_opcode): Use OP_BUF_LEN as the length of the op_buf ++ array. ++ * rl78-decode.c: Regenerate. ++ + 2016-08-03 Tristan Gingold <gingold@adacore.com> + + * configure: Regenerate. diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9752.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9752.patch new file mode 100644 index 0000000000..fce5b14b20 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9752.patch @@ -0,0 +1,204 @@ +commit c53d2e6d744da000aaafe0237bced090aab62818 +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jun 14 11:27:15 2017 +0100 + + Fix potential address violations when processing a corrupt Alpha VMA binary. + + PR binutils/21589 + * vms-alpha.c (_bfd_vms_get_value): Add an extra parameter - the + maximum value for the ascic pointer. Check that name processing + does not read beyond this value. + (_bfd_vms_slurp_etir): Add checks for attempts to read beyond the + end of etir record. + +Upstream-Status: Backport + +CVE: CVE-2017-9752 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/vms-alpha.c +=================================================================== +--- git.orig/bfd/vms-alpha.c 2017-09-21 15:00:19.117805347 +0530 ++++ git/bfd/vms-alpha.c 2017-09-21 15:00:20.673815960 +0530 +@@ -1507,7 +1507,7 @@ + /* Write multiple bytes to section image. */ + + static bfd_boolean +-image_write (bfd *abfd, unsigned char *ptr, int size) ++image_write (bfd *abfd, unsigned char *ptr, unsigned int size) + { + #if VMS_DEBUG + _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size, +@@ -1654,14 +1654,16 @@ + #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L) + + static void +-_bfd_vms_get_value (bfd *abfd, const unsigned char *ascic, ++_bfd_vms_get_value (bfd *abfd, ++ const unsigned char *ascic, ++ const unsigned char *max_ascic, + struct bfd_link_info *info, + bfd_vma *vma, + struct alpha_vms_link_hash_entry **hp) + { + char name[257]; +- int len; +- int i; ++ unsigned int len; ++ unsigned int i; + struct alpha_vms_link_hash_entry *h; + + /* Not linking. Do not try to resolve the symbol. */ +@@ -1673,6 +1675,14 @@ + } + + len = *ascic; ++ if (ascic + len >= max_ascic) ++ { ++ _bfd_error_handler (_("Corrupt vms value")); ++ *vma = 0; ++ *hp = NULL; ++ return; ++ } ++ + for (i = 0; i < len; i++) + name[i] = ascic[i + 1]; + name[i] = 0; +@@ -1797,6 +1807,15 @@ + _bfd_hexdump (8, ptr, cmd_length - 4, 0); + #endif + ++ /* PR 21589: Check for a corrupt ETIR record. */ ++ if (cmd_length < 4) ++ { ++ corrupt_etir: ++ _bfd_error_handler (_("Corrupt ETIR record encountered")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ + switch (cmd) + { + /* Stack global +@@ -1804,7 +1823,7 @@ + + stack 32 bit value of symbol (high bits set to 0). */ + case ETIR__C_STA_GBL: +- _bfd_vms_get_value (abfd, ptr, info, &op1, &h); ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)); + break; + +@@ -1813,6 +1832,8 @@ + + stack 32 bit value, sign extend to 64 bit. */ + case ETIR__C_STA_LW: ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; + _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE); + break; + +@@ -1821,6 +1842,8 @@ + + stack 64 bit value of symbol. */ + case ETIR__C_STA_QW: ++ if (ptr + 8 >= maxptr) ++ goto corrupt_etir; + _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE); + break; + +@@ -1834,6 +1857,8 @@ + { + int psect; + ++ if (ptr + 12 >= maxptr) ++ goto corrupt_etir; + psect = bfd_getl32 (ptr); + if ((unsigned int) psect >= PRIV (section_count)) + { +@@ -1923,6 +1948,8 @@ + { + int size; + ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; + size = bfd_getl32 (ptr); + _bfd_vms_pop (abfd, &op1, &rel1); + if (rel1 != RELC_NONE) +@@ -1935,7 +1962,7 @@ + /* Store global: write symbol value + arg: cs global symbol name. */ + case ETIR__C_STO_GBL: +- _bfd_vms_get_value (abfd, ptr, info, &op1, &h); ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + if (h && h->sym) + { + if (h->sym->typ == EGSD__C_SYMG) +@@ -1957,7 +1984,7 @@ + /* Store code address: write address of entry point + arg: cs global symbol name (procedure). */ + case ETIR__C_STO_CA: +- _bfd_vms_get_value (abfd, ptr, info, &op1, &h); ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + if (h && h->sym) + { + if (h->sym->flags & EGSY__V_NORM) +@@ -2002,8 +2029,10 @@ + da data. */ + case ETIR__C_STO_IMM: + { +- int size; ++ unsigned int size; + ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; + size = bfd_getl32 (ptr); + image_write (abfd, ptr + 4, size); + } +@@ -2016,7 +2045,7 @@ + store global longword: store 32bit value of symbol + arg: cs symbol name. */ + case ETIR__C_STO_GBL_LW: +- _bfd_vms_get_value (abfd, ptr, info, &op1, &h); ++ _bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h); + #if 0 + abort (); + #endif +@@ -2069,7 +2098,7 @@ + da signature. */ + + case ETIR__C_STC_LP_PSB: +- _bfd_vms_get_value (abfd, ptr + 4, info, &op1, &h); ++ _bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h); + if (h && h->sym) + { + if (h->sym->typ == EGSD__C_SYMG) +@@ -2165,6 +2194,8 @@ + /* Augment relocation base: increment image location counter by offset + arg: lw offset value. */ + case ETIR__C_CTL_AUGRB: ++ if (ptr + 4 >= maxptr) ++ goto corrupt_etir; + op1 = bfd_getl32 (ptr); + image_inc_ptr (abfd, op1); + break; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 15:04:44.000000000 +0530 ++++ git/bfd/ChangeLog 2017-09-21 15:07:58.268949291 +0530 +@@ -81,6 +81,15 @@ + PR binutils/21581 + (ieee_archive_p): Likewise. + ++2017-06-14 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21589 ++ * vms-alpha.c (_bfd_vms_get_value): Add an extra parameter - the ++ maximum value for the ascic pointer. Check that name processing ++ does not read beyond this value. ++ (_bfd_vms_slurp_etir): Add checks for attempts to read beyond the ++ end of etir record. ++ + 2017-04-29 Alan Modra <amodra@gmail.com> + + PR 21432 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9753_9754.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9753_9754.patch new file mode 100644 index 0000000000..fe1f9a100d --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9753_9754.patch @@ -0,0 +1,76 @@ +commit 04f963fd489cae724a60140e13984415c205f4ac +Author: Nick Clifton <nickc@redhat.com> +Date: Wed Jun 14 10:35:16 2017 +0100 + + Fix seg-faults in objdump when disassembling a corrupt versados binary. + + PR binutils/21591 + * versados.c (versados_mkobject): Zero the allocated tdata structure. + (process_otr): Check for an invalid offset in the otr structure. + +Upstream-Status: Backport + +CVE: CVE-2017-9753 and CVE-2017-9754 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/versados.c +=================================================================== +--- git.orig/bfd/versados.c 2017-09-21 15:08:34.445197987 +0530 ++++ git/bfd/versados.c 2017-09-21 15:08:34.429197878 +0530 +@@ -149,7 +149,7 @@ + if (abfd->tdata.versados_data == NULL) + { + bfd_size_type amt = sizeof (tdata_type); +- tdata_type *tdata = bfd_alloc (abfd, amt); ++ tdata_type *tdata = bfd_zalloc (abfd, amt); + + if (tdata == NULL) + return FALSE; +@@ -344,13 +344,13 @@ + }; + + static int +-get_offset (int len, unsigned char *ptr) ++get_offset (unsigned int len, unsigned char *ptr) + { + int val = 0; + + if (len) + { +- int i; ++ unsigned int i; + + val = *ptr++; + if (val & 0x80) +@@ -393,9 +393,13 @@ + int flag = *srcp++; + int esdids = (flag >> 5) & 0x7; + int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; +- int offsetlen = flag & 0x7; ++ unsigned int offsetlen = flag & 0x7; + int j; + ++ /* PR 21591: Check for invalid lengths. */ ++ if (srcp + esdids + offsetlen >= endp) ++ return; ++ + if (esdids == 0) + { + /* A zero esdid means the new pc is the offset given. */ +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 15:08:34.445197987 +0530 ++++ git/bfd/ChangeLog 2017-09-21 15:08:34.429197878 +0530 +@@ -90,6 +90,12 @@ + (_bfd_vms_slurp_etir): Add checks for attempts to read beyond the + end of etir record. + ++2017-06-14 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21591 ++ * versados.c (versados_mkobject): Zero the allocated tdata structure. ++ (process_otr): Check for an invalid offset in the otr structure. ++ + 2017-04-29 Alan Modra <amodra@gmail.com> + + PR 21432 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_1.patch new file mode 100644 index 0000000000..3ad32189b1 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_1.patch @@ -0,0 +1,60 @@ +commit 0d96e4df4812c3bad77c229dfef47a9bc115ac12 +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Thu Jun 15 06:40:17 2017 -0700 + + i386-dis: Check valid bnd register + + Since there are only 4 bnd registers, return "(bad)" for register + number > 3. + + PR binutils/21594 + * i386-dis.c (OP_E_register): Check valid bnd register. + (OP_G): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-9755 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/opcodes/i386-dis.c +=================================================================== +--- git.orig/opcodes/i386-dis.c 2017-09-21 15:38:46.907182525 +0530 ++++ git/opcodes/i386-dis.c 2017-09-21 15:38:54.703174976 +0530 +@@ -15211,6 +15211,11 @@ + names = address_mode == mode_64bit ? names64 : names32; + break; + case bnd_mode: ++ if (reg > 0x3) ++ { ++ oappend ("(bad)"); ++ return; ++ } + names = names_bnd; + break; + case indir_v_mode: +@@ -15751,6 +15756,11 @@ + oappend (names64[modrm.reg + add]); + break; + case bnd_mode: ++ if (modrm.reg > 0x3) ++ { ++ oappend ("(bad)"); ++ return; ++ } + oappend (names_bnd[modrm.reg]); + break; + case v_mode: +Index: git/opcodes/ChangeLog +=================================================================== +--- git.orig/opcodes/ChangeLog 2017-09-21 15:38:54.531175122 +0530 ++++ git/opcodes/ChangeLog 2017-09-21 15:45:32.264491166 +0530 +@@ -1,3 +1,9 @@ ++2017-06-15 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21594 ++ * i386-dis.c (OP_E_register): Check valid bnd register. ++ (OP_G): Likewise. ++ + 2017-06-15 Nick Clifton <nickc@redhat.com> + + PR binutils/21586 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_2.patch new file mode 100644 index 0000000000..69e1607d8b --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9755_2.patch @@ -0,0 +1,101 @@ +commit 8cac017d35ef374e65acc98818a17cf8a652cbd0 +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Thu Jun 15 08:21:48 2017 -0700 + + i386-dis: Add 2 tests with invalid bnd register + + PR binutils/21594 + * testsuite/gas/i386/mpx.s: Add 2 tests with invalid bnd + register. + * testsuite/gas/i386/x86-64-mpx.s: Likewise. + * testsuite/gas/i386/mpx.d: Updated. + * testsuite/gas/i386/x86-64-mpx.d: Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-9755 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/gas/testsuite/gas/i386/mpx.d +=================================================================== +--- git.orig/gas/testsuite/gas/i386/mpx.d 2017-09-21 15:45:57.640640603 +0530 ++++ git/gas/testsuite/gas/i386/mpx.d 2017-09-21 15:45:57.616640460 +0530 +@@ -130,4 +130,8 @@ + + [a-f0-9]+ <foo>: + [ ]*[a-f0-9]+: f2 c3 bnd ret ++ ++[a-f0-9]+ <bad>: ++[ ]*[a-f0-9]+: 0f 1a 30 bndldx \(%eax\),\(bad\) ++[ ]*[a-f0-9]+: 66 0f 1a c4 bndmov \(bad\),%bnd0 + #pass +Index: git/gas/testsuite/gas/i386/mpx.s +=================================================================== +--- git.orig/gas/testsuite/gas/i386/mpx.s 2017-09-21 15:45:57.640640603 +0530 ++++ git/gas/testsuite/gas/i386/mpx.s 2017-09-21 15:45:57.616640460 +0530 +@@ -157,3 +157,15 @@ + bnd ret + + foo: bnd ret ++ ++bad: ++ # bndldx (%eax),(bad) ++ .byte 0x0f ++ .byte 0x1a ++ .byte 0x30 ++ ++ # bndmov (bad),%bnd0 ++ .byte 0x66 ++ .byte 0x0f ++ .byte 0x1a ++ .byte 0xc4 +Index: git/gas/testsuite/gas/i386/x86-64-mpx.d +=================================================================== +--- git.orig/gas/testsuite/gas/i386/x86-64-mpx.d 2017-09-21 15:45:57.640640603 +0530 ++++ git/gas/testsuite/gas/i386/x86-64-mpx.d 2017-09-21 15:45:57.616640460 +0530 +@@ -182,4 +182,8 @@ + + [a-f0-9]+ <foo>: + [ ]*[a-f0-9]+: f2 c3 bnd retq ++ ++[a-f0-9]+ <bad>: ++[ ]*[a-f0-9]+: 0f 1a 30 bndldx \(%rax\),\(bad\) ++[ ]*[a-f0-9]+: 66 0f 1a c4 bndmov \(bad\),%bnd0 + #pass +Index: git/gas/testsuite/gas/i386/x86-64-mpx.s +=================================================================== +--- git.orig/gas/testsuite/gas/i386/x86-64-mpx.s 2017-09-21 15:45:57.640640603 +0530 ++++ git/gas/testsuite/gas/i386/x86-64-mpx.s 2017-09-21 15:45:57.616640460 +0530 +@@ -209,3 +209,15 @@ + bnd ret + + foo: bnd ret ++ ++bad: ++ # bndldx (%eax),(bad) ++ .byte 0x0f ++ .byte 0x1a ++ .byte 0x30 ++ ++ # bndmov (bad),%bnd0 ++ .byte 0x66 ++ .byte 0x0f ++ .byte 0x1a ++ .byte 0xc4 +Index: git/gas/ChangeLog +=================================================================== +--- git.orig/gas/ChangeLog 2017-09-21 15:38:53.143176323 +0530 ++++ git/gas/ChangeLog 2017-09-21 15:48:07.134368927 +0530 +@@ -1,3 +1,12 @@ ++2017-06-15 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21594 ++ * testsuite/gas/i386/mpx.s: Add 2 tests with invalid bnd ++ register. ++ * testsuite/gas/i386/x86-64-mpx.s: Likewise. ++ * testsuite/gas/i386/mpx.d: Updated. ++ * testsuite/gas/i386/x86-64-mpx.d: Likewise. ++ + 2016-12-01 Nick Clifton <nickc@redhat.com> + + PR gas/20898 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9756.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9756.patch new file mode 100644 index 0000000000..e40a26eb3c --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9756.patch @@ -0,0 +1,43 @@ +commit cd3ea7c69acc5045eb28f9bf80d923116e15e4f5 +Author: Nick Clifton <nickc@redhat.com> +Date: Thu Jun 15 13:26:54 2017 +0100 + + Prevent address violation problem when disassembling corrupt aarch64 binary. + + PR binutils/21595 + * aarch64-dis.c (aarch64_ext_ldst_reglist): Check for an out of + range value. + +Upstream-Status: Backport + +CVE: CVE-2017-9756 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/opcodes/aarch64-dis.c +=================================================================== +--- git.orig/opcodes/aarch64-dis.c 2017-09-21 15:48:27.154646380 +0530 ++++ git/opcodes/aarch64-dis.c 2017-09-21 15:48:27.134646104 +0530 +@@ -381,6 +381,9 @@ + info->reglist.first_regno = extract_field (FLD_Rt, code, 0); + /* opcode */ + value = extract_field (FLD_opcode, code, 0); ++ /* PR 21595: Check for a bogus value. */ ++ if (value >= ARRAY_SIZE (data)) ++ return 0; + if (expected_num != data[value].num_elements || data[value].is_reserved) + return 0; + info->reglist.num_regs = data[value].num_regs; +Index: git/opcodes/ChangeLog +=================================================================== +--- git.orig/opcodes/ChangeLog 2017-09-21 15:45:32.264491166 +0530 ++++ git/opcodes/ChangeLog 2017-09-21 15:49:53.751803571 +0530 +@@ -1,3 +1,9 @@ ++2017-06-15 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21595 ++ * aarch64-dis.c (aarch64_ext_ldst_reglist): Check for an out of ++ range value. ++ + 2017-06-15 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/21594 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9954.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9954.patch new file mode 100644 index 0000000000..26515721e3 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9954.patch @@ -0,0 +1,58 @@ +commit 04e15b4a9462cb1ae819e878a6009829aab8020b +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Jun 26 15:46:34 2017 +0100 + + Fix address violation parsing a corrupt texhex format file. + + PR binutils/21670 + * tekhex.c (getvalue): Check for the source pointer exceeding the + end pointer before the first byte is read. + +Upstream-Status: Backport + +CVE: CVE-2017-9954 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/tekhex.c +=================================================================== +--- git.orig/bfd/tekhex.c 2017-09-21 16:19:42.570877476 +0530 ++++ git/bfd/tekhex.c 2017-09-21 16:20:06.878964516 +0530 +@@ -273,6 +273,9 @@ + bfd_vma value = 0; + unsigned int len; + ++ if (src >= endp) ++ return FALSE; ++ + if (!ISHEX (*src)) + return FALSE; + +@@ -514,9 +517,10 @@ + /* To the front of the file. */ + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) + return FALSE; ++ + while (! is_eof) + { +- char src[MAXCHUNK]; ++ static char src[MAXCHUNK]; + char type; + + /* Find first '%'. */ +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 16:20:06.822964309 +0530 ++++ git/bfd/ChangeLog 2017-09-21 16:22:29.383577439 +0530 +@@ -55,6 +55,12 @@ + correct magic bytes at the start, set the error to wrong format + and clear the format selector before returning NULL. + ++2017-06-26 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21670 ++ * tekhex.c (getvalue): Check for the source pointer exceeding the ++ end pointer before the first byte is read. ++ + 2017-06-21 Nick Clifton <nickc@redhat.com> + + PR binutils/21637 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_1.patch new file mode 100644 index 0000000000..6cd86c2a30 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_1.patch @@ -0,0 +1,93 @@ +commit cfd14a500e0485374596234de4db10e88ebc7618 +Author: Nick Clifton <nickc@redhat.com> +Date: Mon Jun 26 15:25:08 2017 +0100 + + Fix address violations when atempting to parse fuzzed binaries. + + PR binutils/21665 + * compress.c (bfd_get_full_section_contents): Check for and reject + a section whoes size is greater than the size of the entire file. + * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not + contain a notes section. + + binutils* objdump.c (disassemble_section): Skip any section that is bigger + than the entire file. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/compress.c +=================================================================== +--- git.orig/bfd/compress.c 2017-09-21 17:32:51.645611404 +0530 ++++ git/bfd/compress.c 2017-09-21 17:32:52.965622987 +0530 +@@ -239,6 +239,12 @@ + *ptr = NULL; + return TRUE; + } ++ else if (bfd_get_file_size (abfd) > 0 ++ && sz > (bfd_size_type) bfd_get_file_size (abfd)) ++ { ++ *ptr = NULL; ++ return FALSE; ++ } + + switch (sec->compress_status) + { +Index: git/bfd/elf32-v850.c +=================================================================== +--- git.orig/bfd/elf32-v850.c 2017-09-21 17:32:35.053465773 +0530 ++++ git/bfd/elf32-v850.c 2017-09-21 17:32:52.965622987 +0530 +@@ -2448,7 +2448,9 @@ + BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont)); + + if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL) +- BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont)); ++ /* If the output is being stripped then it is possible for ++ the notes section to disappear. In this case do nothing. */ ++ return; + + /* Copy/overwrite notes from the input to the output. */ + memcpy (ocont, icont, bfd_section_size (obfd, onotes)); +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-21 17:32:52.337617476 +0530 ++++ git/binutils/objdump.c 2017-09-21 17:32:52.965622987 +0530 +@@ -1973,7 +1973,7 @@ + return; + + datasize = bfd_get_section_size (section); +- if (datasize == 0) ++ if (datasize == 0 || datasize >= (bfd_size_type) bfd_get_file_size (abfd)) + return; + + if (start_address == (bfd_vma) -1 +@@ -2839,7 +2839,7 @@ + static void + dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) + { +- bfd_byte *data = 0; ++ bfd_byte *data = NULL; + bfd_size_type datasize; + bfd_vma addr_offset; + bfd_vma start_offset; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 17:32:52.909622495 +0530 ++++ git/bfd/ChangeLog 2017-09-21 17:35:57.863164167 +0530 +@@ -11,6 +11,14 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++2017-06-26 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21665 ++ * compress.c (bfd_get_full_section_contents): Check for and reject ++ a section whoes size is greater than the size of the entire file. ++ * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not ++ contain a notes section. ++ + 2017-07-24 Nick Clifton <nickc@redhat.com> + + PR 21813 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_2.patch new file mode 100644 index 0000000000..6e1824bbab --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_2.patch @@ -0,0 +1,112 @@ +commit 0630b49c470ca2e3c3f74da4c7e4ff63440dd71f +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Mon Jun 26 09:24:49 2017 -0700 + + Check file size before getting section contents + + Don't check the section size in bfd_get_full_section_contents since + the size of a decompressed section may be larger than the file size. + Instead, check file size in _bfd_generic_get_section_contents. + + PR binutils/21665 + * compress.c (bfd_get_full_section_contents): Don't check the + file size here. + * libbfd.c (_bfd_generic_get_section_contents): Check for and + reject a section whoes size + offset is greater than the size + of the entire file. + (_bfd_generic_get_section_contents_in_window): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/libbfd.c +=================================================================== +--- git.orig/bfd/libbfd.c 2017-09-21 17:41:59.457841691 +0530 ++++ git/bfd/libbfd.c 2017-09-21 17:42:18.269987768 +0530 +@@ -780,6 +780,7 @@ + bfd_size_type count) + { + bfd_size_type sz; ++ file_ptr filesz; + if (count == 0) + return TRUE; + +@@ -801,8 +802,15 @@ + sz = section->rawsize; + else + sz = section->size; ++ filesz = bfd_get_file_size (abfd); ++ if (filesz < 0) ++ { ++ /* This should never happen. */ ++ abort (); ++ } + if (offset + count < count +- || offset + count > sz) ++ || offset + count > sz ++ || (section->filepos + offset + sz) > (bfd_size_type) filesz) + { + bfd_set_error (bfd_error_invalid_operation); + return FALSE; +@@ -825,6 +833,7 @@ + { + #ifdef USE_MMAP + bfd_size_type sz; ++ file_ptr filesz; + + if (count == 0) + return TRUE; +@@ -857,7 +866,13 @@ + sz = section->rawsize; + else + sz = section->size; ++ filesz = bfd_get_file_size (abfd); ++ { ++ /* This should never happen. */ ++ abort (); ++ } + if (offset + count > sz ++ || (section->filepos + offset + sz) > (bfd_size_type) filesz + || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, + TRUE)) + return FALSE; +Index: git/bfd/compress.c +=================================================================== +--- git.orig/bfd/compress.c 2017-09-21 17:42:18.213987332 +0530 ++++ git/bfd/compress.c 2017-09-21 17:45:17.107399434 +0530 +@@ -239,12 +239,6 @@ + *ptr = NULL; + return TRUE; + } +- else if (bfd_get_file_size (abfd) > 0 +- && sz > (bfd_size_type) bfd_get_file_size (abfd)) +- { +- *ptr = NULL; +- return FALSE; +- } + + switch (sec->compress_status) + { +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 17:42:18.213987332 +0530 ++++ git/bfd/ChangeLog 2017-09-21 17:47:03.668256850 +0530 +@@ -11,6 +11,16 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++2017-06-26 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21665 ++ * compress.c (bfd_get_full_section_contents): Don't check the ++ file size here. ++ * libbfd.c (_bfd_generic_get_section_contents): Check for and ++ reject a section whoes size + offset is greater than the size ++ of the entire file. ++ (_bfd_generic_get_section_contents_in_window): Likewise. ++ + 2017-06-26 Nick Clifton <nickc@redhat.com> + + PR binutils/21665 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_3.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_3.patch new file mode 100644 index 0000000000..c8741b13ca --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_3.patch @@ -0,0 +1,44 @@ +commit 1f473e3d0ad285195934e6a077c7ed32afe66437 +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Mon Jun 26 15:47:16 2017 -0700 + + Add a missing line to _bfd_generic_get_section_contents_in_window + + PR binutils/21665 + * libbfd.c (_bfd_generic_get_section_contents_in_window): Add + a missing line. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/libbfd.c +=================================================================== +--- git.orig/bfd/libbfd.c 2017-09-21 17:57:11.424955516 +0530 ++++ git/bfd/libbfd.c 2017-09-21 17:58:57.000000000 +0530 +@@ -867,6 +867,7 @@ + else + sz = section->size; + filesz = bfd_get_file_size (abfd); ++ if (filesz < 0) + { + /* This should never happen. */ + abort (); +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 17:57:11.424955516 +0530 ++++ git/bfd/ChangeLog 2017-09-21 18:01:32.258884464 +0530 +@@ -14,6 +14,12 @@ + 2017-06-26 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/21665 ++ * libbfd.c (_bfd_generic_get_section_contents_in_window): Add ++ a missing line. ++ ++2017-06-26 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21665 + * compress.c (bfd_get_full_section_contents): Don't check the + file size here. + * libbfd.c (_bfd_generic_get_section_contents): Check for and diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_4.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_4.patch new file mode 100644 index 0000000000..d6b6a14254 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_4.patch @@ -0,0 +1,50 @@ +commit ab27f80c5dceaa23c4ba7f62c0d5d22a5d5dd7a1 +Author: Pedro Alves <palves@redhat.com> +Date: Tue Jun 27 00:21:25 2017 +0100 + + Fix GDB regressions caused by previous bfd_get_section_contents changes + + Ref: https://sourceware.org/ml/binutils/2017-06/msg00343.html + + bfd/ChangeLog: + 2017-06-26 Pedro Alves <palves@redhat.com> + + PR binutils/21665 + * libbfd.c (_bfd_generic_get_section_contents): Add "count", not + "sz". + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/libbfd.c +=================================================================== +--- git.orig/bfd/libbfd.c 2017-09-21 18:01:58.079078554 +0530 ++++ git/bfd/libbfd.c 2017-09-21 18:01:58.063078433 +0530 +@@ -810,7 +810,7 @@ + } + if (offset + count < count + || offset + count > sz +- || (section->filepos + offset + sz) > (bfd_size_type) filesz) ++ || (section->filepos + offset + count) > (bfd_size_type) filesz) + { + bfd_set_error (bfd_error_invalid_operation); + return FALSE; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 18:01:32.258884464 +0530 ++++ git/bfd/ChangeLog 2017-09-21 18:03:42.955872017 +0530 +@@ -11,6 +11,12 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++2017-06-26 Pedro Alves <palves@redhat.com> ++ ++ PR binutils/21665 ++ * libbfd.c (_bfd_generic_get_section_contents): Add "count", not ++ "sz". ++ + 2017-06-26 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/21665 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_5.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_5.patch new file mode 100644 index 0000000000..3634421923 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_5.patch @@ -0,0 +1,89 @@ +commit 7211ae501eb0de1044983f2dfb00091a58fbd66c +Author: Alan Modra <amodra@gmail.com> +Date: Tue Jun 27 09:45:04 2017 +0930 + + More fixes for bfd_get_section_contents change + + PR binutils/21665 + * libbfd.c (_bfd_generic_get_section_contents): Delete abort. + Use unsigned file pointer type, and remove cast. + * libbfd.c (_bfd_generic_get_section_contents_in_window): Likewise. + Add "count", not "sz". + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/libbfd.c +=================================================================== +--- git.orig/bfd/libbfd.c 2017-09-21 18:04:47.316362760 +0530 ++++ git/bfd/libbfd.c 2017-09-21 18:04:47.300362638 +0530 +@@ -780,7 +780,7 @@ + bfd_size_type count) + { + bfd_size_type sz; +- file_ptr filesz; ++ ufile_ptr filesz; + if (count == 0) + return TRUE; + +@@ -803,14 +803,9 @@ + else + sz = section->size; + filesz = bfd_get_file_size (abfd); +- if (filesz < 0) +- { +- /* This should never happen. */ +- abort (); +- } + if (offset + count < count + || offset + count > sz +- || (section->filepos + offset + count) > (bfd_size_type) filesz) ++ || section->filepos + offset + count > filesz) + { + bfd_set_error (bfd_error_invalid_operation); + return FALSE; +@@ -833,7 +828,7 @@ + { + #ifdef USE_MMAP + bfd_size_type sz; +- file_ptr filesz; ++ ufile_ptr filesz; + + if (count == 0) + return TRUE; +@@ -867,13 +862,8 @@ + else + sz = section->size; + filesz = bfd_get_file_size (abfd); +- if (filesz < 0) +- { +- /* This should never happen. */ +- abort (); +- } + if (offset + count > sz +- || (section->filepos + offset + sz) > (bfd_size_type) filesz ++ || section->filepos + offset + count > filesz + || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, + TRUE)) + return FALSE; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 18:03:42.955872017 +0530 ++++ git/bfd/ChangeLog 2017-09-21 18:06:39.973228125 +0530 +@@ -11,6 +11,14 @@ + of end pointer. + (evax_bfd_print_emh): Check for invalid string lengths. + ++2017-06-27 Alan Modra <amodra@gmail.com> ++ ++ PR binutils/21665 ++ * libbfd.c (_bfd_generic_get_section_contents): Delete abort. ++ Use unsigned file pointer type, and remove cast. ++ * libbfd.c (_bfd_generic_get_section_contents_in_window): Likewise. ++ Add "count", not "sz". ++ + 2017-06-26 Pedro Alves <palves@redhat.com> + + PR binutils/21665 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_6.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_6.patch new file mode 100644 index 0000000000..55feb79c17 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_6.patch @@ -0,0 +1,55 @@ +commit ea9aafc41a764e4e2dbb88a7b031e886b481b99a +Author: Alan Modra <amodra@gmail.com> +Date: Tue Jun 27 14:43:49 2017 +0930 + + Warning fix + + PR binutils/21665 + * libbfd.c (_bfd_generic_get_section_contents): Warning fix. + (_bfd_generic_get_section_contents_in_window): Likewise. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + + +Index: git/bfd/libbfd.c +=================================================================== +--- git.orig/bfd/libbfd.c 2017-09-21 18:07:34.777651818 +0530 ++++ git/bfd/libbfd.c 2017-09-21 18:07:34.761651695 +0530 +@@ -805,7 +805,7 @@ + filesz = bfd_get_file_size (abfd); + if (offset + count < count + || offset + count > sz +- || section->filepos + offset + count > filesz) ++ || (ufile_ptr) section->filepos + offset + count > filesz) + { + bfd_set_error (bfd_error_invalid_operation); + return FALSE; +@@ -863,7 +863,7 @@ + sz = section->size; + filesz = bfd_get_file_size (abfd); + if (offset + count > sz +- || section->filepos + offset + count > filesz ++ || (ufile_ptr) section->filepos + offset + count > filesz + || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, + TRUE)) + return FALSE; +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 18:06:39.973228125 +0530 ++++ git/bfd/ChangeLog 2017-09-21 18:09:41.798640031 +0530 +@@ -19,6 +19,12 @@ + * libbfd.c (_bfd_generic_get_section_contents_in_window): Likewise. + Add "count", not "sz". + ++2017-06-27 Alan Modra <amodra@gmail.com> ++ ++ PR binutils/21665 ++ * libbfd.c (_bfd_generic_get_section_contents): Warning fix. ++ (_bfd_generic_get_section_contents_in_window): Likewise. ++ + 2017-06-26 Pedro Alves <palves@redhat.com> + + PR binutils/21665 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_7.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_7.patch new file mode 100644 index 0000000000..0950561e10 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_7.patch @@ -0,0 +1,79 @@ +commit 60a02042bacf8d25814430080adda61ed086bca6 +Author: Nick Clifton <nickc@redhat.com> +Date: Fri Jun 30 11:03:37 2017 +0100 + + Fix failures in MMIX linker tests introduced by fix for PR 21665. + + PR binutils/21665 + * objdump.c (disassemble_section): Move check for an overlarge + section to just before the allocation of memory. Do not check + section size against file size, but instead use an arbitrary 2Gb + limit. Issue a warning message if the section is too big. + +Upstream-Status: CVE-2017-9955 + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-21 18:10:55.499217078 +0530 ++++ git/binutils/objdump.c 2017-09-21 18:10:55.483216953 +0530 +@@ -1973,7 +1973,7 @@ + return; + + datasize = bfd_get_section_size (section); +- if (datasize == 0 || datasize >= (bfd_size_type) bfd_get_file_size (abfd)) ++ if (datasize == 0) + return; + + if (start_address == (bfd_vma) -1 +@@ -2037,6 +2037,29 @@ + } + rel_ppend = rel_pp + rel_count; + ++ /* PR 21665: Check for overlarge datasizes. ++ Note - we used to check for "datasize > bfd_get_file_size (abfd)" but ++ this fails when using compressed sections or compressed file formats ++ (eg MMO, tekhex). ++ ++ The call to xmalloc below will fail if too much memory is requested, ++ which will catch the problem in the normal use case. But if a memory ++ checker is in use, eg valgrind or sanitize, then an exception will ++ be still generated, so we try to catch the problem first. ++ ++ Unfortunately there is no simple way to determine how much memory can ++ be allocated by calling xmalloc. So instead we use a simple, arbitrary ++ limit of 2Gb. Hopefully this should be enough for most users. If ++ someone does start trying to disassemble sections larger then 2Gb in ++ size they will doubtless complain and we can increase the limit. */ ++#define MAX_XMALLOC (1024 * 1024 * 1024 * 2UL) /* 2Gb */ ++ if (datasize > MAX_XMALLOC) ++ { ++ non_fatal (_("Reading section %s failed because it is too big (%#lx)"), ++ section->name, (unsigned long) datasize); ++ return; ++ } ++ + data = (bfd_byte *) xmalloc (datasize); + + bfd_get_section_contents (abfd, section, data, 0, datasize); +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-09-21 17:57:10.448948416 +0530 ++++ git/binutils/ChangeLog 2017-09-21 18:13:09.052268892 +0530 +@@ -4,6 +4,14 @@ + * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty + string whilst concatenating symbol names. + ++2017-06-30 Nick Clifton <nickc@redhat.com> ++ ++ PR binutils/21665 ++ * objdump.c (disassemble_section): Move check for an overlarge ++ section to just before the allocation of memory. Do not check ++ section size against file size, but instead use an arbitrary 2Gb ++ limit. Issue a warning message if the section is too big. ++ + 2017-05-02 Nick Clifton <nickc@redhat.com> + + PR 21440 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_8.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_8.patch new file mode 100644 index 0000000000..8035ab38cb --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_8.patch @@ -0,0 +1,170 @@ +commit bae7501e87ab614115d9d3213b4dd18d96e604db +Author: Alan Modra <amodra@gmail.com> +Date: Sat Jul 1 21:58:10 2017 +0930 + + Use bfd_malloc_and_get_section + + It's nicer than xmalloc followed by bfd_get_section_contents, since + xmalloc exits on failure and needs a check that its size_t arg doesn't + lose high bits when converted from bfd_size_type. + + PR binutils/21665 + * objdump.c (strtab): Make var a bfd_byte*. + (disassemble_section): Don't limit malloc size. Instead, use + bfd_malloc_and_get_section. + (read_section_stabs): Use bfd_malloc_and_get_section. Return + bfd_byte*. + (find_stabs_section): Remove now unnecessary cast. + * objcopy.c (copy_object): Use bfd_malloc_and_get_section. Free + contents on error return. + * nlmconv.c (copy_sections): Use bfd_malloc_and_get_section. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/binutils/nlmconv.c +=================================================================== +--- git.orig/binutils/nlmconv.c 2017-09-21 18:14:15.792797232 +0530 ++++ git/binutils/nlmconv.c 2017-09-21 18:14:15.776797105 +0530 +@@ -1224,7 +1224,7 @@ + const char *inname; + asection *outsec; + bfd_size_type size; +- void *contents; ++ bfd_byte *contents; + long reloc_size; + bfd_byte buf[4]; + bfd_size_type add; +@@ -1240,9 +1240,7 @@ + contents = NULL; + else + { +- contents = xmalloc (size); +- if (! bfd_get_section_contents (inbfd, insec, contents, +- (file_ptr) 0, size)) ++ if (!bfd_malloc_and_get_section (inbfd, insec, &contents)) + bfd_fatal (bfd_get_filename (inbfd)); + } + +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-21 18:14:15.792797232 +0530 ++++ git/binutils/objdump.c 2017-09-21 18:23:30.420895459 +0530 +@@ -180,7 +180,7 @@ + static bfd_byte *stabs; + static bfd_size_type stab_size; + +-static char *strtab; ++static bfd_byte *strtab; + static bfd_size_type stabstr_size; + + static bfd_boolean is_relocatable = FALSE; +@@ -2037,33 +2037,13 @@ + } + rel_ppend = rel_pp + rel_count; + +- /* PR 21665: Check for overlarge datasizes. +- Note - we used to check for "datasize > bfd_get_file_size (abfd)" but +- this fails when using compressed sections or compressed file formats +- (eg MMO, tekhex). +- +- The call to xmalloc below will fail if too much memory is requested, +- which will catch the problem in the normal use case. But if a memory +- checker is in use, eg valgrind or sanitize, then an exception will +- be still generated, so we try to catch the problem first. +- +- Unfortunately there is no simple way to determine how much memory can +- be allocated by calling xmalloc. So instead we use a simple, arbitrary +- limit of 2Gb. Hopefully this should be enough for most users. If +- someone does start trying to disassemble sections larger then 2Gb in +- size they will doubtless complain and we can increase the limit. */ +-#define MAX_XMALLOC (1024 * 1024 * 1024 * 2UL) /* 2Gb */ +- if (datasize > MAX_XMALLOC) ++ if (!bfd_malloc_and_get_section (abfd, section, &data)) + { +- non_fatal (_("Reading section %s failed because it is too big (%#lx)"), +- section->name, (unsigned long) datasize); ++ non_fatal (_("Reading section %s failed because: %s"), ++ section->name, bfd_errmsg (bfd_get_error ())); + return; + } + +- data = (bfd_byte *) xmalloc (datasize); +- +- bfd_get_section_contents (abfd, section, data, 0, datasize); +- + paux->sec = section; + pinfo->buffer = data; + pinfo->buffer_vma = section->vma; +@@ -2579,12 +2559,11 @@ + /* Read ABFD's stabs section STABSECT_NAME, and return a pointer to + it. Return NULL on failure. */ + +-static char * ++static bfd_byte * + read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr) + { + asection *stabsect; +- bfd_size_type size; +- char *contents; ++ bfd_byte *contents; + + stabsect = bfd_get_section_by_name (abfd, sect_name); + if (stabsect == NULL) +@@ -2593,10 +2572,7 @@ + return FALSE; + } + +- size = bfd_section_size (abfd, stabsect); +- contents = (char *) xmalloc (size); +- +- if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size)) ++ if (!bfd_malloc_and_get_section (abfd, stabsect, &contents)) + { + non_fatal (_("reading %s section of %s failed: %s"), + sect_name, bfd_get_filename (abfd), +@@ -2606,7 +2582,7 @@ + return NULL; + } + +- *size_ptr = size; ++ *size_ptr = bfd_section_size (abfd, stabsect); + + return contents; + } +@@ -2733,8 +2709,7 @@ + + if (strtab) + { +- stabs = (bfd_byte *) read_section_stabs (abfd, section->name, +- &stab_size); ++ stabs = read_section_stabs (abfd, section->name, &stab_size); + if (stabs) + print_section_stabs (abfd, section->name, &sought->string_offset); + } +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-09-21 18:13:09.052268892 +0530 ++++ git/binutils/ChangeLog 2017-09-21 18:25:00.195937741 +0530 +@@ -4,6 +4,19 @@ + * rddbg.c (read_symbol_stabs_debugging_info): Check for an empty + string whilst concatenating symbol names. + ++2017-07-01 Alan Modra <amodra@gmail.com> ++ ++ PR binutils/21665 ++ * objdump.c (strtab): Make var a bfd_byte*. ++ (disassemble_section): Don't limit malloc size. Instead, use ++ bfd_malloc_and_get_section. ++ (read_section_stabs): Use bfd_malloc_and_get_section. Return ++ bfd_byte*. ++ (find_stabs_section): Remove now unnecessary cast. ++ * objcopy.c (copy_object): Use bfd_malloc_and_get_section. Free ++ contents on error return. ++ * nlmconv.c (copy_sections): Use bfd_malloc_and_get_section. ++ + 2017-06-30 Nick Clifton <nickc@redhat.com> + + PR binutils/21665 diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_9.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_9.patch new file mode 100644 index 0000000000..2f50337dab --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-9955_9.patch @@ -0,0 +1,360 @@ +commit 8e2f54bcee7e3e8315d4a39a302eaf8e4389e07d +Author: H.J. Lu <hjl.tools@gmail.com> +Date: Tue May 30 06:34:05 2017 -0700 + + Add bfd_get_file_size to get archive element size + + We can't use stat() to get archive element size. Add bfd_get_file_size + to get size for both normal files and archive elements. + + bfd/ + + PR binutils/21519 + * bfdio.c (bfd_get_file_size): New function. + * bfd-in2.h: Regenerated. + + binutils/ + + PR binutils/21519 + * objdump.c (dump_relocs_in_section): Replace get_file_size + with bfd_get_file_size to get archive element size. + * testsuite/binutils-all/objdump.exp (test_objdump_f): New + proc. + (test_objdump_h): Likewise. + (test_objdump_t): Likewise. + (test_objdump_r): Likewise. + (test_objdump_s): Likewise. + Add objdump tests on archive. + +Upstream-Status: Backport + +CVE: CVE-2017-9955 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/bfd/bfd-in2.h +=================================================================== +--- git.orig/bfd/bfd-in2.h 2017-09-21 20:09:13.475032861 +0530 ++++ git/bfd/bfd-in2.h 2017-09-21 20:09:16.375051269 +0530 +@@ -1208,6 +1208,8 @@ + + file_ptr bfd_get_size (bfd *abfd); + ++file_ptr bfd_get_file_size (bfd *abfd); ++ + void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, + int prot, int flags, file_ptr offset, + void **map_addr, bfd_size_type *map_len); +Index: git/bfd/bfdio.c +=================================================================== +--- git.orig/bfd/bfdio.c 2017-09-21 20:08:55.774919453 +0530 ++++ git/bfd/bfdio.c 2017-09-21 20:09:16.375051269 +0530 +@@ -434,6 +434,29 @@ + return buf.st_size; + } + ++/* ++FUNCTION ++ bfd_get_file_size ++ ++SYNOPSIS ++ file_ptr bfd_get_file_size (bfd *abfd); ++ ++DESCRIPTION ++ Return the file size (as read from file system) for the file ++ associated with BFD @var{abfd}. It supports both normal files ++ and archive elements. ++ ++*/ ++ ++file_ptr ++bfd_get_file_size (bfd *abfd) ++{ ++ if (abfd->my_archive != NULL ++ && !bfd_is_thin_archive (abfd->my_archive)) ++ return arelt_size (abfd); ++ ++ return bfd_get_size (abfd); ++} + + /* + FUNCTION +Index: git/binutils/objdump.c +=================================================================== +--- git.orig/binutils/objdump.c 2017-09-21 20:09:16.319050914 +0530 ++++ git/binutils/objdump.c 2017-09-21 20:09:16.375051269 +0530 +@@ -3240,7 +3240,7 @@ + } + + if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0 +- && relsize > get_file_size (bfd_get_filename (abfd))) ++ && relsize > bfd_get_file_size (abfd)) + { + printf (" (too many: 0x%x)\n", section->reloc_count); + bfd_set_error (bfd_error_file_truncated); +Index: git/binutils/testsuite/binutils-all/objdump.exp +=================================================================== +--- git.orig/binutils/testsuite/binutils-all/objdump.exp 2017-09-21 20:08:55.982920797 +0530 ++++ git/binutils/testsuite/binutils-all/objdump.exp 2017-09-21 20:09:16.375051269 +0530 +@@ -64,96 +64,168 @@ + if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then { + return + } ++if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest2.o]} then { ++ return ++} + if [is_remote host] { + set testfile [remote_download host tmpdir/bintest.o] ++ set testfile2 [remote_download host tmpdir/bintest2.o] + } else { + set testfile tmpdir/bintest.o ++ set testfile2 tmpdir/bintest2.o ++} ++ ++if { ![istarget "alpha-*-*"] || [is_elf_format] } then { ++ remote_file host file delete tmpdir/bintest.a ++ set got [binutils_run $AR "rc tmpdir/bintest.a $testfile2"] ++ if ![string match "" $got] then { ++ fail "bintest.a" ++ remote_file host delete tmpdir/bintest.a ++ } else { ++ if [is_remote host] { ++ set testarchive [remote_download host tmpdir/bintest.a] ++ } else { ++ set testarchive tmpdir/bintest.a ++ } ++ } ++ remote_file host delete tmpdir/bintest2.o + } + + # Test objdump -f + +-set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $testfile"] ++proc test_objdump_f { testfile dumpfile } { ++ global OBJDUMP ++ global OBJDUMPFLAGS ++ global cpus_regex + +-set want "$testfile:\[ \]*file format.*architecture:\[ \]*${cpus_regex}.*HAS_RELOC.*HAS_SYMS" ++ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $testfile"] + +-if ![regexp $want $got] then { +- fail "objdump -f" +-} else { +- pass "objdump -f" ++ set want "$dumpfile:\[ \]*file format.*architecture:\[ \]*${cpus_regex}.*HAS_RELOC.*HAS_SYMS" ++ ++ if ![regexp $want $got] then { ++ fail "objdump -f ($testfile, $dumpfile)" ++ } else { ++ pass "objdump -f ($testfile, $dumpfile)" ++ } ++} ++ ++test_objdump_f $testfile $testfile ++if { [ remote_file host exists $testarchive ] } then { ++ test_objdump_f $testarchive bintest2.o + } + + # Test objdump -h + +-set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $testfile"] ++proc test_objdump_h { testfile dumpfile } { ++ global OBJDUMP ++ global OBJDUMPFLAGS + +-set want "$testfile:\[ \]*file format.*Sections.*\[0-9\]+\[ \]+\[^ \]*(text|TEXT|P|\\\$CODE\\\$)\[^ \]*\[ \]*(\[0-9a-fA-F\]+).*\[0-9\]+\[ \]+\[^ \]*(\\.data|DATA|D_1)\[^ \]*\[ \]*(\[0-9a-fA-F\]+)" ++ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $testfile"] + +-if ![regexp $want $got all text_name text_size data_name data_size] then { +- fail "objdump -h" +-} else { +- verbose "text name is $text_name size is $text_size" +- verbose "data name is $data_name size is $data_size" +- set ets 8 +- set eds 4 +- # The [ti]c4x target has the property sizeof(char)=sizeof(long)=1 +- if [istarget *c4x*-*-*] then { +- set ets 2 +- set eds 1 +- } +- # c54x section sizes are in bytes, not octets; adjust accordingly +- if [istarget *c54x*-*-*] then { +- set ets 4 +- set eds 2 +- } +- if {[expr "0x$text_size"] < $ets || [expr "0x$data_size"] < $eds} then { +- send_log "sizes too small\n" +- fail "objdump -h" ++ set want "$dumpfile:\[ \]*file format.*Sections.*\[0-9\]+\[ \]+\[^ \]*(text|TEXT|P|\\\$CODE\\\$)\[^ \]*\[ \]*(\[0-9a-fA-F\]+).*\[0-9\]+\[ \]+\[^ \]*(\\.data|DATA|D_1)\[^ \]*\[ \]*(\[0-9a-fA-F\]+)" ++ ++ if ![regexp $want $got all text_name text_size data_name data_size] then { ++ fail "objdump -h ($testfile, $dumpfile)" + } else { +- pass "objdump -h" ++ verbose "text name is $text_name size is $text_size" ++ verbose "data name is $data_name size is $data_size" ++ set ets 8 ++ set eds 4 ++ # The [ti]c4x target has the property sizeof(char)=sizeof(long)=1 ++ if [istarget *c4x*-*-*] then { ++ set ets 2 ++ set eds 1 ++ } ++ # c54x section sizes are in bytes, not octets; adjust accordingly ++ if [istarget *c54x*-*-*] then { ++ set ets 4 ++ set eds 2 ++ } ++ if {[expr "0x$text_size"] < $ets || [expr "0x$data_size"] < $eds} then { ++ send_log "sizes too small\n" ++ fail "objdump -h ($testfile, $dumpfile)" ++ } else { ++ pass "objdump -h ($testfile, $dumpfile)" ++ } + } + } + ++test_objdump_h $testfile $testfile ++if { [ remote_file host exists $testarchive ] } then { ++ test_objdump_h $testarchive bintest2.o ++} ++ + # Test objdump -t + +-set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $testfile"] ++proc test_objdump_t { testfile} { ++ global OBJDUMP ++ global OBJDUMPFLAGS ++ ++ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $testfile"] ++ ++ if [info exists vars] then { unset vars } ++ while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} { ++ set vars($symbol) 1 ++ set got $rest ++ } + +-if [info exists vars] then { unset vars } +-while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} { +- set vars($symbol) 1 +- set got $rest ++ if {![info exists vars(text_symbol)] \ ++ || ![info exists vars(data_symbol)] \ ++ || ![info exists vars(common_symbol)] \ ++ || ![info exists vars(external_symbol)]} then { ++ fail "objdump -t ($testfile)" ++ } else { ++ pass "objdump -t ($testfile)" ++ } + } + +-if {![info exists vars(text_symbol)] \ +- || ![info exists vars(data_symbol)] \ +- || ![info exists vars(common_symbol)] \ +- || ![info exists vars(external_symbol)]} then { +- fail "objdump -t" +-} else { +- pass "objdump -t" ++test_objdump_t $testfile ++if { [ remote_file host exists $testarchive ] } then { ++ test_objdump_t $testarchive + } + + # Test objdump -r + +-set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $testfile"] ++proc test_objdump_r { testfile dumpfile } { ++ global OBJDUMP ++ global OBJDUMPFLAGS + +-set want "$testfile:\[ \]*file format.*RELOCATION RECORDS FOR \\\[\[^\]\]*(text|TEXT|P|\\\$CODE\\\$)\[^\]\]*\\\].*external_symbol" ++ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $testfile"] + +-if [regexp $want $got] then { +- pass "objdump -r" +-} else { +- fail "objdump -r" ++ set want "$dumpfile:\[ \]*file format.*RELOCATION RECORDS FOR \\\[\[^\]\]*(text|TEXT|P|\\\$CODE\\\$)\[^\]\]*\\\].*external_symbol" ++ ++ if [regexp $want $got] then { ++ pass "objdump -r ($testfile, $dumpfile)" ++ } else { ++ fail "objdump -r ($testfile, $dumpfile)" ++ } ++} ++ ++test_objdump_r $testfile $testfile ++if { [ remote_file host exists $testarchive ] } then { ++ test_objdump_r $testarchive bintest2.o + } + + # Test objdump -s + +-set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s $testfile"] ++proc test_objdump_s { testfile dumpfile } { ++ global OBJDUMP ++ global OBJDUMPFLAGS + +-set want "$testfile:\[ \]*file format.*Contents.*(text|TEXT|P|\\\$CODE\\\$)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000001|01000000|00000100).*Contents.*(data|DATA|D_1)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000002|02000000|00000200)" ++ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s $testfile"] + +-if [regexp $want $got] then { +- pass "objdump -s" +-} else { +- fail "objdump -s" ++ set want "$dumpfile:\[ \]*file format.*Contents.*(text|TEXT|P|\\\$CODE\\\$)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000001|01000000|00000100).*Contents.*(data|DATA|D_1)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000002|02000000|00000200)" ++ ++ if [regexp $want $got] then { ++ pass "objdump -s ($testfile, $dumpfile)" ++ } else { ++ fail "objdump -s ($testfile, $dumpfile)" ++ } ++} ++ ++test_objdump_s $testfile $testfile ++if { [ remote_file host exists $testarchive ] } then { ++ test_objdump_s $testarchive bintest2.o + } + + # Test objdump -s on a file that contains a compressed .debug section +Index: git/bfd/ChangeLog +=================================================================== +--- git.orig/bfd/ChangeLog 2017-09-21 20:09:16.207050204 +0530 ++++ git/bfd/ChangeLog 2017-09-21 20:13:41.504562787 +0530 +@@ -158,6 +158,12 @@ + (bfd_perform_relocation, bfd_install_relocation): Use it. + (_bfd_final_link_relocate): Likewise. + ++2017-05-30 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21519 ++ * bfdio.c (bfd_get_file_size): New function. ++ * bfd-in2.h: Regenerated. ++ + 2017-04-26 Nick Clifton <nickc@redhat.com> + + PR binutils/21434 +Index: git/binutils/ChangeLog +=================================================================== +--- git.orig/binutils/ChangeLog 2017-09-21 20:09:16.319050914 +0530 ++++ git/binutils/ChangeLog 2017-09-21 20:12:42.624252645 +0530 +@@ -25,6 +25,19 @@ + section size against file size, but instead use an arbitrary 2Gb + limit. Issue a warning message if the section is too big. + ++2017-05-30 H.J. Lu <hongjiu.lu@intel.com> ++ ++ PR binutils/21519 ++ * objdump.c (dump_relocs_in_section): Replace get_file_size ++ with bfd_get_file_size to get archive element size. ++ * testsuite/binutils-all/objdump.exp (test_objdump_f): New ++ proc. ++ (test_objdump_h): Likewise. ++ (test_objdump_t): Likewise. ++ (test_objdump_r): Likewise. ++ (test_objdump_s): Likewise. ++ Add objdump tests on archive. ++ + 2017-05-02 Nick Clifton <nickc@redhat.com> + + PR 21440 diff --git a/meta/recipes-devtools/cmake/cmake.inc b/meta/recipes-devtools/cmake/cmake.inc index 4fcb0b1ed0..821bb81892 100644 --- a/meta/recipes-devtools/cmake/cmake.inc +++ b/meta/recipes-devtools/cmake/cmake.inc @@ -14,6 +14,7 @@ CMAKE_MAJOR_VERSION = "${@'.'.join(d.getVar('PV', True).split('.')[0:2])}" SRC_URI = "https://cmake.org/files/v${CMAKE_MAJOR_VERSION}/cmake-${PV}.tar.gz \ file://support-oe-qt4-tools-names.patch \ file://qt4-fail-silent.patch \ + file://avoid-gcc-warnings-with-Wstrict-prototypes.patch \ " SRC_URI[md5sum] = "d6dd661380adacdb12f41b926ec99545" diff --git a/meta/recipes-devtools/cmake/cmake/avoid-gcc-warnings-with-Wstrict-prototypes.patch b/meta/recipes-devtools/cmake/cmake/avoid-gcc-warnings-with-Wstrict-prototypes.patch new file mode 100644 index 0000000000..8b8d4802ee --- /dev/null +++ b/meta/recipes-devtools/cmake/cmake/avoid-gcc-warnings-with-Wstrict-prototypes.patch @@ -0,0 +1,42 @@ +From 4bc17345c01ea467099e28c7df30c23ace9e7811 Mon Sep 17 00:00:00 2001 +From: Andre McCurdy <armccurdy@gmail.com> +Date: Fri, 14 Oct 2016 16:26:58 -0700 +Subject: [PATCH] CheckFunctionExists.c: avoid gcc warnings with + -Wstrict-prototypes + +Avoid warnings (and therefore build failures etc) if a user happens +to add -Wstrict-prototypes to CFLAGS. + + | $ gcc --version + | gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 + | + | $ gcc -Wstrict-prototypes -Werror -DCHECK_FUNCTION_EXISTS=pthread_create -o foo.o -c Modules/CheckFunctionExists.c + | Modules/CheckFunctionExists.c:7:3: error: function declaration isn't a prototype [-Werror=strict-prototypes] + | CHECK_FUNCTION_EXISTS(); + | ^ + | cc1: all warnings being treated as errors + | + +Upstream-Status: Pending + +Signed-off-by: Andre McCurdy <armccurdy@gmail.com> +--- + Modules/CheckFunctionExists.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Modules/CheckFunctionExists.c b/Modules/CheckFunctionExists.c +index 2304000..224e340 100644 +--- a/Modules/CheckFunctionExists.c ++++ b/Modules/CheckFunctionExists.c +@@ -4,7 +4,7 @@ + extern "C" + #endif + char +- CHECK_FUNCTION_EXISTS(); ++ CHECK_FUNCTION_EXISTS(void); + #ifdef __CLASSIC_C__ + int main() + { +-- +1.9.1 + diff --git a/meta/recipes-devtools/distcc/distcc_3.2.bb b/meta/recipes-devtools/distcc/distcc_3.2.bb index c084ad2b73..f891fab937 100644 --- a/meta/recipes-devtools/distcc/distcc_3.2.bb +++ b/meta/recipes-devtools/distcc/distcc_3.2.bb @@ -14,7 +14,7 @@ PACKAGECONFIG[popt] = "--without-included-popt,--with-included-popt,popt" RRECOMMENDS_${PN} = "avahi-daemon" -SRC_URI = "git://github.com/distcc/distcc.git;branch=${PV} \ +SRC_URI = "git://github.com/akuster/distcc.git;branch=${PV} \ file://separatebuilddir.patch \ file://0001-zeroconf-Include-fcntl.h.patch \ file://default \ diff --git a/meta/recipes-devtools/e2fsprogs/e2fsprogs/0001-misc-rename-copy_file_range-to-copy_file_chunk.patch b/meta/recipes-devtools/e2fsprogs/e2fsprogs/0001-misc-rename-copy_file_range-to-copy_file_chunk.patch new file mode 100644 index 0000000000..276432c1a3 --- /dev/null +++ b/meta/recipes-devtools/e2fsprogs/e2fsprogs/0001-misc-rename-copy_file_range-to-copy_file_chunk.patch @@ -0,0 +1,62 @@ +From 10e2247f7b4692e80d185bb65ea641585bdc6b4d Mon Sep 17 00:00:00 2001 +From: Palmer Dabbelt <palmer@dabbelt.com> +Date: Fri, 29 Dec 2017 10:19:51 -0800 +Subject: [PATCH] misc: rename copy_file_range to copy_file_chunk + +As of 2.27, glibc will have a copy_file_range library call to wrap the +new copy_file_range system call. This conflicts with the function in +misc/create_inode.c, which this patch renames _copy_file_range. + +Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> + +Upstream-Status: Backport + +Signed-off-by: Tanu Kaskinen <tanuk@iki.fi> +--- + misc/create_inode.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/misc/create_inode.c b/misc/create_inode.c +index c879a3ec..6acf0e20 100644 +--- a/misc/create_inode.c ++++ b/misc/create_inode.c +@@ -392,7 +392,7 @@ static ssize_t my_pread(int fd, void *buf, size_t count, off_t offset) + } + #endif /* !defined HAVE_PREAD64 && !defined HAVE_PREAD */ + +-static errcode_t copy_file_range(ext2_filsys fs, int fd, ext2_file_t e2_file, ++static errcode_t copy_file_chunk(ext2_filsys fs, int fd, ext2_file_t e2_file, + off_t start, off_t end, char *buf, + char *zerobuf) + { +@@ -466,7 +466,7 @@ static errcode_t try_lseek_copy(ext2_filsys fs, int fd, struct stat *statbuf, + + data_blk = data & ~(fs->blocksize - 1); + hole_blk = (hole + (fs->blocksize - 1)) & ~(fs->blocksize - 1); +- err = copy_file_range(fs, fd, e2_file, data_blk, hole_blk, buf, ++ err = copy_file_chunk(fs, fd, e2_file, data_blk, hole_blk, buf, + zerobuf); + if (err) + return err; +@@ -518,7 +518,7 @@ static errcode_t try_fiemap_copy(ext2_filsys fs, int fd, ext2_file_t e2_file, + } + for (i = 0, ext = ext_buf; i < fiemap_buf->fm_mapped_extents; + i++, ext++) { +- err = copy_file_range(fs, fd, e2_file, ext->fe_logical, ++ err = copy_file_chunk(fs, fd, e2_file, ext->fe_logical, + ext->fe_logical + ext->fe_length, + buf, zerobuf); + if (err) +@@ -569,7 +569,7 @@ static errcode_t copy_file(ext2_filsys fs, int fd, struct stat *statbuf, + if (err != EXT2_ET_UNIMPLEMENTED) + goto out; + +- err = copy_file_range(fs, fd, e2_file, 0, statbuf->st_size, buf, ++ err = copy_file_chunk(fs, fd, e2_file, 0, statbuf->st_size, buf, + zerobuf); + out: + ext2fs_free_mem(&zerobuf); +-- +2.16.2 + diff --git a/meta/recipes-devtools/e2fsprogs/e2fsprogs_1.43.bb b/meta/recipes-devtools/e2fsprogs/e2fsprogs_1.43.bb index dcfb564a4b..4eadc3eab4 100644 --- a/meta/recipes-devtools/e2fsprogs/e2fsprogs_1.43.bb +++ b/meta/recipes-devtools/e2fsprogs/e2fsprogs_1.43.bb @@ -11,6 +11,7 @@ SRC_URI += "file://acinclude.m4 \ file://Revert-mke2fs-enable-the-metadata_csum-and-64bit-fea.patch \ file://mkdir_p.patch \ file://0001-e2fsck-exit-with-exit-status-0-if-no-errors-were-fix.patch \ + file://0001-misc-rename-copy_file_range-to-copy_file_chunk.patch \ " SRC_URI_append_class-native = " file://e2fsprogs-fix-missing-check-for-permission-denied.patch" diff --git a/meta/recipes-devtools/gcc/gcc-5.4.inc b/meta/recipes-devtools/gcc/gcc-5.4.inc index 338530fd6d..b7696756af 100644 --- a/meta/recipes-devtools/gcc/gcc-5.4.inc +++ b/meta/recipes-devtools/gcc/gcc-5.4.inc @@ -89,6 +89,7 @@ SRC_URI = "\ file://0057-unwind-fix-for-musl.patch \ file://0058-fdebug-prefix-map-support-to-remap-relative-path.patch \ file://0059-libgcc-use-ldflags.patch \ + file://CVE-2016-6131.patch \ " BACKPORTS = "" diff --git a/meta/recipes-devtools/gcc/gcc-5.4/CVE-2016-6131.patch b/meta/recipes-devtools/gcc/gcc-5.4/CVE-2016-6131.patch new file mode 100644 index 0000000000..88524c342e --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-5.4/CVE-2016-6131.patch @@ -0,0 +1,251 @@ +From b3f6b32165d3f437bd0ac6269c3c499b68ecf036 Mon Sep 17 00:00:00 2001 +From: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Thu, 4 Aug 2016 16:53:18 +0000 +Subject: [PATCH] Fix for PR71696 in Libiberty Demangler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[BZ #71696] -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71696 + +2016-08-04 Marcel Böhme <boehme.marcel@gmail.com> + + PR c++/71696 + * cplus-dem.c: Prevent infinite recursion when there is a cycle + in the referencing of remembered mangled types. + (work_stuff): New stack to keep track of the remembered mangled + types that are currently being processed. + (push_processed_type): New method to push currently processed + remembered type onto the stack. + (pop_processed_type): New method to pop currently processed + remembered type from the stack. + (work_stuff_copy_to_from): Copy values of new variables. + (delete_non_B_K_work_stuff): Free stack memory. + (demangle_args): Push/Pop currently processed remembered type. + (do_type): Do not demangle a cyclic reference and push/pop + referenced remembered type. + +cherry-picked from commit of +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239143 138bc75d-0d04-0410-961f-82ee72b054a4 + +Upstream-Status: Backport [master] +CVE: CVE-2016-6131 +Signed-off-by: Yuanjie Huang <yuanjie.huang@windriver.com> +--- + libiberty/ChangeLog | 17 ++++++++ + libiberty/cplus-dem.c | 78 ++++++++++++++++++++++++++++++++--- + libiberty/testsuite/demangle-expected | 18 ++++++++ + 3 files changed, 108 insertions(+), 5 deletions(-) + +diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog +index 9859ad3..7939480 100644 +--- a/libiberty/ChangeLog ++++ b/libiberty/ChangeLog +@@ -1,3 +1,20 @@ ++2016-08-04 Marcel Böhme <boehme.marcel@gmail.com> ++ ++ PR c++/71696 ++ * cplus-dem.c: Prevent infinite recursion when there is a cycle ++ in the referencing of remembered mangled types. ++ (work_stuff): New stack to keep track of the remembered mangled ++ types that are currently being processed. ++ (push_processed_type): New method to push currently processed ++ remembered type onto the stack. ++ (pop_processed_type): New method to pop currently processed ++ remembered type from the stack. ++ (work_stuff_copy_to_from): Copy values of new variables. ++ (delete_non_B_K_work_stuff): Free stack memory. ++ (demangle_args): Push/Pop currently processed remembered type. ++ (do_type): Do not demangle a cyclic reference and push/pop ++ referenced remembered type. ++ + 2016-06-03 Release Manager + + * GCC 5.4.0 released. +diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c +index 7514e57..f21e630 100644 +--- a/libiberty/cplus-dem.c ++++ b/libiberty/cplus-dem.c +@@ -144,6 +144,9 @@ struct work_stuff + string* previous_argument; /* The last function argument demangled. */ + int nrepeats; /* The number of times to repeat the previous + argument. */ ++ int *proctypevec; /* Indices of currently processed remembered typevecs. */ ++ int proctypevec_size; ++ int nproctypes; + }; + + #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) +@@ -435,6 +438,10 @@ iterate_demangle_function (struct work_stuff *, + + static void remember_type (struct work_stuff *, const char *, int); + ++static void push_processed_type (struct work_stuff *, int); ++ ++static void pop_processed_type (struct work_stuff *); ++ + static void remember_Btype (struct work_stuff *, const char *, int, int); + + static int register_Btype (struct work_stuff *); +@@ -1301,6 +1308,10 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) + memcpy (to->btypevec[i], from->btypevec[i], len); + } + ++ if (from->proctypevec) ++ to->proctypevec = ++ XDUPVEC (int, from->proctypevec, from->proctypevec_size); ++ + if (from->ntmpl_args) + to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); + +@@ -1329,11 +1340,17 @@ delete_non_B_K_work_stuff (struct work_stuff *work) + /* Discard the remembered types, if any. */ + + forget_types (work); +- if (work -> typevec != NULL) ++ if (work->typevec != NULL) + { +- free ((char *) work -> typevec); +- work -> typevec = NULL; +- work -> typevec_size = 0; ++ free ((char *) work->typevec); ++ work->typevec = NULL; ++ work->typevec_size = 0; ++ } ++ if (work->proctypevec != NULL) ++ { ++ free (work->proctypevec); ++ work->proctypevec = NULL; ++ work->proctypevec_size = 0; + } + if (work->tmpl_argvec) + { +@@ -3552,6 +3569,8 @@ static int + do_type (struct work_stuff *work, const char **mangled, string *result) + { + int n; ++ int i; ++ int is_proctypevec; + int done; + int success; + string decl; +@@ -3564,6 +3583,7 @@ do_type (struct work_stuff *work, const char **mangled, string *result) + + done = 0; + success = 1; ++ is_proctypevec = 0; + while (success && !done) + { + int member; +@@ -3616,8 +3636,15 @@ do_type (struct work_stuff *work, const char **mangled, string *result) + success = 0; + } + else ++ for (i = 0; i < work->nproctypes; i++) ++ if (work -> proctypevec [i] == n) ++ success = 0; ++ ++ if (success) + { +- remembered_type = work -> typevec[n]; ++ is_proctypevec = 1; ++ push_processed_type (work, n); ++ remembered_type = work->typevec[n]; + mangled = &remembered_type; + } + break; +@@ -3840,6 +3867,9 @@ do_type (struct work_stuff *work, const char **mangled, string *result) + string_delete (result); + string_delete (&decl); + ++ if (is_proctypevec) ++ pop_processed_type (work); ++ + if (success) + /* Assume an integral type, if we're not sure. */ + return (int) ((tk == tk_none) ? tk_integral : tk); +@@ -4252,6 +4282,41 @@ do_arg (struct work_stuff *work, const char **mangled, string *result) + } + + static void ++push_processed_type (struct work_stuff *work, int typevec_index) ++{ ++ if (work->nproctypes >= work->proctypevec_size) ++ { ++ if (!work->proctypevec_size) ++ { ++ work->proctypevec_size = 4; ++ work->proctypevec = XNEWVEC (int, work->proctypevec_size); ++ } ++ else ++ { ++ if (work->proctypevec_size < 16) ++ /* Double when small. */ ++ work->proctypevec_size *= 2; ++ else ++ { ++ /* Grow slower when large. */ ++ if (work->proctypevec_size > (INT_MAX / 3) * 2) ++ xmalloc_failed (INT_MAX); ++ work->proctypevec_size = (work->proctypevec_size * 3 / 2); ++ } ++ work->proctypevec ++ = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size); ++ } ++ } ++ work->proctypevec [work->nproctypes++] = typevec_index; ++} ++ ++static void ++pop_processed_type (struct work_stuff *work) ++{ ++ work->nproctypes--; ++} ++ ++static void + remember_type (struct work_stuff *work, const char *start, int len) + { + char *tem; +@@ -4515,10 +4580,13 @@ demangle_args (struct work_stuff *work, const char **mangled, + { + string_append (declp, ", "); + } ++ push_processed_type (work, t); + if (!do_arg (work, &tem, &arg)) + { ++ pop_processed_type (work); + return (0); + } ++ pop_processed_type (work); + if (PRINT_ARG_TYPES) + { + string_appends (declp, &arg); +diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected +index 1d8b771..d690b23 100644 +--- a/libiberty/testsuite/demangle-expected ++++ b/libiberty/testsuite/demangle-expected +@@ -4429,3 +4429,21 @@ __vt_90000000000cafebabe + + _Z80800000000000000000000 + _Z80800000000000000000000 ++# ++# Tests write access violation PR70926 ++ ++0__Ot2m02R5T0000500000 ++0__Ot2m02R5T0000500000 ++# ++ ++0__GT50000000000_ ++0__GT50000000000_ ++# ++ ++__t2m05B500000000000000000_ ++__t2m05B500000000000000000_ ++# ++# Tests stack overflow PR71696 ++ ++__10%0__S4_0T0T0 ++%0<>::%0(%0<>) +-- +2.9.3 + diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0041-ssp_nonshared.patch b/meta/recipes-devtools/gcc/gcc-6.2/0041-ssp_nonshared.patch deleted file mode 100644 index 0744529741..0000000000 --- a/meta/recipes-devtools/gcc/gcc-6.2/0041-ssp_nonshared.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 551a5db7acb56e085a101f1c222d51b2c1b039a4 Mon Sep 17 00:00:00 2001 -From: Szabolcs Nagy <nsz@port70.net> -Date: Sat, 7 Nov 2015 14:58:40 +0000 -Subject: [PATCH 41/46] ssp_nonshared - ---- -Upstream-Status: Inappropriate [OE Configuration] - - gcc/gcc.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/gcc/gcc.c b/gcc/gcc.c -index 2812819..9de96ee 100644 ---- a/gcc/gcc.c -+++ b/gcc/gcc.c -@@ -863,7 +863,8 @@ proper position among the other output files. */ - #ifndef LINK_SSP_SPEC - #ifdef TARGET_LIBC_PROVIDES_SSP - #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ -- "|fstack-protector-strong|fstack-protector-explicit:}" -+ "|fstack-protector-strong|fstack-protector-explicit" \ -+ ":-lssp_nonshared}" - #else - #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ - "|fstack-protector-strong|fstack-protector-explicit" \ --- -2.8.2 - diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0048-ARM-PR-target-71056-Don-t-use-vectorized-builtins-wh.patch b/meta/recipes-devtools/gcc/gcc-6.2/0048-ARM-PR-target-71056-Don-t-use-vectorized-builtins-wh.patch deleted file mode 100644 index 9c39c7f7ad..0000000000 --- a/meta/recipes-devtools/gcc/gcc-6.2/0048-ARM-PR-target-71056-Don-t-use-vectorized-builtins-wh.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 84d2a5509892b65ed60d39e6e2f9719e3762e40e Mon Sep 17 00:00:00 2001 -From: ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> -Date: Tue, 31 May 2016 08:29:39 +0000 -Subject: [PATCH] [ARM] PR target/71056: Don't use vectorized builtins when - NEON is not available - - PR target/71056 - * config/arm/arm-builtins.c (arm_builtin_vectorized_function): Return - NULL_TREE early if NEON is not available. Remove now redundant check - in ARM_CHECK_BUILTIN_MODE. - - * gcc.target/arm/pr71056.c: New test. - - - -git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@236910 138bc75d-0d04-0410-961f-82ee72b054a4 ---- -Upstream-Status: Backport -Signed-off-by: Khem Raj <raj.khem@gmail.com> - - gcc/ChangeLog | 7 +++++++ - gcc/config/arm/arm-builtins.c | 6 +++++- - gcc/testsuite/ChangeLog | 5 +++++ - gcc/testsuite/gcc.target/arm/pr71056.c | 32 ++++++++++++++++++++++++++++++++ - 4 files changed, 49 insertions(+), 1 deletion(-) - create mode 100644 gcc/testsuite/gcc.target/arm/pr71056.c - -diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c -index 90fb40f..68b2839 100644 ---- a/gcc/config/arm/arm-builtins.c -+++ b/gcc/config/arm/arm-builtins.c -@@ -2861,6 +2861,10 @@ arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) - int in_n, out_n; - bool out_unsigned_p = TYPE_UNSIGNED (type_out); - -+ /* Can't provide any vectorized builtins when we can't use NEON. */ -+ if (!TARGET_NEON) -+ return NULL_TREE; -+ - if (TREE_CODE (type_out) != VECTOR_TYPE - || TREE_CODE (type_in) != VECTOR_TYPE) - return NULL_TREE; -@@ -2875,7 +2879,7 @@ arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in) - NULL_TREE is returned if no such builtin is available. */ - #undef ARM_CHECK_BUILTIN_MODE - #define ARM_CHECK_BUILTIN_MODE(C) \ -- (TARGET_NEON && TARGET_FPU_ARMV8 \ -+ (TARGET_FPU_ARMV8 \ - && flag_unsafe_math_optimizations \ - && ARM_CHECK_BUILTIN_MODE_1 (C)) - -diff --git a/gcc/testsuite/gcc.target/arm/pr71056.c b/gcc/testsuite/gcc.target/arm/pr71056.c -new file mode 100644 -index 0000000..136754e ---- /dev/null -+++ b/gcc/testsuite/gcc.target/arm/pr71056.c -@@ -0,0 +1,32 @@ -+/* PR target/71056. */ -+/* { dg-do compile } */ -+/* { dg-require-effective-target arm_vfp3_ok } */ -+/* { dg-options "-O3 -mfpu=vfpv3" } */ -+ -+/* Check that compiling for a non-NEON target doesn't try to introduce -+ a NEON vectorized builtin. */ -+ -+extern char *buff; -+int f2 (); -+struct T1 -+{ -+ int reserved[2]; -+ unsigned int ip; -+ unsigned short cs; -+ unsigned short rsrv2; -+}; -+void -+f3 (const char *p) -+{ -+ struct T1 x; -+ __builtin_memcpy (&x, p, sizeof (struct T1)); -+ x.reserved[0] = __builtin_bswap32 (x.reserved[0]); -+ x.reserved[1] = __builtin_bswap32 (x.reserved[1]); -+ x.ip = __builtin_bswap32 (x.ip); -+ x.cs = x.cs << 8 | x.cs >> 8; -+ x.rsrv2 = x.rsrv2 << 8 | x.rsrv2 >> 8; -+ if (f2 ()) -+ { -+ __builtin_memcpy (buff, "\n", 1); -+ } -+} --- -2.9.0 - diff --git a/meta/recipes-devtools/gcc/gcc-6.2/CVE-2016-4490.patch b/meta/recipes-devtools/gcc/gcc-6.2/CVE-2016-4490.patch deleted file mode 100644 index f32e91d4fc..0000000000 --- a/meta/recipes-devtools/gcc/gcc-6.2/CVE-2016-4490.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 7d235b1b5ea35352c54957ef5530d9a02c46962f Mon Sep 17 00:00:00 2001 -From: bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> -Date: Mon, 2 May 2016 17:06:40 +0000 -Subject: [PATCH] =?UTF-8?q?Demangler=20integer=20overflow=20fixes=20from?= - =?UTF-8?q?=20Marcel=20B=C3=B6hme.?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - PR c++/70498 - * cp-demangle.c: Parse numbers as integer instead of long to avoid - overflow after sanity checks. Include <limits.h> if available. - (INT_MAX): Define if necessary. - (d_make_template_param): Takes integer argument instead of long. - (d_make_function_param): Likewise. - (d_append_num): Likewise. - (d_identifier): Likewise. - (d_number): Parse as and return integer. - (d_compact_number): Handle overflow. - (d_source_name): Change variable type to integer for parsed number. - (d_java_resource): Likewise. - (d_special_name): Likewise. - (d_discriminator): Likewise. - (d_unnamed_type): Likewise. - * testsuite/demangle-expected: Add regression test cases. - - - -git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235767 138bc75d-0d04-0410-961f-82ee72b054a4 - -Upstream-Status: Backport -CVE: CVE-2016-4490 -[Yocto #9632] - -Signed-off-by: Armin Kuster <akuster@mvista.com> - ---- - libiberty/ChangeLog | 19 +++++++++++++ - libiberty/cp-demangle.c | 52 ++++++++++++++++++++--------------- - libiberty/testsuite/demangle-expected | 14 ++++++++-- - 3 files changed, 61 insertions(+), 24 deletions(-) - -Index: git/libiberty/ChangeLog -=================================================================== ---- git.orig/libiberty/ChangeLog -+++ git/libiberty/ChangeLog -@@ -1,3 +1,22 @@ -+2016-05-02 Marcel Böhme <boehme.marcel@gmail.com> -+ -+ PR c++/70498 -+ * cp-demangle.c: Parse numbers as integer instead of long to avoid -+ overflow after sanity checks. Include <limits.h> if available. -+ (INT_MAX): Define if necessary. -+ (d_make_template_param): Takes integer argument instead of long. -+ (d_make_function_param): Likewise. -+ (d_append_num): Likewise. -+ (d_identifier): Likewise. -+ (d_number): Parse as and return integer. -+ (d_compact_number): Handle overflow. -+ (d_source_name): Change variable type to integer for parsed number. -+ (d_java_resource): Likewise. -+ (d_special_name): Likewise. -+ (d_discriminator): Likewise. -+ (d_unnamed_type): Likewise. -+ * testsuite/demangle-expected: Add regression test cases. -+ - 2016-04-27 Release Manager - - * GCC 6.1.0 released. -Index: git/libiberty/cp-demangle.c -=================================================================== ---- git.orig/libiberty/cp-demangle.c -+++ git/libiberty/cp-demangle.c -@@ -128,6 +128,13 @@ extern char *alloca (); - # endif /* alloca */ - #endif /* HAVE_ALLOCA_H */ - -+#ifdef HAVE_LIMITS_H -+#include <limits.h> -+#endif -+#ifndef INT_MAX -+# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ -+#endif -+ - #include "ansidecl.h" - #include "libiberty.h" - #include "demangle.h" -@@ -398,7 +405,7 @@ d_make_dtor (struct d_info *, enum gnu_v - struct demangle_component *); - - static struct demangle_component * --d_make_template_param (struct d_info *, long); -+d_make_template_param (struct d_info *, int); - - static struct demangle_component * - d_make_sub (struct d_info *, const char *, int); -@@ -421,9 +428,9 @@ static struct demangle_component *d_unqu - - static struct demangle_component *d_source_name (struct d_info *); - --static long d_number (struct d_info *); -+static int d_number (struct d_info *); - --static struct demangle_component *d_identifier (struct d_info *, long); -+static struct demangle_component *d_identifier (struct d_info *, int); - - static struct demangle_component *d_operator_name (struct d_info *); - -@@ -1119,7 +1126,7 @@ d_make_dtor (struct d_info *di, enum gnu - /* Add a new template parameter. */ - - static struct demangle_component * --d_make_template_param (struct d_info *di, long i) -+d_make_template_param (struct d_info *di, int i) - { - struct demangle_component *p; - -@@ -1135,7 +1142,7 @@ d_make_template_param (struct d_info *di - /* Add a new function parameter. */ - - static struct demangle_component * --d_make_function_param (struct d_info *di, long i) -+d_make_function_param (struct d_info *di, int i) - { - struct demangle_component *p; - -@@ -1620,7 +1627,7 @@ d_unqualified_name (struct d_info *di) - static struct demangle_component * - d_source_name (struct d_info *di) - { -- long len; -+ int len; - struct demangle_component *ret; - - len = d_number (di); -@@ -1633,12 +1640,12 @@ d_source_name (struct d_info *di) - - /* number ::= [n] <(non-negative decimal integer)> */ - --static long -+static int - d_number (struct d_info *di) - { - int negative; - char peek; -- long ret; -+ int ret; - - negative = 0; - peek = d_peek_char (di); -@@ -1681,7 +1688,7 @@ d_number_component (struct d_info *di) - /* identifier ::= <(unqualified source code identifier)> */ - - static struct demangle_component * --d_identifier (struct d_info *di, long len) -+d_identifier (struct d_info *di, int len) - { - const char *name; - -@@ -1702,7 +1709,7 @@ d_identifier (struct d_info *di, long le - /* Look for something which looks like a gcc encoding of an - anonymous namespace, and replace it with a more user friendly - name. */ -- if (len >= (long) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2 -+ if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2 - && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX, - ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0) - { -@@ -1870,7 +1877,7 @@ d_java_resource (struct d_info *di) - { - struct demangle_component *p = NULL; - struct demangle_component *next = NULL; -- long len, i; -+ int len, i; - char c; - const char *str; - -@@ -2012,7 +2019,7 @@ d_special_name (struct d_info *di) - case 'C': - { - struct demangle_component *derived_type; -- long offset; -+ int offset; - struct demangle_component *base_type; - - derived_type = cplus_demangle_type (di); -@@ -2946,10 +2953,10 @@ d_pointer_to_member_type (struct d_info - - /* <non-negative number> _ */ - --static long -+static int - d_compact_number (struct d_info *di) - { -- long num; -+ int num; - if (d_peek_char (di) == '_') - num = 0; - else if (d_peek_char (di) == 'n') -@@ -2957,7 +2964,7 @@ d_compact_number (struct d_info *di) - else - num = d_number (di) + 1; - -- if (! d_check_char (di, '_')) -+ if (num < 0 || ! d_check_char (di, '_')) - return -1; - return num; - } -@@ -2969,7 +2976,7 @@ d_compact_number (struct d_info *di) - static struct demangle_component * - d_template_param (struct d_info *di) - { -- long param; -+ int param; - - if (! d_check_char (di, 'T')) - return NULL; -@@ -3171,9 +3178,10 @@ d_expression_1 (struct d_info *di) - } - else - { -- index = d_compact_number (di) + 1; -- if (index == 0) -+ index = d_compact_number (di); -+ if (index == INT_MAX || index == -1) - return NULL; -+ index ++; - } - return d_make_function_param (di, index); - } -@@ -3502,7 +3510,7 @@ d_local_name (struct d_info *di) - static int - d_discriminator (struct d_info *di) - { -- long discrim; -+ int discrim; - - if (d_peek_char (di) != '_') - return 1; -@@ -3558,7 +3566,7 @@ static struct demangle_component * - d_unnamed_type (struct d_info *di) - { - struct demangle_component *ret; -- long num; -+ int num; - - if (! d_check_char (di, 'U')) - return NULL; -@@ -4086,10 +4094,10 @@ d_append_string (struct d_print_info *dp - } - - static inline void --d_append_num (struct d_print_info *dpi, long l) -+d_append_num (struct d_print_info *dpi, int l) - { - char buf[25]; -- sprintf (buf,"%ld", l); -+ sprintf (buf,"%d", l); - d_append_string (dpi, buf); - } - -Index: git/libiberty/testsuite/demangle-expected -=================================================================== ---- git.orig/libiberty/testsuite/demangle-expected -+++ git/libiberty/testsuite/demangle-expected -@@ -4422,12 +4422,22 @@ void baz<int>(A<sizeof (foo((int)(), (fl - _Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv - X<sizeof ((P(((F)())())).array)>::Type foo<F>() - # --# Tests a use-after-free problem -+# Tests a use-after-free problem PR70481 - - _Q.__0 - ::Q.(void) - # --# Tests a use-after-free problem -+# Tests a use-after-free problem PR70481 - - _Q10-__9cafebabe. - cafebabe.::-(void) -+# -+# Tests integer overflow problem PR70492 -+ -+__vt_90000000000cafebabe -+__vt_90000000000cafebabe -+# -+# Tests write access violation PR70498 -+ -+_Z80800000000000000000000 -+_Z80800000000000000000000 diff --git a/meta/recipes-devtools/gcc/gcc-6.2/ubsan-fix-check-empty-string.patch b/meta/recipes-devtools/gcc/gcc-6.2/ubsan-fix-check-empty-string.patch deleted file mode 100644 index c0127198e0..0000000000 --- a/meta/recipes-devtools/gcc/gcc-6.2/ubsan-fix-check-empty-string.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8db2cf6353c13f2a84cbe49b689654897906c499 Mon Sep 17 00:00:00 2001 -From: kyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4> -Date: Sat, 3 Sep 2016 10:57:05 +0000 -Subject: [PATCH] gcc/ * ubsan.c (ubsan_use_new_style_p): Fix check for empty - string. - -git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239971 138bc75d-0d04-0410-961f-82ee72b054a4 - -Upstream-Status: Backport -Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> - ---- - gcc/ubsan.c | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -Index: gcc-6.3.0/gcc/ubsan.c -=================================================================== ---- gcc-6.3.0.orig/gcc/ubsan.c -+++ gcc-6.3.0/gcc/ubsan.c -@@ -1471,7 +1471,7 @@ ubsan_use_new_style_p (location_t loc) - - expanded_location xloc = expand_location (loc); - if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 -- || xloc.file == '\0' || xloc.file[0] == '\xff' -+ || xloc.file[0] == '\0' || xloc.file[0] == '\xff' - || xloc.file[1] == '\xff') - return false; - diff --git a/meta/recipes-devtools/gcc/gcc-6.2.inc b/meta/recipes-devtools/gcc/gcc-6.4.inc index 39ae653805..daa9e42af8 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2.inc +++ b/meta/recipes-devtools/gcc/gcc-6.4.inc @@ -2,13 +2,13 @@ require gcc-common.inc # Third digit in PV should be incremented after a minor release -PV = "6.2.0" +PV = "6.4.0" # BINV should be incremented to a revision after a minor gcc release -BINV = "6.2.0" +BINV = "6.4.0" -FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-6.2:${FILE_DIRNAME}/gcc-6.2/backport:" +FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-6.4:${FILE_DIRNAME}/gcc-6.4/backport:" DEPENDS =+ "mpfr gmp libmpc zlib" NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native" @@ -24,7 +24,7 @@ LIC_FILES_CHKSUM = "\ " -BASEURI ?= "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.bz2" +BASEURI ?= "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.xz" #SRCREV = "bd9a826d5448db11d29d2ec5884e7e679066f140" #BASEURI ?= "git://github.com/gcc-mirror/gcc;branch=gcc-6-branch;protocol=git" #BASEURI ?= "ftp://sourceware.org/pub/gcc/snapshots/6.2.0-RC-20160815/gcc-6.2.0-RC-20160815.tar.bz2" @@ -71,20 +71,38 @@ SRC_URI = "\ file://0038-Search-target-sysroot-gcc-version-specific-dirs-with.patch \ file://0039-Fix-various-_FOR_BUILD-and-related-variables.patch \ file://0040-nios2-Define-MUSL_DYNAMIC_LINKER.patch \ - file://0041-ssp_nonshared.patch \ + file://0041-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch \ file://0042-gcc-libcpp-support-ffile-prefix-map-old-new.patch \ file://0043-Reuse-fdebug-prefix-map-to-replace-ffile-prefix-map.patch \ file://0044-gcc-final.c-fdebug-prefix-map-support-to-remap-sourc.patch \ file://0045-libgcc-Add-knob-to-use-ldbl-128-on-ppc.patch \ file://0046-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch \ file://0047-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch \ + file://0048-sync-gcc-stddef.h-with-musl.patch \ + file://0054_all_nopie-all-flags.patch \ + file://0055-unwind_h-glibc26.patch \ ${BACKPORTS} \ " BACKPORTS = "\ - file://ubsan-fix-check-empty-string.patch \ + file://CVE-2016-6131.patch \ + file://0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch \ + file://0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch \ + file://0001-i386-Move-struct-ix86_frame-to-machine_function.patch \ + file://0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch \ + file://0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch \ + file://0004-x86-Add-mindirect-branch.patch \ + file://0005-x86-Add-mfunction-return.patch \ + file://0006-x86-Add-mindirect-branch-register.patch \ + file://0007-x86-Add-V-register-operand-modifier.patch \ + file://0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch \ + file://0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch \ + file://0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch \ + file://0011-i386-Update-mfunction-return-for-return-with-pop.patch \ + file://0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch \ " -SRC_URI[md5sum] = "9768625159663b300ae4de2f4745fcc4" -SRC_URI[sha256sum] = "9944589fc722d3e66308c0ce5257788ebd7872982a718aa2516123940671b7c5" + +SRC_URI[md5sum] = "11ba51a0cfb8471927f387c8895fe232" +SRC_URI[sha256sum] = "850bf21eafdfe5cd5f6827148184c08c4a0852a37ccf36ce69855334d2c914d4" S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}" #S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/git" diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch b/meta/recipes-devtools/gcc/gcc-6.4/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch index 415f091ee7..415f091ee7 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0002-uclibc-conf.patch b/meta/recipes-devtools/gcc/gcc-6.4/0002-uclibc-conf.patch index 4d284ef862..4d284ef862 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0002-uclibc-conf.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0002-uclibc-conf.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0003-gcc-uclibc-locale-ctype_touplow_t.patch b/meta/recipes-devtools/gcc/gcc-6.4/0003-gcc-uclibc-locale-ctype_touplow_t.patch index df07febee2..df07febee2 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0003-gcc-uclibc-locale-ctype_touplow_t.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0003-gcc-uclibc-locale-ctype_touplow_t.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0004-uclibc-locale.patch b/meta/recipes-devtools/gcc/gcc-6.4/0004-uclibc-locale.patch index ae2627c2ef..ae2627c2ef 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0004-uclibc-locale.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0004-uclibc-locale.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0005-uclibc-locale-no__x.patch b/meta/recipes-devtools/gcc/gcc-6.4/0005-uclibc-locale-no__x.patch index 3275016e77..3275016e77 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0005-uclibc-locale-no__x.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0005-uclibc-locale-no__x.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0006-uclibc-locale-wchar_fix.patch b/meta/recipes-devtools/gcc/gcc-6.4/0006-uclibc-locale-wchar_fix.patch index e45a482d53..e45a482d53 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0006-uclibc-locale-wchar_fix.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0006-uclibc-locale-wchar_fix.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0007-uclibc-locale-update.patch b/meta/recipes-devtools/gcc/gcc-6.4/0007-uclibc-locale-update.patch index b73e5914e2..b73e5914e2 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0007-uclibc-locale-update.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0007-uclibc-locale-update.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0008-missing-execinfo_h.patch b/meta/recipes-devtools/gcc/gcc-6.4/0008-missing-execinfo_h.patch index 01e7c9549e..01e7c9549e 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0008-missing-execinfo_h.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0008-missing-execinfo_h.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0009-c99-snprintf.patch b/meta/recipes-devtools/gcc/gcc-6.4/0009-c99-snprintf.patch index d62341ac65..d62341ac65 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0009-c99-snprintf.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0009-c99-snprintf.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0010-gcc-poison-system-directories.patch b/meta/recipes-devtools/gcc/gcc-6.4/0010-gcc-poison-system-directories.patch index ac4cf442da..ac4cf442da 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0010-gcc-poison-system-directories.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0010-gcc-poison-system-directories.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0011-gcc-poison-dir-extend.patch b/meta/recipes-devtools/gcc/gcc-6.4/0011-gcc-poison-dir-extend.patch index a1736aea12..a1736aea12 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0011-gcc-poison-dir-extend.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0011-gcc-poison-dir-extend.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0012-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch b/meta/recipes-devtools/gcc/gcc-6.4/0012-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch index 939b0705f8..939b0705f8 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0012-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0012-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0013-64-bit-multilib-hack.patch b/meta/recipes-devtools/gcc/gcc-6.4/0013-64-bit-multilib-hack.patch index e31cde4317..e31cde4317 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0013-64-bit-multilib-hack.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0013-64-bit-multilib-hack.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0014-optional-libstdc.patch b/meta/recipes-devtools/gcc/gcc-6.4/0014-optional-libstdc.patch index 44b0cc7d6e..44b0cc7d6e 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0014-optional-libstdc.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0014-optional-libstdc.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0015-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch b/meta/recipes-devtools/gcc/gcc-6.4/0015-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch index 6fc7346f6e..6fc7346f6e 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0015-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0015-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0016-COLLECT_GCC_OPTIONS.patch b/meta/recipes-devtools/gcc/gcc-6.4/0016-COLLECT_GCC_OPTIONS.patch index c1548647c7..c1548647c7 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0016-COLLECT_GCC_OPTIONS.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0016-COLLECT_GCC_OPTIONS.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0017-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch b/meta/recipes-devtools/gcc/gcc-6.4/0017-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch index 0dbabd9e93..0dbabd9e93 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0017-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0017-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0018-fortran-cross-compile-hack.patch b/meta/recipes-devtools/gcc/gcc-6.4/0018-fortran-cross-compile-hack.patch index b43d89ea84..b43d89ea84 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0018-fortran-cross-compile-hack.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0018-fortran-cross-compile-hack.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0019-cpp-honor-sysroot.patch b/meta/recipes-devtools/gcc/gcc-6.4/0019-cpp-honor-sysroot.patch index 417a5ede4d..417a5ede4d 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0019-cpp-honor-sysroot.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0019-cpp-honor-sysroot.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0020-MIPS64-Default-to-N64-ABI.patch b/meta/recipes-devtools/gcc/gcc-6.4/0020-MIPS64-Default-to-N64-ABI.patch index ba612f5458..ba612f5458 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0020-MIPS64-Default-to-N64-ABI.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0020-MIPS64-Default-to-N64-ABI.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0021-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch b/meta/recipes-devtools/gcc/gcc-6.4/0021-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch index 6675ce34fa..6675ce34fa 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0021-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0021-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0022-gcc-Fix-argument-list-too-long-error.patch b/meta/recipes-devtools/gcc/gcc-6.4/0022-gcc-Fix-argument-list-too-long-error.patch index fab6e4aeb7..fab6e4aeb7 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0022-gcc-Fix-argument-list-too-long-error.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0022-gcc-Fix-argument-list-too-long-error.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0023-Disable-sdt.patch b/meta/recipes-devtools/gcc/gcc-6.4/0023-Disable-sdt.patch index 0efd890aa7..0efd890aa7 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0023-Disable-sdt.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0023-Disable-sdt.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0024-libtool.patch b/meta/recipes-devtools/gcc/gcc-6.4/0024-libtool.patch index 1f73b5db5a..1f73b5db5a 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0024-libtool.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0024-libtool.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0025-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch b/meta/recipes-devtools/gcc/gcc-6.4/0025-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch index 3b7ee497f3..3b7ee497f3 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0025-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0025-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0026-Use-the-multilib-config-files-from-B-instead-of-usin.patch b/meta/recipes-devtools/gcc/gcc-6.4/0026-Use-the-multilib-config-files-from-B-instead-of-usin.patch index be25be6162..be25be6162 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0026-Use-the-multilib-config-files-from-B-instead-of-usin.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0026-Use-the-multilib-config-files-from-B-instead-of-usin.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0027-Avoid-using-libdir-from-.la-which-usually-points-to-.patch b/meta/recipes-devtools/gcc/gcc-6.4/0027-Avoid-using-libdir-from-.la-which-usually-points-to-.patch index d1bbebc0a8..d1bbebc0a8 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0027-Avoid-using-libdir-from-.la-which-usually-points-to-.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0027-Avoid-using-libdir-from-.la-which-usually-points-to-.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0028-export-CPP.patch b/meta/recipes-devtools/gcc/gcc-6.4/0028-export-CPP.patch index c21253938c..c21253938c 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0028-export-CPP.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0028-export-CPP.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0029-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch b/meta/recipes-devtools/gcc/gcc-6.4/0029-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch index 47b9c0d1b1..47b9c0d1b1 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0029-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0029-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0030-Disable-the-MULTILIB_OSDIRNAMES-and-other-multilib-o.patch b/meta/recipes-devtools/gcc/gcc-6.4/0030-Disable-the-MULTILIB_OSDIRNAMES-and-other-multilib-o.patch index c09d0192ef..c09d0192ef 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0030-Disable-the-MULTILIB_OSDIRNAMES-and-other-multilib-o.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0030-Disable-the-MULTILIB_OSDIRNAMES-and-other-multilib-o.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0031-Ensure-target-gcc-headers-can-be-included.patch b/meta/recipes-devtools/gcc/gcc-6.4/0031-Ensure-target-gcc-headers-can-be-included.patch index fb1cd0f169..fb1cd0f169 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0031-Ensure-target-gcc-headers-can-be-included.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0031-Ensure-target-gcc-headers-can-be-included.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0032-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch b/meta/recipes-devtools/gcc/gcc-6.4/0032-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch index c0b001db51..c0b001db51 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0032-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0032-gcc-4.8-won-t-build-with-disable-dependency-tracking.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0033-Don-t-search-host-directory-during-relink-if-inst_pr.patch b/meta/recipes-devtools/gcc/gcc-6.4/0033-Don-t-search-host-directory-during-relink-if-inst_pr.patch index e425d71463..e425d71463 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0033-Don-t-search-host-directory-during-relink-if-inst_pr.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0033-Don-t-search-host-directory-during-relink-if-inst_pr.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0034-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch b/meta/recipes-devtools/gcc/gcc-6.4/0034-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch index 922a8555b6..922a8555b6 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0034-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0034-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0035-aarch64-Add-support-for-musl-ldso.patch b/meta/recipes-devtools/gcc/gcc-6.4/0035-aarch64-Add-support-for-musl-ldso.patch index 9dfc47276f..9dfc47276f 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0035-aarch64-Add-support-for-musl-ldso.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0035-aarch64-Add-support-for-musl-ldso.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0036-libcc1-fix-libcc1-s-install-path-and-rpath.patch b/meta/recipes-devtools/gcc/gcc-6.4/0036-libcc1-fix-libcc1-s-install-path-and-rpath.patch index f89a8860f9..f89a8860f9 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0036-libcc1-fix-libcc1-s-install-path-and-rpath.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0036-libcc1-fix-libcc1-s-install-path-and-rpath.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0037-handle-sysroot-support-for-nativesdk-gcc.patch b/meta/recipes-devtools/gcc/gcc-6.4/0037-handle-sysroot-support-for-nativesdk-gcc.patch index 15efcb12ed..15efcb12ed 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0037-handle-sysroot-support-for-nativesdk-gcc.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0037-handle-sysroot-support-for-nativesdk-gcc.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0038-Search-target-sysroot-gcc-version-specific-dirs-with.patch b/meta/recipes-devtools/gcc/gcc-6.4/0038-Search-target-sysroot-gcc-version-specific-dirs-with.patch index 89ee79db89..89ee79db89 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0038-Search-target-sysroot-gcc-version-specific-dirs-with.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0038-Search-target-sysroot-gcc-version-specific-dirs-with.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0039-Fix-various-_FOR_BUILD-and-related-variables.patch b/meta/recipes-devtools/gcc/gcc-6.4/0039-Fix-various-_FOR_BUILD-and-related-variables.patch index 0ce7aec790..0ce7aec790 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0039-Fix-various-_FOR_BUILD-and-related-variables.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0039-Fix-various-_FOR_BUILD-and-related-variables.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0040-nios2-Define-MUSL_DYNAMIC_LINKER.patch b/meta/recipes-devtools/gcc/gcc-6.4/0040-nios2-Define-MUSL_DYNAMIC_LINKER.patch index c9a6fd0ebc..c9a6fd0ebc 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0040-nios2-Define-MUSL_DYNAMIC_LINKER.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0040-nios2-Define-MUSL_DYNAMIC_LINKER.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.4/0041-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch b/meta/recipes-devtools/gcc/gcc-6.4/0041-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch new file mode 100644 index 0000000000..29b7ce72d2 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/0041-Add-ssp_nonshared-to-link-commandline-for-musl-targe.patch @@ -0,0 +1,87 @@ +From 210f6b3b82084cc756e02b8bc12f909a43b14ee8 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Tue, 27 Jun 2017 18:10:54 -0700 +Subject: [PATCH 40/49] Add ssp_nonshared to link commandline for musl targets + +when -fstack-protector options are enabled we need to +link with ssp_shared on musl since it does not provide +the __stack_chk_fail_local() so essentially it provides +libssp but not libssp_nonshared something like +TARGET_LIBC_PROVIDES_SSP_BUT_NOT_SSP_NONSHARED + where-as for glibc the needed symbols +are already present in libc_nonshared library therefore +we do not need any library helper on glibc based systems +but musl needs the libssp_noshared from gcc + +Upstream-Status: Pending + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + gcc/config/linux.h | 7 +++++++ + gcc/config/rs6000/linux.h | 10 ++++++++++ + gcc/config/rs6000/linux64.h | 10 ++++++++++ + 3 files changed, 27 insertions(+) + +diff --git a/gcc/config/linux.h b/gcc/config/linux.h +index 2e683d0c430..1b4df798671 100644 +--- a/gcc/config/linux.h ++++ b/gcc/config/linux.h +@@ -182,6 +182,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + { GCC_INCLUDE_DIR, "GCC", 0, 1, 0, 0 }, \ + { 0, 0, 0, 0, 0, 0 } \ + } ++#ifdef TARGET_LIBC_PROVIDES_SSP ++#undef LINK_SSP_SPEC ++#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ ++ "|fstack-protector-strong|fstack-protector-explicit" \ ++ ":-lssp_nonshared}" ++#endif ++ + #endif + + #if (DEFAULT_LIBC == LIBC_UCLIBC) && defined (SINGLE_LIBC) /* uClinux */ +diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h +index 684afd6c190..22cfa391b89 100644 +--- a/gcc/config/rs6000/linux.h ++++ b/gcc/config/rs6000/linux.h +@@ -91,6 +91,16 @@ + " -m elf32ppclinux") + #endif + ++/* link libssp_nonshared.a with musl */ ++#if DEFAULT_LIBC == LIBC_MUSL ++#ifdef TARGET_LIBC_PROVIDES_SSP ++#undef LINK_SSP_SPEC ++#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ ++ "|fstack-protector-strong|fstack-protector-explicit" \ ++ ":-lssp_nonshared}" ++#endif ++#endif ++ + #undef LINK_OS_LINUX_SPEC + #define LINK_OS_LINUX_SPEC LINK_OS_LINUX_EMUL " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ +diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h +index 3b00ec0fcf0..8371f8d7b6b 100644 +--- a/gcc/config/rs6000/linux64.h ++++ b/gcc/config/rs6000/linux64.h +@@ -465,6 +465,16 @@ extern int dot_symbols; + " -m elf64ppc") + #endif + ++/* link libssp_nonshared.a with musl */ ++#if DEFAULT_LIBC == LIBC_MUSL ++#ifdef TARGET_LIBC_PROVIDES_SSP ++#undef LINK_SSP_SPEC ++#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \ ++ "|fstack-protector-strong|fstack-protector-explicit" \ ++ ":-lssp_nonshared}" ++#endif ++#endif ++ + #define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \ +-- +2.13.2 + diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0042-gcc-libcpp-support-ffile-prefix-map-old-new.patch b/meta/recipes-devtools/gcc/gcc-6.4/0042-gcc-libcpp-support-ffile-prefix-map-old-new.patch index 861f0fd7f1..861f0fd7f1 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0042-gcc-libcpp-support-ffile-prefix-map-old-new.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0042-gcc-libcpp-support-ffile-prefix-map-old-new.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0043-Reuse-fdebug-prefix-map-to-replace-ffile-prefix-map.patch b/meta/recipes-devtools/gcc/gcc-6.4/0043-Reuse-fdebug-prefix-map-to-replace-ffile-prefix-map.patch index 0077f80e46..0077f80e46 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0043-Reuse-fdebug-prefix-map-to-replace-ffile-prefix-map.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0043-Reuse-fdebug-prefix-map-to-replace-ffile-prefix-map.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0044-gcc-final.c-fdebug-prefix-map-support-to-remap-sourc.patch b/meta/recipes-devtools/gcc/gcc-6.4/0044-gcc-final.c-fdebug-prefix-map-support-to-remap-sourc.patch index 5d41af44a4..5d41af44a4 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0044-gcc-final.c-fdebug-prefix-map-support-to-remap-sourc.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0044-gcc-final.c-fdebug-prefix-map-support-to-remap-sourc.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0045-libgcc-Add-knob-to-use-ldbl-128-on-ppc.patch b/meta/recipes-devtools/gcc/gcc-6.4/0045-libgcc-Add-knob-to-use-ldbl-128-on-ppc.patch index c62b727d6e..c62b727d6e 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0045-libgcc-Add-knob-to-use-ldbl-128-on-ppc.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0045-libgcc-Add-knob-to-use-ldbl-128-on-ppc.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0046-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch b/meta/recipes-devtools/gcc/gcc-6.4/0046-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch index 390037f7b1..390037f7b1 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0046-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0046-Link-libgcc-using-LDFLAGS-not-just-SHLIB_LDFLAGS.patch diff --git a/meta/recipes-devtools/gcc/gcc-6.2/0047-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch b/meta/recipes-devtools/gcc/gcc-6.4/0047-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch index ed6cd6905c..6b5da0254e 100644 --- a/meta/recipes-devtools/gcc/gcc-6.2/0047-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch +++ b/meta/recipes-devtools/gcc/gcc-6.4/0047-libgcc_s-Use-alias-for-__cpu_indicator_init-instead-.patch @@ -31,7 +31,7 @@ gcc/Changelog: Signed-off-by: Khem Raj <raj.khem@gmail.com> --- -Upstream-Status: Rejected +Upstream-Status: Denied gcc/config/i386/i386.c | 4 ++-- libgcc/config/i386/cpuinfo.c | 6 +++--- diff --git a/meta/recipes-devtools/gcc/gcc-6.4/0048-sync-gcc-stddef.h-with-musl.patch b/meta/recipes-devtools/gcc/gcc-6.4/0048-sync-gcc-stddef.h-with-musl.patch new file mode 100644 index 0000000000..30c158d7da --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/0048-sync-gcc-stddef.h-with-musl.patch @@ -0,0 +1,91 @@ +From 10595c03c39b4e980d2a00e16fc84e9caf82292e Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Fri, 3 Feb 2017 12:56:00 -0800 +Subject: [PATCH 48/48] sync gcc stddef.h with musl + +musl defines ptrdiff_t size_t and wchar_t +so dont define them here if musl is definining them + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- +Upstream-Status: Pending + + gcc/ginclude/stddef.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h +index d711530d053..c315b7a97c1 100644 +--- a/gcc/ginclude/stddef.h ++++ b/gcc/ginclude/stddef.h +@@ -134,6 +134,7 @@ _TYPE_wchar_t; + #ifndef ___int_ptrdiff_t_h + #ifndef _GCC_PTRDIFF_T + #ifndef _PTRDIFF_T_DECLARED /* DragonFly */ ++#ifndef __DEFINED_ptrdiff_t /* musl */ + #define _PTRDIFF_T + #define _T_PTRDIFF_ + #define _T_PTRDIFF +@@ -143,10 +144,12 @@ _TYPE_wchar_t; + #define ___int_ptrdiff_t_h + #define _GCC_PTRDIFF_T + #define _PTRDIFF_T_DECLARED ++#define __DEFINED_ptrdiff_t /* musl */ + #ifndef __PTRDIFF_TYPE__ + #define __PTRDIFF_TYPE__ long int + #endif + typedef __PTRDIFF_TYPE__ ptrdiff_t; ++#endif /* __DEFINED_ptrdiff_t */ + #endif /* _PTRDIFF_T_DECLARED */ + #endif /* _GCC_PTRDIFF_T */ + #endif /* ___int_ptrdiff_t_h */ +@@ -184,6 +187,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; + #ifndef _GCC_SIZE_T + #ifndef _SIZET_ + #ifndef __size_t ++#ifndef __DEFINED_size_t /* musl */ + #define __size_t__ /* BeOS */ + #define __SIZE_T__ /* Cray Unicos/Mk */ + #define _SIZE_T +@@ -200,6 +204,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; + #define ___int_size_t_h + #define _GCC_SIZE_T + #define _SIZET_ ++#define __DEFINED_size_t /* musl */ + #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \ + || defined(__DragonFly__) \ + || defined(__FreeBSD_kernel__) +@@ -235,6 +240,7 @@ typedef long ssize_t; + #endif /* _SIZE_T */ + #endif /* __SIZE_T__ */ + #endif /* __size_t__ */ ++#endif /* __DEFINED_size_t */ + #undef __need_size_t + #endif /* _STDDEF_H or __need_size_t. */ + +@@ -264,6 +270,7 @@ typedef long ssize_t; + #ifndef ___int_wchar_t_h + #ifndef __INT_WCHAR_T_H + #ifndef _GCC_WCHAR_T ++#ifndef __DEFINED_wchar_t /* musl */ + #define __wchar_t__ /* BeOS */ + #define __WCHAR_T__ /* Cray Unicos/Mk */ + #define _WCHAR_T +@@ -279,6 +286,7 @@ typedef long ssize_t; + #define __INT_WCHAR_T_H + #define _GCC_WCHAR_T + #define _WCHAR_T_DECLARED ++#define __DEFINED_wchar_t /* musl */ + + /* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_ + instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other +@@ -344,6 +352,7 @@ typedef __WCHAR_TYPE__ wchar_t; + #endif + #endif /* __WCHAR_T__ */ + #endif /* __wchar_t__ */ ++#endif /* __DEFINED_wchar_t musl */ + #undef __need_wchar_t + #endif /* _STDDEF_H or __need_wchar_t. */ + +-- +2.11.0 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/0054_all_nopie-all-flags.patch b/meta/recipes-devtools/gcc/gcc-6.4/0054_all_nopie-all-flags.patch new file mode 100644 index 0000000000..73ab9502dc --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/0054_all_nopie-all-flags.patch @@ -0,0 +1,22 @@ +Need to pass NO_PIE_CFLAGS to ALL_* so gcc doesn't fail when +we compile it with older gcc and pie. + +Upstream-Status: Inappropriate [configuration] + +Maintained by: Gentoo Toolchain Project <toolchain@gentoo.org> +Signed-off-by: Stephen Arnold <stephen.arnold42@gmail.com> + +--- a/gcc/Makefile.in 2015-06-25 19:18:12.000000000 +0200 ++++ b/gcc/Makefile.in 2016-04-22 00:12:54.029178860 +0200 +@@ -991,10 +991,10 @@ ALL_CXXFLAGS = $(T_CFLAGS) $(CFLAGS-$@) + ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS) + + # This is the variable to use when using $(COMPILER). +-ALL_COMPILERFLAGS = $(ALL_CXXFLAGS) ++ALL_COMPILERFLAGS = $(NO_PIE_CFLAGS) $(ALL_CXXFLAGS) + + # This is the variable to use when using $(LINKER). +-ALL_LINKERFLAGS = $(ALL_CXXFLAGS) ++ALL_LINKERFLAGS = $(NO_PIE_CFLAGS) $(ALL_CXXFLAGS) + + # Build and host support libraries. diff --git a/meta/recipes-devtools/gcc/gcc-6.4/0055-unwind_h-glibc26.patch b/meta/recipes-devtools/gcc/gcc-6.4/0055-unwind_h-glibc26.patch new file mode 100644 index 0000000000..c266cfe21f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/0055-unwind_h-glibc26.patch @@ -0,0 +1,139 @@ +Backport and edit of patches from: +https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=249957 +by jsm28 (Joseph Myers) + +Current glibc no longer gives the ucontext_t type the tag struct +ucontext, to conform with POSIX namespace rules. This requires +various linux-unwind.h files in libgcc, that were previously using +struct ucontext, to be fixed to use ucontext_t instead. This is +similar to the removal of the struct siginfo tag from siginfo_t some +years ago. + +This patch changes those files to use ucontext_t instead. As the +standard name that should be unconditionally safe, so this is not +restricted to architectures supported by glibc, or conditioned on the +glibc version. + +Upstream-Status: Backport + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- branches/gcc-6-branch/libgcc/config/aarch64/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/aarch64/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -52,7 +52,7 @@ + struct rt_sigframe + { + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + }; + + struct rt_sigframe *rt_; +--- branches/gcc-6-branch/libgcc/config/alpha/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/alpha/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -51,7 +51,7 @@ + { + struct rt_sigframe { + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_ = context->cfa; + sc = &rt_->uc.uc_mcontext; + } +--- branches/gcc-6-branch/libgcc/config/bfin/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/bfin/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -52,7 +52,7 @@ + void *puc; + char retcode[8]; + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_ = context->cfa; + + /* The void * cast is necessary to avoid an aliasing warning. +--- branches/gcc-6-branch/libgcc/config/i386/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/i386/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -58,7 +58,7 @@ + if (*(unsigned char *)(pc+0) == 0x48 + && *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL) + { +- struct ucontext *uc_ = context->cfa; ++ ucontext_t *uc_ = context->cfa; + /* The void * cast is necessary to avoid an aliasing warning. + The aliasing warning is correct, but should not be a problem + because it does not alias anything. */ +@@ -138,7 +138,7 @@ + siginfo_t *pinfo; + void *puc; + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_ = context->cfa; + /* The void * cast is necessary to avoid an aliasing warning. + The aliasing warning is correct, but should not be a problem +--- branches/gcc-6-branch/libgcc/config/m68k/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/m68k/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -33,7 +33,7 @@ + /* <sys/ucontext.h> is unfortunately broken right now. */ + struct uw_ucontext { + unsigned long uc_flags; +- struct ucontext *uc_link; ++ ucontext_t *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + unsigned long uc_filler[80]; +--- branches/gcc-6-branch/libgcc/config/nios2/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/nios2/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -38,7 +38,7 @@ + + struct nios2_ucontext { + unsigned long uc_flags; +- struct ucontext *uc_link; ++ ucontext_t *uc_link; + stack_t uc_stack; + struct nios2_mcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +--- branches/gcc-6-branch/libgcc/config/pa/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/pa/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -80,7 +80,7 @@ + struct sigcontext *sc; + struct rt_sigframe { + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *frame; + + /* rt_sigreturn trampoline: +--- branches/gcc-6-branch/libgcc/config/sh/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/sh/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -180,7 +180,7 @@ + { + struct rt_sigframe { + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_ = context->cfa; + /* The void * cast is necessary to avoid an aliasing warning. + The aliasing warning is correct, but should not be a problem +--- branches/gcc-6-branch/libgcc/config/tilepro/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/tilepro/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -61,7 +61,7 @@ + struct rt_sigframe { + unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_; + + /* Return if this is not a signal handler. */ +--- branches/gcc-6-branch/libgcc/config/xtensa/linux-unwind.h 2017/07/04 10:22:56 249956 +--- b/libgcc/config/xtensa/linux-unwind.h 2017/07/04 10:23:57 249957 +@@ -67,7 +67,7 @@ + + struct rt_sigframe { + siginfo_t info; +- struct ucontext uc; ++ ucontext_t uc; + } *rt_; + + /* movi a2, __NR_rt_sigreturn; syscall */ diff --git a/meta/recipes-devtools/gcc/gcc-6.4/0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch b/meta/recipes-devtools/gcc/gcc-6.4/0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch new file mode 100644 index 0000000000..0214ab83d9 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch @@ -0,0 +1,194 @@ +From ad5bf450aef2ffee6d57ed193fabc5f72f8eaa65 Mon Sep 17 00:00:00 2001 +From: rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Thu, 19 Oct 2017 13:16:42 +0000 +Subject: [PATCH] [ARM] PR 82445 - suppress 32-bit aligned ldrd/strd peepholing + with -mno-unaligned-access + +Peephole patterns exist in the arm backend to spot load/store +operations to adjacent memory operations in order to convert them into +ldrd/strd instructions. However, when we have strict alignment +enforced, then we can only do this if the accesses are known to be +64-bit aligned; this is unlikely to be the case for most loads. The +patch adds some alignment checking to the code that validates the +addresses for use in the peephole patterns. This should also fix +incorrect generation of ldrd/strd with unaligned accesses that could +previously have occurred on ARMv5e where all such operations must be +64-bit aligned. + +I've added some new tests as well. In doing so I discovered that the +ldrd/strd peephole tests could never fail since they would match the +source file name in the scanned assembly as well as any instructions +of the intended type. I've fixed those by tightening the scan results +slightly. + +gcc: + +* config/arm/arm.c (align_ok_ldrd_strd): New function. +(mem_ok_for_ldrd_strd): New parameter align. Extract the alignment of the +mem into it. +(gen_operands_ldrd_strd): Validate the alignment of the accesses. + +testsuite: + +* gcc.target/arm/peep-ldrd-1.c: Tighten test scan pattern. +* gcc.target/arm/peep-strd-1.c: Likewise. +* gcc.target/arm/peep-ldrd-2.c: New test. +* gcc.target/arm/peep-strd-2.c: New test. + + + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@253892 138bc75d-0d04-0410-961f-82ee72b054a4 +--- +Upstream-Status: Backport +Signed-off-by: Khem Raj <raj.khem@gmail.com> + + gcc/ChangeLog | 8 +++++++ + gcc/config/arm/arm.c | 27 ++++++++++++++++++---- + gcc/testsuite/ChangeLog | 8 +++++++ + gcc/testsuite/gcc.target/arm/peep-ldrd-1.c | 2 +- + .../arm/{peep-ldrd-1.c => peep-ldrd-2.c} | 4 ++-- + gcc/testsuite/gcc.target/arm/peep-strd-1.c | 2 +- + .../arm/{peep-strd-1.c => peep-strd-2.c} | 4 ++-- + 7 files changed, 44 insertions(+), 11 deletions(-) + copy gcc/testsuite/gcc.target/arm/{peep-ldrd-1.c => peep-ldrd-2.c} (63%) + copy gcc/testsuite/gcc.target/arm/{peep-strd-1.c => peep-strd-2.c} (58%) + +diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c +index 9c0813d598d..e3da9f77fb6 100644 +--- a/gcc/config/arm/arm.c ++++ b/gcc/config/arm/arm.c +@@ -15926,12 +15926,23 @@ operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset, + return true; + } + ++/* Return true if a 64-bit access with alignment ALIGN and with a ++ constant offset OFFSET from the base pointer is permitted on this ++ architecture. */ ++static bool ++align_ok_ldrd_strd (HOST_WIDE_INT align, HOST_WIDE_INT offset) ++{ ++ return (unaligned_access ++ ? (align >= BITS_PER_WORD && (offset & 3) == 0) ++ : (align >= 2 * BITS_PER_WORD && (offset & 7) == 0)); ++} ++ + /* Helper for gen_operands_ldrd_strd. Returns true iff the memory + operand MEM's address contains an immediate offset from the base +- register and has no side effects, in which case it sets BASE and +- OFFSET accordingly. */ ++ register and has no side effects, in which case it sets BASE, ++ OFFSET and ALIGN accordingly. */ + static bool +-mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset) ++mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset, HOST_WIDE_INT *align) + { + rtx addr; + +@@ -15950,6 +15961,7 @@ mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset) + gcc_assert (MEM_P (mem)); + + *offset = const0_rtx; ++ *align = MEM_ALIGN (mem); + + addr = XEXP (mem, 0); + +@@ -15990,7 +16002,7 @@ gen_operands_ldrd_strd (rtx *operands, bool load, + bool const_store, bool commute) + { + int nops = 2; +- HOST_WIDE_INT offsets[2], offset; ++ HOST_WIDE_INT offsets[2], offset, align[2]; + rtx base = NULL_RTX; + rtx cur_base, cur_offset, tmp; + int i, gap; +@@ -16002,7 +16014,8 @@ gen_operands_ldrd_strd (rtx *operands, bool load, + registers, and the corresponding memory offsets. */ + for (i = 0; i < nops; i++) + { +- if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset)) ++ if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset, ++ &align[i])) + return false; + + if (i == 0) +@@ -16114,6 +16127,7 @@ gen_operands_ldrd_strd (rtx *operands, bool load, + /* Swap the instructions such that lower memory is accessed first. */ + std::swap (operands[0], operands[1]); + std::swap (operands[2], operands[3]); ++ std::swap (align[0], align[1]); + if (const_store) + std::swap (operands[4], operands[5]); + } +@@ -16127,6 +16141,9 @@ gen_operands_ldrd_strd (rtx *operands, bool load, + if (gap != 4) + return false; + ++ if (!align_ok_ldrd_strd (align[0], offset)) ++ return false; ++ + /* Make sure we generate legal instructions. */ + if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, + false, load)) +diff --git a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c b/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c +index eb2b86ee7b6..d49eff6b87e 100644 +--- a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c ++++ b/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c +@@ -8,4 +8,4 @@ int foo(int a, int b, int* p, int *q) + *p = a; + return a; + } +-/* { dg-final { scan-assembler "ldrd" } } */ ++/* { dg-final { scan-assembler "ldrd\\t" } } */ +diff --git a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c b/gcc/testsuite/gcc.target/arm/peep-ldrd-2.c +similarity index 63% +copy from gcc/testsuite/gcc.target/arm/peep-ldrd-1.c +copy to gcc/testsuite/gcc.target/arm/peep-ldrd-2.c +index eb2b86ee7b6..6822c2b1454 100644 +--- a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c ++++ b/gcc/testsuite/gcc.target/arm/peep-ldrd-2.c +@@ -1,6 +1,6 @@ + /* { dg-do compile } */ + /* { dg-require-effective-target arm_prefer_ldrd_strd } */ +-/* { dg-options "-O2" } */ ++/* { dg-options "-O2 -mno-unaligned-access" } */ + int foo(int a, int b, int* p, int *q) + { + a = p[2] + p[3]; +@@ -8,4 +8,4 @@ int foo(int a, int b, int* p, int *q) + *p = a; + return a; + } +-/* { dg-final { scan-assembler "ldrd" } } */ ++/* { dg-final { scan-assembler-not "ldrd\\t" } } */ +diff --git a/gcc/testsuite/gcc.target/arm/peep-strd-1.c b/gcc/testsuite/gcc.target/arm/peep-strd-1.c +index bd330769599..fe1beac7229 100644 +--- a/gcc/testsuite/gcc.target/arm/peep-strd-1.c ++++ b/gcc/testsuite/gcc.target/arm/peep-strd-1.c +@@ -6,4 +6,4 @@ void foo(int a, int b, int* p) + p[2] = a; + p[3] = b; + } +-/* { dg-final { scan-assembler "strd" } } */ ++/* { dg-final { scan-assembler "strd\\t" } } */ +diff --git a/gcc/testsuite/gcc.target/arm/peep-strd-1.c b/gcc/testsuite/gcc.target/arm/peep-strd-2.c +similarity index 58% +copy from gcc/testsuite/gcc.target/arm/peep-strd-1.c +copy to gcc/testsuite/gcc.target/arm/peep-strd-2.c +index bd330769599..bfc5ebe9eec 100644 +--- a/gcc/testsuite/gcc.target/arm/peep-strd-1.c ++++ b/gcc/testsuite/gcc.target/arm/peep-strd-2.c +@@ -1,9 +1,9 @@ + /* { dg-do compile } */ + /* { dg-require-effective-target arm_prefer_ldrd_strd } */ +-/* { dg-options "-O2" } */ ++/* { dg-options "-O2 -mno-unaligned-access" } */ + void foo(int a, int b, int* p) + { + p[2] = a; + p[3] = b; + } +-/* { dg-final { scan-assembler "strd" } } */ ++/* { dg-final { scan-assembler-not "strd\\t" } } */ +-- +2.15.0 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch new file mode 100644 index 0000000000..3f664c5885 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch @@ -0,0 +1,67 @@ +From 22fcc126fad61a8e9ddaaabbc8036644273642dc Mon Sep 17 00:00:00 2001 +From: ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Thu, 9 Nov 2017 14:34:28 +0000 +Subject: [PATCH] enable FL_LPAE flag for armv7ve cores + +The following commit added the FL_LPAE flag to FL_FOR_ARCH7VE, but +neglected to also add it to the armv7ve compatible cores defined in +arm-cores.def. + + https://github.com/gcc-mirror/gcc/commit/af2d9b9e58e8be576c53d94f30c48c68146b0c98 + +The result is that gcc 6.4 now refuses to allow -march=armv7ve and +-mcpu=XXX to be used together, even when -mcpu is set to an armv7ve +compatible core: + + arm-linux-gnueabi-gcc -march=armv7ve -mcpu=cortex-a7 -Werror ... + error: switch -mcpu=cortex-a7 conflicts with -march=armv7ve switch [-Werror] + +Fix by defining flags for armv7ve compatible cores directly from +FL_FOR_ARCH7VE, rather than re-creating the armv7ve flags +independently by combining FL_FOR_ARCH7A with the armv7ve specific +FL_THUMB_DIV and FL_ARM_DIV flags. + +Upstream-Status: Backport + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@254584 138bc75d-0d04-0410-961f-82ee72b054a4 + +Signed-off-by: Andre McCurdy <armccurdy@gmail.com> +--- + gcc/config/arm/arm-cores.def | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def +index 829b839..ca37e6f 100644 +--- a/gcc/config/arm/arm-cores.def ++++ b/gcc/config/arm/arm-cores.def +@@ -145,12 +145,12 @@ ARM_CORE("cortex-m0plus.small-multiply",cortexm0plussmallmultiply, cortexm0plus, + /* V7 Architecture Processors */ + ARM_CORE("generic-armv7-a", genericv7a, genericv7a, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7A), cortex) + ARM_CORE("cortex-a5", cortexa5, cortexa5, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7A), cortex_a5) +-ARM_CORE("cortex-a7", cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a7) ++ARM_CORE("cortex-a7", cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a7) + ARM_CORE("cortex-a8", cortexa8, cortexa8, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7A), cortex_a8) + ARM_CORE("cortex-a9", cortexa9, cortexa9, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7A), cortex_a9) +-ARM_CORE("cortex-a12", cortexa12, cortexa17, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a12) +-ARM_CORE("cortex-a15", cortexa15, cortexa15, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a15) +-ARM_CORE("cortex-a17", cortexa17, cortexa17, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a12) ++ARM_CORE("cortex-a12", cortexa12, cortexa17, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a12) ++ARM_CORE("cortex-a15", cortexa15, cortexa15, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a15) ++ARM_CORE("cortex-a17", cortexa17, cortexa17, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a12) + ARM_CORE("cortex-r4", cortexr4, cortexr4, 7R, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7R), cortex) + ARM_CORE("cortex-r4f", cortexr4f, cortexr4f, 7R, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7R), cortex) + ARM_CORE("cortex-r5", cortexr5, cortexr5, 7R, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_ARM_DIV | FL_FOR_ARCH7R), cortex) +@@ -162,8 +162,8 @@ ARM_CORE("cortex-m3", cortexm3, cortexm3, 7M, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | + ARM_CORE("marvell-pj4", marvell_pj4, marvell_pj4, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7A), marvell_pj4) + + /* V7 big.LITTLE implementations */ +-ARM_CORE("cortex-a15.cortex-a7", cortexa15cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a15) +-ARM_CORE("cortex-a17.cortex-a7", cortexa17cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV | FL_FOR_ARCH7A), cortex_a12) ++ARM_CORE("cortex-a15.cortex-a7", cortexa15cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a15) ++ARM_CORE("cortex-a17.cortex-a7", cortexa17cortexa7, cortexa7, 7A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_FOR_ARCH7VE), cortex_a12) + + /* V8 Architecture Processors */ + ARM_CORE("cortex-a32", cortexa32, cortexa53, 8A, ARM_FSET_MAKE_CPU1 (FL_LDSCHED | FL_CRC32 | FL_FOR_ARCH8A), cortex_a35) +-- +1.9.1 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch new file mode 100644 index 0000000000..00b0ffd156 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch @@ -0,0 +1,247 @@ +From c2c7775c5587dc59b6756162d390d89d60971a16 Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Mon, 15 Jan 2018 11:27:24 +0000 +Subject: [PATCH 01/12] i386: Move struct ix86_frame to machine_function + +Make ix86_frame available to i386 code generation. This is needed to +backport the patch set of -mindirect-branch= to mitigate variant #2 of +the speculative execution vulnerabilities on x86 processors identified +by CVE-2017-5715, aka Spectre. + + Backport from mainline + 2017-06-01 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * config/i386/i386.c (ix86_frame): Moved to ... + * config/i386/i386.h (ix86_frame): Here. + (machine_function): Add frame. + * config/i386/i386.c (ix86_compute_frame_layout): Repace the + frame argument with &cfun->machine->frame. + (ix86_can_use_return_insn_p): Don't pass &frame to + ix86_compute_frame_layout. Copy frame from cfun->machine->frame. + (ix86_can_eliminate): Likewise. + (ix86_expand_prologue): Likewise. + (ix86_expand_epilogue): Likewise. + (ix86_expand_split_stack_prologue): Likewise. + + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 68 ++++++++++---------------------------------------- + gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++- + 2 files changed, 65 insertions(+), 56 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 8b5faac..a1ff32b 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -2434,53 +2434,6 @@ struct GTY(()) stack_local_entry { + struct stack_local_entry *next; + }; + +-/* Structure describing stack frame layout. +- Stack grows downward: +- +- [arguments] +- <- ARG_POINTER +- saved pc +- +- saved static chain if ix86_static_chain_on_stack +- +- saved frame pointer if frame_pointer_needed +- <- HARD_FRAME_POINTER +- [saved regs] +- <- regs_save_offset +- [padding0] +- +- [saved SSE regs] +- <- sse_regs_save_offset +- [padding1] | +- | <- FRAME_POINTER +- [va_arg registers] | +- | +- [frame] | +- | +- [padding2] | = to_allocate +- <- STACK_POINTER +- */ +-struct ix86_frame +-{ +- int nsseregs; +- int nregs; +- int va_arg_size; +- int red_zone_size; +- int outgoing_arguments_size; +- +- /* The offsets relative to ARG_POINTER. */ +- HOST_WIDE_INT frame_pointer_offset; +- HOST_WIDE_INT hard_frame_pointer_offset; +- HOST_WIDE_INT stack_pointer_offset; +- HOST_WIDE_INT hfp_save_offset; +- HOST_WIDE_INT reg_save_offset; +- HOST_WIDE_INT sse_reg_save_offset; +- +- /* When save_regs_using_mov is set, emit prologue using +- move instead of push instructions. */ +- bool save_regs_using_mov; +-}; +- + /* Which cpu are we scheduling for. */ + enum attr_cpu ix86_schedule; + +@@ -2572,7 +2525,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode, + const_tree); + static rtx ix86_static_chain (const_tree, bool); + static int ix86_function_regparm (const_tree, const_tree); +-static void ix86_compute_frame_layout (struct ix86_frame *); ++static void ix86_compute_frame_layout (void); + static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode, + rtx, rtx, int); + static void ix86_add_new_builtins (HOST_WIDE_INT); +@@ -10944,7 +10897,8 @@ ix86_can_use_return_insn_p (void) + if (crtl->args.pops_args && crtl->args.size >= 32768) + return 0; + +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame = cfun->machine->frame; + return (frame.stack_pointer_offset == UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) == 0); + } +@@ -11355,8 +11309,8 @@ ix86_can_eliminate (const int from, const int to) + HOST_WIDE_INT + ix86_initial_elimination_offset (int from, int to) + { +- struct ix86_frame frame; +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ struct ix86_frame frame = cfun->machine->frame; + + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) + return frame.hard_frame_pointer_offset; +@@ -11395,8 +11349,9 @@ ix86_builtin_setjmp_frame_value (void) + /* Fill structure ix86_frame about frame of currently computed function. */ + + static void +-ix86_compute_frame_layout (struct ix86_frame *frame) ++ix86_compute_frame_layout (void) + { ++ struct ix86_frame *frame = &cfun->machine->frame; + unsigned HOST_WIDE_INT stack_alignment_needed; + HOST_WIDE_INT offset; + unsigned HOST_WIDE_INT preferred_alignment; +@@ -12702,7 +12657,8 @@ ix86_expand_prologue (void) + m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET; + m->fs.sp_valid = true; + +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame = m->frame; + + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) + { +@@ -13379,7 +13335,8 @@ ix86_expand_epilogue (int style) + bool using_drap; + + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame = m->frame; + + m->fs.sp_valid = (!frame_pointer_needed + || (crtl->sp_is_unchanging +@@ -13876,7 +13833,8 @@ ix86_expand_split_stack_prologue (void) + gcc_assert (flag_split_stack && reload_completed); + + ix86_finalize_stack_realign_flags (); +- ix86_compute_frame_layout (&frame); ++ ix86_compute_frame_layout (); ++ frame = cfun->machine->frame; + allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; + + /* This is the label we will branch to if we have enough stack +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 8113f83..5414416 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2427,9 +2427,56 @@ enum avx_u128_state + + #define FASTCALL_PREFIX '@' + ++#ifndef USED_FOR_TARGET ++/* Structure describing stack frame layout. ++ Stack grows downward: ++ ++ [arguments] ++ <- ARG_POINTER ++ saved pc ++ ++ saved static chain if ix86_static_chain_on_stack ++ ++ saved frame pointer if frame_pointer_needed ++ <- HARD_FRAME_POINTER ++ [saved regs] ++ <- regs_save_offset ++ [padding0] ++ ++ [saved SSE regs] ++ <- sse_regs_save_offset ++ [padding1] | ++ | <- FRAME_POINTER ++ [va_arg registers] | ++ | ++ [frame] | ++ | ++ [padding2] | = to_allocate ++ <- STACK_POINTER ++ */ ++struct GTY(()) ix86_frame ++{ ++ int nsseregs; ++ int nregs; ++ int va_arg_size; ++ int red_zone_size; ++ int outgoing_arguments_size; ++ ++ /* The offsets relative to ARG_POINTER. */ ++ HOST_WIDE_INT frame_pointer_offset; ++ HOST_WIDE_INT hard_frame_pointer_offset; ++ HOST_WIDE_INT stack_pointer_offset; ++ HOST_WIDE_INT hfp_save_offset; ++ HOST_WIDE_INT reg_save_offset; ++ HOST_WIDE_INT sse_reg_save_offset; ++ ++ /* When save_regs_using_mov is set, emit prologue using ++ move instead of push instructions. */ ++ bool save_regs_using_mov; ++}; ++ + /* Machine specific frame tracking during prologue/epilogue generation. */ + +-#ifndef USED_FOR_TARGET + struct GTY(()) machine_frame_state + { + /* This pair tracks the currently active CFA as reg+offset. When reg +@@ -2475,6 +2522,9 @@ struct GTY(()) machine_function { + int varargs_fpr_size; + int optimize_mode_switching[MAX_386_ENTITIES]; + ++ /* Cached initial frame layout for the current function. */ ++ struct ix86_frame frame; ++ + /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE + has been computed for. */ + int use_fast_prologue_epilogue_nregs; +@@ -2554,6 +2604,7 @@ struct GTY(()) machine_function { + #define ix86_current_function_calls_tls_descriptor \ + (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) + #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) ++#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) + + /* Control behavior of x86_file_start. */ + #define X86_FILE_START_VERSION_DIRECTIVE false +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch new file mode 100644 index 0000000000..df65b08f93 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch @@ -0,0 +1,74 @@ +From fe2b3be3f4b6ec6b3a6f89c26016a3983b7cb351 Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Mon, 15 Jan 2018 11:28:44 +0000 +Subject: [PATCH 02/12] i386: Use reference of struct ix86_frame to avoid copy + +When there is no need to make a copy of ix86_frame, we can use reference +of struct ix86_frame to avoid copy. + + Backport from mainline + 2017-11-06 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference + of struct ix86_frame. + (ix86_initial_elimination_offset): Likewise. + (ix86_expand_split_stack_prologue): Likewise. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index a1ff32b..13ebf10 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -10887,7 +10887,6 @@ symbolic_reference_mentioned_p (rtx op) + bool + ix86_can_use_return_insn_p (void) + { +- struct ix86_frame frame; + + if (! reload_completed || frame_pointer_needed) + return 0; +@@ -10898,7 +10897,7 @@ ix86_can_use_return_insn_p (void) + return 0; + + ix86_compute_frame_layout (); +- frame = cfun->machine->frame; ++ struct ix86_frame &frame = cfun->machine->frame; + return (frame.stack_pointer_offset == UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) == 0); + } +@@ -11310,7 +11309,7 @@ HOST_WIDE_INT + ix86_initial_elimination_offset (int from, int to) + { + ix86_compute_frame_layout (); +- struct ix86_frame frame = cfun->machine->frame; ++ struct ix86_frame &frame = cfun->machine->frame; + + if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) + return frame.hard_frame_pointer_offset; +@@ -13821,7 +13820,6 @@ static GTY(()) rtx split_stack_fn_large; + void + ix86_expand_split_stack_prologue (void) + { +- struct ix86_frame frame; + HOST_WIDE_INT allocate; + unsigned HOST_WIDE_INT args_size; + rtx_code_label *label; +@@ -13834,7 +13832,7 @@ ix86_expand_split_stack_prologue (void) + + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame = cfun->machine->frame; ++ struct ix86_frame &frame = cfun->machine->frame; + allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; + + /* This is the label we will branch to if we have enough stack +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch new file mode 100644 index 0000000000..a5ffd85d6f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch @@ -0,0 +1,131 @@ +From 82243732dc63e9b90396a5ae4ad99ca36af81355 Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Sat, 27 Jan 2018 13:10:24 +0000 +Subject: [PATCH 03/12] i386: Use const reference of struct ix86_frame to avoid + copy + +We can use const reference of struct ix86_frame to avoid making a local +copy of ix86_frame. ix86_expand_epilogue makes a local copy of struct +ix86_frame and uses the reg_save_offset field as a local variable. This +patch uses a separate local variable for reg_save_offset. + +Tested on x86-64 with ada. + + Backport from mainline + PR target/83905 + * config/i386/i386.c (ix86_expand_prologue): Use cost reference + of struct ix86_frame. + (ix86_expand_epilogue): Likewise. Add a local variable for + the reg_save_offset field in struct ix86_frame. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257123 138bc75d-0d04-0410-961f-82ee72b054a4 + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 13ebf10..6c98f75 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -12633,7 +12633,6 @@ ix86_expand_prologue (void) + { + struct machine_function *m = cfun->machine; + rtx insn, t; +- struct ix86_frame frame; + HOST_WIDE_INT allocate; + bool int_registers_saved; + bool sse_registers_saved; +@@ -12657,7 +12656,7 @@ ix86_expand_prologue (void) + m->fs.sp_valid = true; + + ix86_compute_frame_layout (); +- frame = m->frame; ++ const struct ix86_frame &frame = cfun->machine->frame; + + if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) + { +@@ -13329,13 +13328,12 @@ ix86_expand_epilogue (int style) + { + struct machine_function *m = cfun->machine; + struct machine_frame_state frame_state_save = m->fs; +- struct ix86_frame frame; + bool restore_regs_via_mov; + bool using_drap; + + ix86_finalize_stack_realign_flags (); + ix86_compute_frame_layout (); +- frame = m->frame; ++ const struct ix86_frame &frame = cfun->machine->frame; + + m->fs.sp_valid = (!frame_pointer_needed + || (crtl->sp_is_unchanging +@@ -13377,11 +13375,13 @@ ix86_expand_epilogue (int style) + + UNITS_PER_WORD); + } + ++ HOST_WIDE_INT reg_save_offset = frame.reg_save_offset; ++ + /* Special care must be taken for the normal return case of a function + using eh_return: the eax and edx registers are marked as saved, but + not restored along this path. Adjust the save location to match. */ + if (crtl->calls_eh_return && style != 2) +- frame.reg_save_offset -= 2 * UNITS_PER_WORD; ++ reg_save_offset -= 2 * UNITS_PER_WORD; + + /* EH_RETURN requires the use of moves to function properly. */ + if (crtl->calls_eh_return) +@@ -13397,11 +13397,11 @@ ix86_expand_epilogue (int style) + else if (TARGET_EPILOGUE_USING_MOVE + && cfun->machine->use_fast_prologue_epilogue + && (frame.nregs > 1 +- || m->fs.sp_offset != frame.reg_save_offset)) ++ || m->fs.sp_offset != reg_save_offset)) + restore_regs_via_mov = true; + else if (frame_pointer_needed + && !frame.nregs +- && m->fs.sp_offset != frame.reg_save_offset) ++ && m->fs.sp_offset != reg_save_offset) + restore_regs_via_mov = true; + else if (frame_pointer_needed + && TARGET_USE_LEAVE +@@ -13439,7 +13439,7 @@ ix86_expand_epilogue (int style) + rtx t; + + if (frame.nregs) +- ix86_emit_restore_regs_using_mov (frame.reg_save_offset, style == 2); ++ ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2); + + /* eh_return epilogues need %ecx added to the stack pointer. */ + if (style == 2) +@@ -13529,19 +13529,19 @@ ix86_expand_epilogue (int style) + epilogues. */ + if (!m->fs.sp_valid + || (TARGET_SEH +- && (m->fs.sp_offset - frame.reg_save_offset ++ && (m->fs.sp_offset - reg_save_offset + >= SEH_MAX_FRAME_SIZE))) + { + pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, + GEN_INT (m->fs.fp_offset +- - frame.reg_save_offset), ++ - reg_save_offset), + style, false); + } +- else if (m->fs.sp_offset != frame.reg_save_offset) ++ else if (m->fs.sp_offset != reg_save_offset) + { + pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (m->fs.sp_offset +- - frame.reg_save_offset), ++ - reg_save_offset), + style, + m->fs.cfa_reg == stack_pointer_rtx); + } +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch new file mode 100644 index 0000000000..a9d6e5ff2d --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch @@ -0,0 +1,2154 @@ +From 6140c2c0bb2b61e69d0da84315e0433ff3520aaa Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Sat, 6 Jan 2018 22:29:55 -0800 +Subject: [PATCH 04/12] x86: Add -mindirect-branch= + +Add -mindirect-branch= option to convert indirect call and jump to call +and return thunks. The default is 'keep', which keeps indirect call and +jump unmodified. 'thunk' converts indirect call and jump to call and +return thunk. 'thunk-inline' converts indirect call and jump to inlined +call and return thunk. 'thunk-extern' converts indirect call and jump to +external call and return thunk provided in a separate object file. You +can control this behavior for a specific function by using the function +attribute indirect_branch. + +2 kinds of thunks are geneated. Memory thunk where the function address +is at the top of the stack: + +__x86_indirect_thunk: + call L2 +L1: + pause + lfence + jmp L1 +L2: + lea 8(%rsp), %rsp|lea 4(%esp), %esp + ret + +Indirect jmp via memory, "jmp mem", is converted to + + push memory + jmp __x86_indirect_thunk + +Indirect call via memory, "call mem", is converted to + + jmp L2 +L1: + push [mem] + jmp __x86_indirect_thunk +L2: + call L1 + +Register thunk where the function address is in a register, reg: + +__x86_indirect_thunk_reg: + call L2 +L1: + pause + lfence + jmp L1 +L2: + movq %reg, (%rsp)|movl %reg, (%esp) + ret + +where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di, +(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15. + +Indirect jmp via register, "jmp reg", is converted to + + jmp __x86_indirect_thunk_reg + +Indirect call via register, "call reg", is converted to + + call __x86_indirect_thunk_reg + +gcc/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386-opts.h (indirect_branch): New. + * config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise. + * config/i386/i386.c (ix86_using_red_zone): Disallow red-zone + with local indirect jump when converting indirect call and jump. + (ix86_set_indirect_branch_type): New. + (ix86_set_current_function): Call ix86_set_indirect_branch_type. + (indirectlabelno): New. + (indirect_thunk_needed): Likewise. + (indirect_thunk_bnd_needed): Likewise. + (indirect_thunks_used): Likewise. + (indirect_thunks_bnd_used): Likewise. + (INDIRECT_LABEL): Likewise. + (indirect_thunk_name): Likewise. + (output_indirect_thunk): Likewise. + (output_indirect_thunk_function): Likewise. + (ix86_output_indirect_branch_via_reg): Likewise. + (ix86_output_indirect_branch_via_push): Likewise. + (ix86_output_indirect_branch): Likewise. + (ix86_output_indirect_jmp): Likewise. + (ix86_code_end): Call output_indirect_thunk_function if needed. + (ix86_output_call_insn): Call ix86_output_indirect_branch if + needed. + (ix86_handle_fndecl_attribute): Handle indirect_branch. + (ix86_attribute_table): Add indirect_branch. + * config/i386/i386.h (machine_function): Add indirect_branch_type + and has_local_indirect_jump. + * config/i386/i386.md (indirect_jump): Set has_local_indirect_jump + to true. + (tablejump): Likewise. + (*indirect_jump): Use ix86_output_indirect_jmp. + (*tablejump_1): Likewise. + (simple_return_indirect_internal): Likewise. + * config/i386/i386.opt (mindirect-branch=): New option. + (indirect_branch): New. + (keep): Likewise. + (thunk): Likewise. + (thunk-inline): Likewise. + (thunk-extern): Likewise. + * doc/extend.texi: Document indirect_branch function attribute. + * doc/invoke.texi: Document -mindirect-branch= option. + +gcc/testsuite/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/indirect-thunk-1.c: New test. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386-opts.h | 13 + + gcc/config/i386/i386-protos.h | 1 + + gcc/config/i386/i386.c | 639 ++++++++++++++++++++- + gcc/config/i386/i386.h | 7 + + gcc/config/i386/i386.md | 26 +- + gcc/config/i386/i386.opt | 20 + + gcc/doc/extend.texi | 10 + + gcc/doc/invoke.texi | 13 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 20 + + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 20 + + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 21 + + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 21 + + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 17 + + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 18 + + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 44 ++ + .../gcc.target/i386/indirect-thunk-attr-1.c | 23 + + .../gcc.target/i386/indirect-thunk-attr-2.c | 21 + + .../gcc.target/i386/indirect-thunk-attr-3.c | 23 + + .../gcc.target/i386/indirect-thunk-attr-4.c | 22 + + .../gcc.target/i386/indirect-thunk-attr-5.c | 22 + + .../gcc.target/i386/indirect-thunk-attr-6.c | 21 + + .../gcc.target/i386/indirect-thunk-attr-7.c | 44 ++ + .../gcc.target/i386/indirect-thunk-attr-8.c | 42 ++ + .../gcc.target/i386/indirect-thunk-bnd-1.c | 20 + + .../gcc.target/i386/indirect-thunk-bnd-2.c | 21 + + .../gcc.target/i386/indirect-thunk-bnd-3.c | 19 + + .../gcc.target/i386/indirect-thunk-bnd-4.c | 20 + + .../gcc.target/i386/indirect-thunk-extern-1.c | 19 + + .../gcc.target/i386/indirect-thunk-extern-2.c | 19 + + .../gcc.target/i386/indirect-thunk-extern-3.c | 20 + + .../gcc.target/i386/indirect-thunk-extern-4.c | 20 + + .../gcc.target/i386/indirect-thunk-extern-5.c | 16 + + .../gcc.target/i386/indirect-thunk-extern-6.c | 17 + + .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++ + .../gcc.target/i386/indirect-thunk-inline-1.c | 20 + + .../gcc.target/i386/indirect-thunk-inline-2.c | 20 + + .../gcc.target/i386/indirect-thunk-inline-3.c | 21 + + .../gcc.target/i386/indirect-thunk-inline-4.c | 21 + + .../gcc.target/i386/indirect-thunk-inline-5.c | 17 + + .../gcc.target/i386/indirect-thunk-inline-6.c | 18 + + .../gcc.target/i386/indirect-thunk-inline-7.c | 44 ++ + 41 files changed, 1486 insertions(+), 17 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c + +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h +index b7f92e3..cc21152 100644 +--- a/gcc/config/i386/i386-opts.h ++++ b/gcc/config/i386/i386-opts.h +@@ -99,4 +99,17 @@ enum stack_protector_guard { + SSP_GLOBAL /* global canary */ + }; + ++/* This is used to mitigate variant #2 of the speculative execution ++ vulnerabilities on x86 processors identified by CVE-2017-5715, aka ++ Spectre. They convert indirect branches and function returns to ++ call and return thunks to avoid speculative execution via indirect ++ call, jmp and ret. */ ++enum indirect_branch { ++ indirect_branch_unset = 0, ++ indirect_branch_keep, ++ indirect_branch_thunk, ++ indirect_branch_thunk_inline, ++ indirect_branch_thunk_extern ++}; ++ + #endif +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h +index ff47bc1..eca4cbf 100644 +--- a/gcc/config/i386/i386-protos.h ++++ b/gcc/config/i386/i386-protos.h +@@ -311,6 +311,7 @@ extern enum attr_cpu ix86_schedule; + #endif + + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); ++extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, + enum machine_mode mode); + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 6c98f75..0b9fc4d 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -3662,12 +3662,23 @@ make_pass_stv (gcc::context *ctxt) + return new pass_stv (ctxt); + } + +-/* Return true if a red-zone is in use. */ ++/* Return true if a red-zone is in use. We can't use red-zone when ++ there are local indirect jumps, like "indirect_jump" or "tablejump", ++ which jumps to another place in the function, since "call" in the ++ indirect thunk pushes the return address onto stack, destroying ++ red-zone. ++ ++ TODO: If we can reserve the first 2 WORDs, for PUSH and, another ++ for CALL, in red-zone, we can allow local indirect jumps with ++ indirect thunk. */ + + bool + ix86_using_red_zone (void) + { +- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI; ++ return (TARGET_RED_ZONE ++ && !TARGET_64BIT_MS_ABI ++ && (!cfun->machine->has_local_indirect_jump ++ || cfun->machine->indirect_branch_type == indirect_branch_keep)); + } + + /* Return a string that documents the current -m options. The caller is +@@ -6350,6 +6361,37 @@ ix86_reset_previous_fndecl (void) + ix86_previous_fndecl = NULL_TREE; + } + ++/* Set the indirect_branch_type field from the function FNDECL. */ ++ ++static void ++ix86_set_indirect_branch_type (tree fndecl) ++{ ++ if (cfun->machine->indirect_branch_type == indirect_branch_unset) ++ { ++ tree attr = lookup_attribute ("indirect_branch", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr != NULL) ++ { ++ tree args = TREE_VALUE (attr); ++ if (args == NULL) ++ gcc_unreachable (); ++ tree cst = TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) ++ cfun->machine->indirect_branch_type = indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) ++ cfun->machine->indirect_branch_type = indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) ++ cfun->machine->indirect_branch_type = indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->indirect_branch_type = ix86_indirect_branch; ++ } ++} ++ + /* Establish appropriate back-end context for processing the function + FNDECL. The argument might be NULL to indicate processing at top + level, outside of any function scope. */ +@@ -6360,7 +6402,13 @@ ix86_set_current_function (tree fndecl) + several times in the course of compiling a function, and we don't want to + slow things down too much or call target_reinit when it isn't safe. */ + if (fndecl == ix86_previous_fndecl) +- return; ++ { ++ /* There may be 2 function bodies for the same function FNDECL, ++ one is extern inline and one isn't. */ ++ if (fndecl != NULL_TREE) ++ ix86_set_indirect_branch_type (fndecl); ++ return; ++ } + + tree old_tree; + if (ix86_previous_fndecl == NULL_TREE) +@@ -6377,6 +6425,8 @@ ix86_set_current_function (tree fndecl) + return; + } + ++ ix86_set_indirect_branch_type (fndecl); ++ + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree == NULL_TREE) + new_tree = target_option_default_node; +@@ -10962,6 +11012,220 @@ ix86_setup_frame_addresses (void) + # endif + #endif + ++/* Label count for call and return thunks. It is used to make unique ++ labels in call and return thunks. */ ++static int indirectlabelno; ++ ++/* True if call and return thunk functions are needed. */ ++static bool indirect_thunk_needed = false; ++/* True if call and return thunk functions with the BND prefix are ++ needed. */ ++static bool indirect_thunk_bnd_needed = false; ++ ++/* Bit masks of integer registers, which contain branch target, used ++ by call and return thunks functions. */ ++static int indirect_thunks_used; ++/* Bit masks of integer registers, which contain branch target, used ++ by call and return thunks functions with the BND prefix. */ ++static int indirect_thunks_bnd_used; ++ ++#ifndef INDIRECT_LABEL ++# define INDIRECT_LABEL "LIND" ++#endif ++ ++/* Fills in the label name that should be used for the indirect thunk. */ ++ ++static void ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p) ++{ ++ if (USE_HIDDEN_LINKONCE) ++ { ++ const char *bnd = need_bnd_p ? "_bnd" : ""; ++ if (regno >= 0) ++ { ++ const char *reg_prefix; ++ if (LEGACY_INT_REGNO_P (regno)) ++ reg_prefix = TARGET_64BIT ? "r" : "e"; ++ else ++ reg_prefix = ""; ++ sprintf (name, "__x86_indirect_thunk%s_%s%s", ++ bnd, reg_prefix, reg_names[regno]); ++ } ++ else ++ sprintf (name, "__x86_indirect_thunk%s", bnd); ++ } ++ else ++ { ++ if (regno >= 0) ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno); ++ } ++ else ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); ++ } ++ } ++} ++ ++/* Output a call and return thunk for indirect branch. If BND_P is ++ true, the BND prefix is needed. If REGNO != -1, the function ++ address is in REGNO and the call and return thunk looks like: ++ ++ call L2 ++ L1: ++ pause ++ jmp L1 ++ L2: ++ mov %REG, (%sp) ++ ret ++ ++ Otherwise, the function address is on the top of stack and the ++ call and return thunk looks like: ++ ++ call L2 ++ L1: ++ pause ++ jmp L1 ++ L2: ++ lea WORD_SIZE(%sp), %sp ++ ret ++ */ ++ ++static void ++output_indirect_thunk (bool need_bnd_p, int regno) ++{ ++ char indirectlabel1[32]; ++ char indirectlabel2[32]; ++ ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL, ++ indirectlabelno++); ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL, ++ indirectlabelno++); ++ ++ /* Call */ ++ if (need_bnd_p) ++ fputs ("\tbnd call\t", asm_out_file); ++ else ++ fputs ("\tcall\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel2); ++ fputc ('\n', asm_out_file); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); ++ ++ /* Pause + lfence. */ ++ fprintf (asm_out_file, "\tpause\n\tlfence\n"); ++ ++ /* Jump. */ ++ fputs ("\tjmp\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel1); ++ fputc ('\n', asm_out_file); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); ++ ++ if (regno >= 0) ++ { ++ /* MOV. */ ++ rtx xops[2]; ++ xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx); ++ xops[1] = gen_rtx_REG (word_mode, regno); ++ output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); ++ } ++ else ++ { ++ /* LEA. */ ++ rtx xops[2]; ++ xops[0] = stack_pointer_rtx; ++ xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); ++ output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); ++ } ++ ++ if (need_bnd_p) ++ fputs ("\tbnd ret\n", asm_out_file); ++ else ++ fputs ("\tret\n", asm_out_file); ++} ++ ++/* Output a funtion with a call and return thunk for indirect branch. ++ If BND_P is true, the BND prefix is needed. If REGNO != -1, the ++ function address is in REGNO. Otherwise, the function address is ++ on the top of stack. */ ++ ++static void ++output_indirect_thunk_function (bool need_bnd_p, int regno) ++{ ++ char name[32]; ++ tree decl; ++ ++ /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ ++ indirect_thunk_name (name, regno, need_bnd_p); ++ decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, ++ get_identifier (name), ++ build_function_type_list (void_type_node, NULL_TREE)); ++ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, ++ NULL_TREE, void_type_node); ++ TREE_PUBLIC (decl) = 1; ++ TREE_STATIC (decl) = 1; ++ DECL_IGNORED_P (decl) = 1; ++ ++#if TARGET_MACHO ++ if (TARGET_MACHO) ++ { ++ switch_to_section (darwin_sections[picbase_thunk_section]); ++ fputs ("\t.weak_definition\t", asm_out_file); ++ assemble_name (asm_out_file, name); ++ fputs ("\n\t.private_extern\t", asm_out_file); ++ assemble_name (asm_out_file, name); ++ putc ('\n', asm_out_file); ++ ASM_OUTPUT_LABEL (asm_out_file, name); ++ DECL_WEAK (decl) = 1; ++ } ++ else ++#endif ++ if (USE_HIDDEN_LINKONCE) ++ { ++ cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl)); ++ ++ targetm.asm_out.unique_section (decl, 0); ++ switch_to_section (get_named_section (decl, NULL, 0)); ++ ++ targetm.asm_out.globalize_label (asm_out_file, name); ++ fputs ("\t.hidden\t", asm_out_file); ++ assemble_name (asm_out_file, name); ++ putc ('\n', asm_out_file); ++ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl); ++ } ++ else ++ { ++ switch_to_section (text_section); ++ ASM_OUTPUT_LABEL (asm_out_file, name); ++ } ++ ++ DECL_INITIAL (decl) = make_node (BLOCK); ++ current_function_decl = decl; ++ allocate_struct_function (decl, false); ++ init_function_start (decl); ++ /* We're about to hide the function body from callees of final_* by ++ emitting it directly; tell them we're a thunk, if they care. */ ++ cfun->is_thunk = true; ++ first_function_block_is_cold = false; ++ /* Make sure unwind info is emitted for the thunk if needed. */ ++ final_start_function (emit_barrier (), asm_out_file, 1); ++ ++ output_indirect_thunk (need_bnd_p, regno); ++ ++ final_end_function (); ++ init_insn_lengths (); ++ free_after_compilation (cfun); ++ set_cfun (NULL); ++ current_function_decl = NULL; ++} ++ + static int pic_labels_used; + + /* Fills in the label name that should be used for a pc thunk for +@@ -10988,11 +11252,32 @@ ix86_code_end (void) + rtx xops[2]; + int regno; + ++ if (indirect_thunk_needed) ++ output_indirect_thunk_function (false, -1); ++ if (indirect_thunk_bnd_needed) ++ output_indirect_thunk_function (true, -1); ++ ++ for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) ++ { ++ int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; ++ if ((indirect_thunks_used & (1 << i))) ++ output_indirect_thunk_function (false, regno); ++ ++ if ((indirect_thunks_bnd_used & (1 << i))) ++ output_indirect_thunk_function (true, regno); ++ } ++ + for (regno = AX_REG; regno <= SP_REG; regno++) + { + char name[32]; + tree decl; + ++ if ((indirect_thunks_used & (1 << regno))) ++ output_indirect_thunk_function (false, regno); ++ ++ if ((indirect_thunks_bnd_used & (1 << regno))) ++ output_indirect_thunk_function (true, regno); ++ + if (!(pic_labels_used & (1 << regno))) + continue; + +@@ -27369,12 +27654,292 @@ ix86_nopic_noplt_attribute_p (rtx call_op) + return false; + } + ++/* Output indirect branch via a call and return thunk. CALL_OP is a ++ register which contains the branch target. XASM is the assembly ++ template for CALL_OP. Branch is a tail call if SIBCALL_P is true. ++ A normal call is converted to: ++ ++ call __x86_indirect_thunk_reg ++ ++ and a tail call is converted to: ++ ++ jmp __x86_indirect_thunk_reg ++ */ ++ ++static void ++ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) ++{ ++ char thunk_name_buf[32]; ++ char *thunk_name; ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno = REGNO (call_op); ++ ++ if (cfun->machine->indirect_branch_type ++ != indirect_branch_thunk_inline) ++ { ++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk) ++ { ++ int i = regno; ++ if (i >= FIRST_REX_INT_REG) ++ i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1); ++ if (need_bnd_p) ++ indirect_thunks_bnd_used |= 1 << i; ++ else ++ indirect_thunks_used |= 1 << i; ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ thunk_name = thunk_name_buf; ++ } ++ else ++ thunk_name = NULL; ++ ++ if (sibcall_p) ++ { ++ if (thunk_name != NULL) ++ { ++ if (need_bnd_p) ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ else ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ else ++ output_indirect_thunk (need_bnd_p, regno); ++ } ++ else ++ { ++ if (thunk_name != NULL) ++ { ++ if (need_bnd_p) ++ fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name); ++ else ++ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name); ++ return; ++ } ++ ++ char indirectlabel1[32]; ++ char indirectlabel2[32]; ++ ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, ++ INDIRECT_LABEL, ++ indirectlabelno++); ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, ++ INDIRECT_LABEL, ++ indirectlabelno++); ++ ++ /* Jump. */ ++ if (need_bnd_p) ++ fputs ("\tbnd jmp\t", asm_out_file); ++ else ++ fputs ("\tjmp\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel2); ++ fputc ('\n', asm_out_file); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); ++ ++ if (thunk_name != NULL) ++ { ++ if (need_bnd_p) ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ else ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ else ++ output_indirect_thunk (need_bnd_p, regno); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); ++ ++ /* Call. */ ++ if (need_bnd_p) ++ fputs ("\tbnd call\t", asm_out_file); ++ else ++ fputs ("\tcall\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel1); ++ fputc ('\n', asm_out_file); ++ } ++} ++ ++/* Output indirect branch via a call and return thunk. CALL_OP is ++ the branch target. XASM is the assembly template for CALL_OP. ++ Branch is a tail call if SIBCALL_P is true. A normal call is ++ converted to: ++ ++ jmp L2 ++ L1: ++ push CALL_OP ++ jmp __x86_indirect_thunk ++ L2: ++ call L1 ++ ++ and a tail call is converted to: ++ ++ push CALL_OP ++ jmp __x86_indirect_thunk ++ */ ++ ++static void ++ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, ++ bool sibcall_p) ++{ ++ char thunk_name_buf[32]; ++ char *thunk_name; ++ char push_buf[64]; ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); ++ int regno = -1; ++ ++ if (cfun->machine->indirect_branch_type ++ != indirect_branch_thunk_inline) ++ { ++ if (cfun->machine->indirect_branch_type == indirect_branch_thunk) ++ { ++ if (need_bnd_p) ++ indirect_thunk_bnd_needed = true; ++ else ++ indirect_thunk_needed = true; ++ } ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ thunk_name = thunk_name_buf; ++ } ++ else ++ thunk_name = NULL; ++ ++ snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s", ++ TARGET_64BIT ? 'q' : 'l', xasm); ++ ++ if (sibcall_p) ++ { ++ output_asm_insn (push_buf, &call_op); ++ if (thunk_name != NULL) ++ { ++ if (need_bnd_p) ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ else ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ else ++ output_indirect_thunk (need_bnd_p, regno); ++ } ++ else ++ { ++ char indirectlabel1[32]; ++ char indirectlabel2[32]; ++ ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, ++ INDIRECT_LABEL, ++ indirectlabelno++); ++ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, ++ INDIRECT_LABEL, ++ indirectlabelno++); ++ ++ /* Jump. */ ++ if (need_bnd_p) ++ fputs ("\tbnd jmp\t", asm_out_file); ++ else ++ fputs ("\tjmp\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel2); ++ fputc ('\n', asm_out_file); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); ++ ++ /* An external function may be called via GOT, instead of PLT. */ ++ if (MEM_P (call_op)) ++ { ++ struct ix86_address parts; ++ rtx addr = XEXP (call_op, 0); ++ if (ix86_decompose_address (addr, &parts) ++ && parts.base == stack_pointer_rtx) ++ { ++ /* Since call will adjust stack by -UNITS_PER_WORD, ++ we must convert "disp(stack, index, scale)" to ++ "disp+UNITS_PER_WORD(stack, index, scale)". */ ++ if (parts.index) ++ { ++ addr = gen_rtx_MULT (Pmode, parts.index, ++ GEN_INT (parts.scale)); ++ addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, ++ addr); ++ } ++ else ++ addr = stack_pointer_rtx; ++ ++ rtx disp; ++ if (parts.disp != NULL_RTX) ++ disp = plus_constant (Pmode, parts.disp, ++ UNITS_PER_WORD); ++ else ++ disp = GEN_INT (UNITS_PER_WORD); ++ ++ addr = gen_rtx_PLUS (Pmode, addr, disp); ++ call_op = gen_rtx_MEM (GET_MODE (call_op), addr); ++ } ++ } ++ ++ output_asm_insn (push_buf, &call_op); ++ ++ if (thunk_name != NULL) ++ { ++ if (need_bnd_p) ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ else ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ else ++ output_indirect_thunk (need_bnd_p, regno); ++ ++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); ++ ++ /* Call. */ ++ if (need_bnd_p) ++ fputs ("\tbnd call\t", asm_out_file); ++ else ++ fputs ("\tcall\t", asm_out_file); ++ assemble_name_raw (asm_out_file, indirectlabel1); ++ fputc ('\n', asm_out_file); ++ } ++} ++ ++/* Output indirect branch via a call and return thunk. CALL_OP is ++ the branch target. XASM is the assembly template for CALL_OP. ++ Branch is a tail call if SIBCALL_P is true. */ ++ ++static void ++ix86_output_indirect_branch (rtx call_op, const char *xasm, ++ bool sibcall_p) ++{ ++ if (REG_P (call_op)) ++ ix86_output_indirect_branch_via_reg (call_op, sibcall_p); ++ else ++ ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); ++} ++/* Output indirect jump. CALL_OP is the jump target. Jump is a ++ function return if RET_P is true. */ ++ ++const char * ++ix86_output_indirect_jmp (rtx call_op, bool ret_p) ++{ ++ if (cfun->machine->indirect_branch_type != indirect_branch_keep) ++ { ++ /* We can't have red-zone if this isn't a function return since ++ "call" in the indirect thunk pushes the return address onto ++ stack, destroying red-zone. */ ++ if (!ret_p && ix86_red_zone_size != 0) ++ gcc_unreachable (); ++ ++ ix86_output_indirect_branch (call_op, "%0", true); ++ return ""; ++ } ++ else ++ return "%!jmp\t%A0"; ++} ++ + /* Output the assembly for a call instruction. */ + + const char * + ix86_output_call_insn (rtx_insn *insn, rtx call_op) + { + bool direct_p = constant_call_address_operand (call_op, VOIDmode); ++ bool output_indirect_p ++ = (!TARGET_SEH ++ && cfun->machine->indirect_branch_type != indirect_branch_keep); + bool seh_nop_p = false; + const char *xasm; + +@@ -27383,7 +27948,13 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) + if (direct_p) + { + if (ix86_nopic_noplt_attribute_p (call_op)) +- xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ { ++ direct_p = false; ++ if (output_indirect_p) ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ } + else + xasm = "%!jmp\t%P0"; + } +@@ -27392,9 +27963,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) + else if (TARGET_SEH) + xasm = "%!rex.W jmp\t%A0"; + else +- xasm = "%!jmp\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm = "%0"; ++ else ++ xasm = "%!jmp\t%A0"; ++ } + +- output_asm_insn (xasm, &call_op); ++ if (output_indirect_p && !direct_p) ++ ix86_output_indirect_branch (call_op, xasm, true); ++ else ++ output_asm_insn (xasm, &call_op); + return ""; + } + +@@ -27431,14 +28010,28 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) + if (direct_p) + { + if (ix86_nopic_noplt_attribute_p (call_op)) +- xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ { ++ direct_p = false; ++ if (output_indirect_p) ++ xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ else ++ xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; ++ } + else + xasm = "%!call\t%P0"; + } + else +- xasm = "%!call\t%A0"; ++ { ++ if (output_indirect_p) ++ xasm = "%0"; ++ else ++ xasm = "%!call\t%A0"; ++ } + +- output_asm_insn (xasm, &call_op); ++ if (output_indirect_p && !direct_p) ++ ix86_output_indirect_branch (call_op, xasm, false); ++ else ++ output_asm_insn (xasm, &call_op); + + if (seh_nop_p) + return "nop"; +@@ -44836,7 +45429,7 @@ ix86_handle_struct_attribute (tree *node, tree name, tree, int, + } + + static tree +-ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, ++ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, + bool *no_add_attrs) + { + if (TREE_CODE (*node) != FUNCTION_DECL) +@@ -44845,6 +45438,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, + name); + *no_add_attrs = true; + } ++ ++ if (is_attribute_p ("indirect_branch", name)) ++ { ++ tree cst = TREE_VALUE (args); ++ if (TREE_CODE (cst) != STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs = true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs = true; ++ } ++ } ++ + return NULL_TREE; + } + +@@ -49072,6 +49688,9 @@ static const struct attribute_spec ix86_attribute_table[] = + false }, + { "callee_pop_aggregate_return", 1, 1, false, true, true, + ix86_handle_callee_pop_aggregate_return, true }, ++ { "indirect_branch", 1, 1, true, false, false, ++ ix86_handle_fndecl_attribute, false }, ++ + /* End element. */ + { NULL, 0, 0, false, false, false, NULL, false } + }; +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 5414416..9dccdb0 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2572,6 +2572,13 @@ struct GTY(()) machine_function { + /* If true, it is safe to not save/restore DRAP register. */ + BOOL_BITFIELD no_drap_save_restore : 1; + ++ /* How to generate indirec branch. */ ++ ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; ++ ++ /* If true, the current function has local indirect jumps, like ++ "indirect_jump" or "tablejump". */ ++ BOOL_BITFIELD has_local_indirect_jump : 1; ++ + /* If true, there is register available for argument passing. This + is used only in ix86_function_ok_for_sibcall by 32-bit to determine + if there is scratch register available for indirect sibcall. In +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index d2bfe31..153e162 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11807,13 +11807,18 @@ + { + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump = true; + }) + + (define_insn "*indirect_jump" + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] + "" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], false);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ != indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) + +@@ -11856,14 +11861,19 @@ + + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); ++ cfun->machine->has_local_indirect_jump = true; + }) + + (define_insn "*tablejump_1" + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) + (use (label_ref (match_operand 1)))] + "" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], false);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ != indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) + +@@ -12520,8 +12530,12 @@ + [(simple_return) + (use (match_operand:SI 0 "register_operand" "r"))] + "reload_completed" +- "%!jmp\t%A0" +- [(set_attr "type" "ibr") ++ "* return ix86_output_indirect_jmp (operands[0], true);" ++ [(set (attr "type") ++ (if_then_else (match_test "(cfun->machine->indirect_branch_type ++ != indirect_branch_keep)") ++ (const_string "multi") ++ (const_string "ibr"))) + (set_attr "length_immediate" "0") + (set_attr "maybe_prefix_bnd" "1")]) + +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index f304b62..5ffa334 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -897,3 +897,23 @@ Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL) + mmitigate-rop + Target Var(flag_mitigate_rop) Init(0) + Attempt to avoid generating instruction sequences containing ret bytes. ++ ++mindirect-branch= ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) ++Convert indirect call and jump to call and return thunks. ++ ++Enum ++Name(indirect_branch) Type(enum indirect_branch) ++Known indirect branch choices (for use with the -mindirect-branch= option): ++ ++EnumValue ++Enum(indirect_branch) String(keep) Value(indirect_branch_keep) ++ ++EnumValue ++Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) ++ ++EnumValue ++Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 8cc4f7e..8668dae 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -5419,6 +5419,16 @@ Specify which floating-point unit to use. You must specify the + @code{target("fpmath=sse,387")} option as + @code{target("fpmath=sse+387")} because the comma would separate + different options. ++ ++@item indirect_branch("@var{choice}") ++@cindex @code{indirect_branch} function attribute, x86 ++On x86 targets, the @code{indirect_branch} attribute causes the compiler ++to convert indirect call and jump with @var{choice}. @samp{keep} ++keeps indirect call and jump unmodified. @samp{thunk} converts indirect ++call and jump to call and return thunk. @samp{thunk-inline} converts ++indirect call and jump to inlined call and return thunk. ++@samp{thunk-extern} converts indirect call and jump to external call ++and return thunk provided in a separate object file. + @end table + + On the x86, the inliner does not inline a +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index b066f7b..ff9a194 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1169,7 +1169,7 @@ See RS/6000 and PowerPC Options. + -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol + -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol +--mmitigate-rop} ++-mmitigate-rop -mindirect-branch=@var{choice}} + + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -24218,6 +24218,17 @@ opcodes, to mitigate against certain forms of attack. At the moment, + this option is limited in what it can do and should not be relied + on to provide serious protection. + ++@item -mindirect-branch=@var{choice} ++@opindex -mindirect-branch ++Convert indirect call and jump with @var{choice}. The default is ++@samp{keep}, which keeps indirect call and jump unmodified. ++@samp{thunk} converts indirect call and jump to call and return thunk. ++@samp{thunk-inline} converts indirect call and jump to inlined call ++and return thunk. @samp{thunk-extern} converts indirect call and jump ++to external call and return thunk provided in a separate object file. ++You can control this behavior for a specific function by using the ++function attribute @code{indirect_branch}. @xref{Function Attributes}. ++ + @end table + + These @samp{-m} switches are supported in addition to the above +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +new file mode 100644 +index 0000000..d983e1c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +new file mode 100644 +index 0000000..58f09b4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +new file mode 100644 +index 0000000..f20d35c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +new file mode 100644 +index 0000000..0eff8fb +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +new file mode 100644 +index 0000000..a25b20d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ ++ ++extern void bar (void); ++ ++void ++foo (void) ++{ ++ bar (); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +new file mode 100644 +index 0000000..cff114a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ ++ ++extern void bar (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +new file mode 100644 +index 0000000..afdb600 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++void func0 (void); ++void func1 (void); ++void func2 (void); ++void func3 (void); ++void func4 (void); ++void func4 (void); ++void func5 (void); ++ ++void ++bar (int i) ++{ ++ switch (i) ++ { ++ default: ++ func0 (); ++ break; ++ case 1: ++ func1 (); ++ break; ++ case 2: ++ func2 (); ++ break; ++ case 3: ++ func3 (); ++ break; ++ case 4: ++ func4 (); ++ break; ++ case 5: ++ func5 (); ++ break; ++ } ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +new file mode 100644 +index 0000000..d64d978 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++extern void male_indirect_jump (long) ++ __attribute__ ((indirect_branch("thunk"))); ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +new file mode 100644 +index 0000000..9306745 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++__attribute__ ((indirect_branch("thunk"))) ++void ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +new file mode 100644 +index 0000000..97744d6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++extern int male_indirect_jump (long) ++ __attribute__ ((indirect_branch("thunk-inline"))); ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +new file mode 100644 +index 0000000..bfce3ea +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++__attribute__ ((indirect_branch("thunk-inline"))) ++int ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +new file mode 100644 +index 0000000..0833606 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++extern int male_indirect_jump (long) ++ __attribute__ ((indirect_branch("thunk-extern"))); ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +new file mode 100644 +index 0000000..2eba0fb +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++__attribute__ ((indirect_branch("thunk-extern"))) ++int ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +new file mode 100644 +index 0000000..f58427e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fno-pic" } */ ++ ++void func0 (void); ++void func1 (void); ++void func2 (void); ++void func3 (void); ++void func4 (void); ++void func4 (void); ++void func5 (void); ++ ++__attribute__ ((indirect_branch("thunk-extern"))) ++void ++bar (int i) ++{ ++ switch (i) ++ { ++ default: ++ func0 (); ++ break; ++ case 1: ++ func1 (); ++ break; ++ case 2: ++ func2 (); ++ break; ++ case 3: ++ func3 (); ++ break; ++ case 4: ++ func4 (); ++ break; ++ case 5: ++ func5 (); ++ break; ++ } ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c +new file mode 100644 +index 0000000..564ed39 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c +@@ -0,0 +1,42 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++ ++void func0 (void); ++void func1 (void); ++void func2 (void); ++void func3 (void); ++void func4 (void); ++void func4 (void); ++void func5 (void); ++ ++__attribute__ ((indirect_branch("keep"))) ++void ++bar (int i) ++{ ++ switch (i) ++ { ++ default: ++ func0 (); ++ break; ++ case 1: ++ func1 (); ++ break; ++ case 2: ++ func2 (); ++ break; ++ case 3: ++ func3 (); ++ break; ++ case 4: ++ func4 (); ++ break; ++ case 5: ++ func5 (); ++ break; ++ } ++} ++ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +new file mode 100644 +index 0000000..50fbee2 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile { target { ! x32 } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++ ++void (*dispatch) (char *); ++char buf[10]; ++ ++void ++foo (void) ++{ ++ dispatch (buf); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd ret" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +new file mode 100644 +index 0000000..2976e67 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile { target { ! x32 } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++ ++void (*dispatch) (char *); ++char buf[10]; ++ ++int ++foo (void) ++{ ++ dispatch (buf); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd ret" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +new file mode 100644 +index 0000000..da4bc98 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++ ++void bar (char *); ++char buf[10]; ++ ++void ++foo (void) ++{ ++ bar (buf); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "bnd ret" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +new file mode 100644 +index 0000000..c64d12e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++ ++void bar (char *); ++char buf[10]; ++ ++int ++foo (void) ++{ ++ bar (buf); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler "bnd ret" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +new file mode 100644 +index 0000000..49f27b4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +new file mode 100644 +index 0000000..a1e3eb6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +new file mode 100644 +index 0000000..395634e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +new file mode 100644 +index 0000000..fd3f633 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +new file mode 100644 +index 0000000..ba2f92b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +@@ -0,0 +1,16 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++ ++extern void bar (void); ++ ++void ++foo (void) ++{ ++ bar (); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +new file mode 100644 +index 0000000..0c5a2d4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++ ++extern void bar (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +new file mode 100644 +index 0000000..6652523 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +@@ -0,0 +1,43 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++void func0 (void); ++void func1 (void); ++void func2 (void); ++void func3 (void); ++void func4 (void); ++void func4 (void); ++void func5 (void); ++ ++void ++bar (int i) ++{ ++ switch (i) ++ { ++ default: ++ func0 (); ++ break; ++ case 1: ++ func1 (); ++ break; ++ case 2: ++ func2 (); ++ break; ++ case 3: ++ func3 (); ++ break; ++ case 4: ++ func4 (); ++ break; ++ case 5: ++ func5 (); ++ break; ++ } ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +new file mode 100644 +index 0000000..68c0ff7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +new file mode 100644 +index 0000000..e2da1fc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +new file mode 100644 +index 0000000..244fec7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +new file mode 100644 +index 0000000..107ebe3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch[256]; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch[offset](offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +new file mode 100644 +index 0000000..17b04ef +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++ ++extern void bar (void); ++ ++void ++foo (void) ++{ ++ bar (); ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +new file mode 100644 +index 0000000..d9eb112 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target *-*-linux* } } */ ++/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++ ++extern void bar (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +new file mode 100644 +index 0000000..d02b1dc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +@@ -0,0 +1,44 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++void func0 (void); ++void func1 (void); ++void func2 (void); ++void func3 (void); ++void func4 (void); ++void func4 (void); ++void func5 (void); ++ ++void ++bar (int i) ++{ ++ switch (i) ++ { ++ default: ++ func0 (); ++ break; ++ case 1: ++ func1 (); ++ break; ++ case 2: ++ func2 (); ++ break; ++ case 3: ++ func3 (); ++ break; ++ case 4: ++ func4 (); ++ break; ++ case 5: ++ func5 (); ++ break; ++ } ++} ++ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch new file mode 100644 index 0000000000..5354c77d6f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch @@ -0,0 +1,1570 @@ +From e3270814b9e0caad63fbcdfd7ae9da2d52c97497 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 05/12] x86: Add -mfunction-return= + +Add -mfunction-return= option to convert function return to call and +return thunks. The default is 'keep', which keeps function return +unmodified. 'thunk' converts function return to call and return thunk. +'thunk-inline' converts function return to inlined call and return thunk. +'thunk-extern' converts function return to external call and return +thunk provided in a separate object file. You can control this behavior +for a specific function by using the function attribute function_return. + +Function return thunk is the same as memory thunk for -mindirect-branch= +where the return address is at the top of the stack: + +__x86_return_thunk: + call L2 +L1: + pause + lfence + jmp L1 +L2: + lea 8(%rsp), %rsp|lea 4(%esp), %esp + ret + +and function return becomes + + jmp __x86_return_thunk + +-mindirect-branch= tests are updated with -mfunction-return=keep to +avoid false test failures when -mfunction-return=thunk is added to +RUNTESTFLAGS for "make check". + +gcc/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386-protos.h (ix86_output_function_return): New. + * config/i386/i386.c (ix86_set_indirect_branch_type): Also + set function_return_type. + (indirect_thunk_name): Add ret_p to indicate thunk for function + return. + (output_indirect_thunk_function): Pass false to + indirect_thunk_name. + (ix86_output_indirect_branch_via_reg): Likewise. + (ix86_output_indirect_branch_via_push): Likewise. + (output_indirect_thunk_function): Create alias for function + return thunk if regno < 0. + (ix86_output_function_return): New function. + (ix86_handle_fndecl_attribute): Handle function_return. + (ix86_attribute_table): Add function_return. + * config/i386/i386.h (machine_function): Add + function_return_type. + * config/i386/i386.md (simple_return_internal): Use + ix86_output_function_return. + (simple_return_internal_long): Likewise. + * config/i386/i386.opt (mfunction-return=): New option. + (indirect_branch): Mention -mfunction-return=. + * doc/extend.texi: Document function_return function attribute. + * doc/invoke.texi: Document -mfunction-return= option. + +gcc/testsuite/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/indirect-thunk-1.c (dg-options): Add + -mfunction-return=keep. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-1.c: New test. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + * gcc.target/i386/ret-thunk-16.c: Likewise. + * gcc.target/i386/ret-thunk-2.c: Likewise. + * gcc.target/i386/ret-thunk-3.c: Likewise. + * gcc.target/i386/ret-thunk-4.c: Likewise. + * gcc.target/i386/ret-thunk-5.c: Likewise. + * gcc.target/i386/ret-thunk-6.c: Likewise. + * gcc.target/i386/ret-thunk-7.c: Likewise. + * gcc.target/i386/ret-thunk-8.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. + +i386: Don't use ASM_OUTPUT_DEF for TARGET_MACHO + +ASM_OUTPUT_DEF isn't defined for TARGET_MACHO. Use ASM_OUTPUT_LABEL to +generate the __x86_return_thunk label, instead of the set directive. +Update testcase to remove the __x86_return_thunk label check. Since +-fno-pic is ignored on Darwin, update testcases to sscan or "push" +only on Linux. + +gcc/ + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + PR target/83839 + * config/i386/i386.c (output_indirect_thunk_function): Use + ASM_OUTPUT_LABEL, instead of ASM_OUTPUT_DEF, for TARGET_MACHO + for __x86.return_thunk. + +gcc/testsuite/ + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + PR target/83839 + * gcc.target/i386/indirect-thunk-1.c: Scan for "push" only on + Linux. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-register-1.c: Likewise. + * gcc.target/i386/indirect-thunk-register-3.c: Likewise. + * gcc.target/i386/indirect-thunk-register-4.c: Likewise. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Don't check the + __x86_return_thunk label. + Scan for "push" only for Linux. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386-protos.h | 1 + + gcc/config/i386/i386.c | 152 +++++++++++++++++++-- + gcc/config/i386/i386.h | 3 + + gcc/config/i386/i386.md | 9 +- + gcc/config/i386/i386.opt | 6 +- + gcc/doc/extend.texi | 9 ++ + gcc/doc/invoke.texi | 14 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-3.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-4.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-5.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-6.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-7.c | 4 +- + .../gcc.target/i386/indirect-thunk-attr-8.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-1.c | 4 +- + .../gcc.target/i386/indirect-thunk-bnd-2.c | 4 +- + .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +- + .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +- + .../gcc.target/i386/indirect-thunk-extern-3.c | 4 +- + .../gcc.target/i386/indirect-thunk-extern-4.c | 4 +- + .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +- + .../gcc.target/i386/indirect-thunk-inline-1.c | 4 +- + .../gcc.target/i386/indirect-thunk-inline-2.c | 4 +- + .../gcc.target/i386/indirect-thunk-inline-3.c | 4 +- + .../gcc.target/i386/indirect-thunk-inline-4.c | 4 +- + .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-7.c | 4 +- + gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 13 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 23 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 23 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 22 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +++ + gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 13 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 15 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 14 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 ++ + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 24 ++++ + 56 files changed, 516 insertions(+), 74 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c + +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h +index eca4cbf..620d70e 100644 +--- a/gcc/config/i386/i386-protos.h ++++ b/gcc/config/i386/i386-protos.h +@@ -312,6 +312,7 @@ extern enum attr_cpu ix86_schedule; + + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); + extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); ++extern const char * ix86_output_function_return (bool long_p); + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, + enum machine_mode mode); + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 0b9fc4d..34e26a3 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -6390,6 +6390,31 @@ ix86_set_indirect_branch_type (tree fndecl) + else + cfun->machine->indirect_branch_type = ix86_indirect_branch; + } ++ ++ if (cfun->machine->function_return_type == indirect_branch_unset) ++ { ++ tree attr = lookup_attribute ("function_return", ++ DECL_ATTRIBUTES (fndecl)); ++ if (attr != NULL) ++ { ++ tree args = TREE_VALUE (attr); ++ if (args == NULL) ++ gcc_unreachable (); ++ tree cst = TREE_VALUE (args); ++ if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) ++ cfun->machine->function_return_type = indirect_branch_keep; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) ++ cfun->machine->function_return_type = indirect_branch_thunk; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) ++ cfun->machine->function_return_type = indirect_branch_thunk_inline; ++ else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) ++ cfun->machine->function_return_type = indirect_branch_thunk_extern; ++ else ++ gcc_unreachable (); ++ } ++ else ++ cfun->machine->function_return_type = ix86_function_return; ++ } + } + + /* Establish appropriate back-end context for processing the function +@@ -11036,8 +11061,12 @@ static int indirect_thunks_bnd_used; + /* Fills in the label name that should be used for the indirect thunk. */ + + static void +-indirect_thunk_name (char name[32], int regno, bool need_bnd_p) ++indirect_thunk_name (char name[32], int regno, bool need_bnd_p, ++ bool ret_p) + { ++ if (regno >= 0 && ret_p) ++ gcc_unreachable (); ++ + if (USE_HIDDEN_LINKONCE) + { + const char *bnd = need_bnd_p ? "_bnd" : ""; +@@ -11052,7 +11081,10 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) + bnd, reg_prefix, reg_names[regno]); + } + else +- sprintf (name, "__x86_indirect_thunk%s", bnd); ++ { ++ const char *ret = ret_p ? "return" : "indirect"; ++ sprintf (name, "__x86_%s_thunk%s", ret, bnd); ++ } + } + else + { +@@ -11065,10 +11097,20 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) + } + else + { +- if (need_bnd_p) +- ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); ++ if (ret_p) ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0); ++ } + else +- ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); ++ { ++ if (need_bnd_p) ++ ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); ++ else ++ ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); ++ } + } + } + } +@@ -11163,7 +11205,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) + tree decl; + + /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ +- indirect_thunk_name (name, regno, need_bnd_p); ++ indirect_thunk_name (name, regno, need_bnd_p, false); + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, + get_identifier (name), + build_function_type_list (void_type_node, NULL_TREE)); +@@ -11206,6 +11248,36 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) + ASM_OUTPUT_LABEL (asm_out_file, name); + } + ++ if (regno < 0) ++ { ++ /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ ++ char alias[32]; ++ ++ indirect_thunk_name (alias, regno, need_bnd_p, true); ++#if TARGET_MACHO ++ if (TARGET_MACHO) ++ { ++ fputs ("\t.weak_definition\t", asm_out_file); ++ assemble_name (asm_out_file, alias); ++ fputs ("\n\t.private_extern\t", asm_out_file); ++ assemble_name (asm_out_file, alias); ++ putc ('\n', asm_out_file); ++ ASM_OUTPUT_LABEL (asm_out_file, alias); ++ } ++#else ++ ASM_OUTPUT_DEF (asm_out_file, alias, name); ++ if (USE_HIDDEN_LINKONCE) ++ { ++ fputs ("\t.globl\t", asm_out_file); ++ assemble_name (asm_out_file, alias); ++ putc ('\n', asm_out_file); ++ fputs ("\t.hidden\t", asm_out_file); ++ assemble_name (asm_out_file, alias); ++ putc ('\n', asm_out_file); ++ } ++#endif ++ } ++ + DECL_INITIAL (decl) = make_node (BLOCK); + current_function_decl = decl; + allocate_struct_function (decl, false); +@@ -27687,7 +27759,7 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) + else + indirect_thunks_used |= 1 << i; + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name = thunk_name_buf; + } + else +@@ -27796,7 +27868,7 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, + else + indirect_thunk_needed = true; + } +- indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); ++ indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); + thunk_name = thunk_name_buf; + } + else +@@ -27931,6 +28003,46 @@ ix86_output_indirect_jmp (rtx call_op, bool ret_p) + return "%!jmp\t%A0"; + } + ++/* Output function return. CALL_OP is the jump target. Add a REP ++ prefix to RET if LONG_P is true and function return is kept. */ ++ ++const char * ++ix86_output_function_return (bool long_p) ++{ ++ if (cfun->machine->function_return_type != indirect_branch_keep) ++ { ++ char thunk_name[32]; ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); ++ ++ if (cfun->machine->function_return_type ++ != indirect_branch_thunk_inline) ++ { ++ bool need_thunk = (cfun->machine->function_return_type ++ == indirect_branch_thunk); ++ indirect_thunk_name (thunk_name, -1, need_bnd_p, true); ++ if (need_bnd_p) ++ { ++ indirect_thunk_bnd_needed |= need_thunk; ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ } ++ else ++ { ++ indirect_thunk_needed |= need_thunk; ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ } ++ else ++ output_indirect_thunk (need_bnd_p, -1); ++ ++ return ""; ++ } ++ ++ if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn)) ++ return "%!ret"; ++ ++ return "rep%; ret"; ++} ++ + /* Output the assembly for a call instruction. */ + + const char * +@@ -45461,6 +45573,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, + } + } + ++ if (is_attribute_p ("function_return", name)) ++ { ++ tree cst = TREE_VALUE (args); ++ if (TREE_CODE (cst) != STRING_CST) ++ { ++ warning (OPT_Wattributes, ++ "%qE attribute requires a string constant argument", ++ name); ++ *no_add_attrs = true; ++ } ++ else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 ++ && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) ++ { ++ warning (OPT_Wattributes, ++ "argument to %qE attribute is not " ++ "(keep|thunk|thunk-inline|thunk-extern)", name); ++ *no_add_attrs = true; ++ } ++ } ++ + return NULL_TREE; + } + +@@ -49690,6 +49824,8 @@ static const struct attribute_spec ix86_attribute_table[] = + ix86_handle_callee_pop_aggregate_return, true }, + { "indirect_branch", 1, 1, true, false, false, + ix86_handle_fndecl_attribute, false }, ++ { "function_return", 1, 1, true, false, false, ++ ix86_handle_fndecl_attribute, false }, + + /* End element. */ + { NULL, 0, 0, false, false, false, NULL, false } +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index 9dccdb0..b34bc11 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2579,6 +2579,9 @@ struct GTY(()) machine_function { + "indirect_jump" or "tablejump". */ + BOOL_BITFIELD has_local_indirect_jump : 1; + ++ /* How to generate function return. */ ++ ENUM_BITFIELD(indirect_branch) function_return_type : 3; ++ + /* If true, there is register available for argument passing. This + is used only in ix86_function_ok_for_sibcall by 32-bit to determine + if there is scratch register available for indirect sibcall. In +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index 153e162..2da671e 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -12489,7 +12489,7 @@ + (define_insn "simple_return_internal" + [(simple_return)] + "reload_completed" +- "%!ret" ++ "* return ix86_output_function_return (false);" + [(set_attr "length" "1") + (set_attr "atom_unit" "jeu") + (set_attr "length_immediate" "0") +@@ -12503,12 +12503,7 @@ + [(simple_return) + (unspec [(const_int 0)] UNSPEC_REP)] + "reload_completed" +-{ +- if (ix86_bnd_prefixed_insn_p (insn)) +- return "%!ret"; +- +- return "rep%; ret"; +-} ++ "* return ix86_output_function_return (true);" + [(set_attr "length" "2") + (set_attr "atom_unit" "jeu") + (set_attr "length_immediate" "0") +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 5ffa334..ad5916f 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -902,9 +902,13 @@ mindirect-branch= + Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) + Convert indirect call and jump to call and return thunks. + ++mfunction-return= ++Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep) ++Convert function return to call and return thunk. ++ + Enum + Name(indirect_branch) Type(enum indirect_branch) +-Known indirect branch choices (for use with the -mindirect-branch= option): ++Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options): + + EnumValue + Enum(indirect_branch) String(keep) Value(indirect_branch_keep) +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 8668dae..2cb6bd1 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -5429,6 +5429,15 @@ call and jump to call and return thunk. @samp{thunk-inline} converts + indirect call and jump to inlined call and return thunk. + @samp{thunk-extern} converts indirect call and jump to external call + and return thunk provided in a separate object file. ++ ++@item function_return("@var{choice}") ++@cindex @code{function_return} function attribute, x86 ++On x86 targets, the @code{function_return} attribute causes the compiler ++to convert function return with @var{choice}. @samp{keep} keeps function ++return unmodified. @samp{thunk} converts function return to call and ++return thunk. @samp{thunk-inline} converts function return to inlined ++call and return thunk. @samp{thunk-extern} converts function return to ++external call and return thunk provided in a separate object file. + @end table + + On the x86, the inliner does not inline a +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index ff9a194..fa63dc5 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1169,7 +1169,8 @@ See RS/6000 and PowerPC Options. + -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol + -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol +--mmitigate-rop -mindirect-branch=@var{choice}} ++-mmitigate-rop -mindirect-branch=@var{choice} @gol ++-mfunction-return=@var{choice}} + + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -24229,6 +24230,17 @@ to external call and return thunk provided in a separate object file. + You can control this behavior for a specific function by using the + function attribute @code{indirect_branch}. @xref{Function Attributes}. + ++@item -mfunction-return=@var{choice} ++@opindex -mfunction-return ++Convert function return with @var{choice}. The default is @samp{keep}, ++which keeps function return unmodified. @samp{thunk} converts function ++return to call and return thunk. @samp{thunk-inline} converts function ++return to inlined call and return thunk. @samp{thunk-extern} converts ++function return to external call and return thunk provided in a separate ++object file. You can control this behavior for a specific function by ++using the function attribute @code{function_return}. ++@xref{Function Attributes}. ++ + @end table + + These @samp{-m} switches are supported in addition to the above +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +index d983e1c..e365ef5 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +index 58f09b4..05a51ad 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +index f20d35c..3c0d4c3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +index 0eff8fb..14d4ef6 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +index a25b20d..b4836c3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +index cff114a..1f06bd1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +index afdb600..bc6b47a 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + void func0 (void); + void func1 (void); +@@ -35,7 +35,7 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +index d64d978..2257be3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +index 9306745..e9cfdc5 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +index 97744d6..f938db0 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +index bfce3ea..4e58599 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +index 0833606..b8d5024 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -14,7 +14,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +index 2eba0fb..455adab 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -13,7 +13,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +index f58427e..4595b84 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ + + void func0 (void); + void func1 (void); +@@ -36,7 +36,7 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c +index 564ed39..d730d31 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +index 50fbee2..5e3e118 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { ! x32 } } } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ + + void (*dispatch) (char *); + char buf[10]; +@@ -10,7 +10,7 @@ foo (void) + dispatch (buf); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +index 2976e67..2801aa4 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { ! x32 } } } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ + + void (*dispatch) (char *); + char buf[10]; +@@ -11,7 +11,7 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ + /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +index da4bc98..70b4fb3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ + + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +index c64d12e..3baf03e 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ +-/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ + + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +index 49f27b4..edeb264 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +index a1e3eb6..1d00413 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +index 395634e..06ebf1c 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +index fd3f633..1c8f944 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +index ba2f92b..21740ac 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +index 0c5a2d4..a77c1f4 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +index 6652523..86e9fd1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + void func0 (void); + void func1 (void); +@@ -35,7 +35,7 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +index 68c0ff7..3ecde87 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +index e2da1fc..df32a19 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +index 244fec7..9540996 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +index 107ebe3..f3db6e2 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +index 17b04ef..0f687c3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +index d9eb112..b27c6fc 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +index d02b1dc..764a375 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + void func0 (void); + void func1 (void); +@@ -35,7 +35,7 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c +new file mode 100644 +index 0000000..7223f67 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +new file mode 100644 +index 0000000..3a6727b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 2 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +new file mode 100644 +index 0000000..b8f6818 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +new file mode 100644 +index 0000000..01b0a02 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +new file mode 100644 +index 0000000..4b497b5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++ ++extern void (*bar) (void); ++extern int foo (void) __attribute__ ((function_return("thunk"))); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 2 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +new file mode 100644 +index 0000000..4ae4c44 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++__attribute__ ((function_return("thunk-inline"))) ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +new file mode 100644 +index 0000000..5b5bc76 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk"))) ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c +new file mode 100644 +index 0000000..a16cad1 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++__attribute__ ((function_return("keep"), indirect_branch("keep"))) ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c +new file mode 100644 +index 0000000..c6659e3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c +new file mode 100644 +index 0000000..0f7f388 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c +new file mode 100644 +index 0000000..9ae37e8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep" } */ ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c +new file mode 100644 +index 0000000..4bd0d2a +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep" } */ ++ ++extern void foo (void) __attribute__ ((function_return("thunk"))); ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c +new file mode 100644 +index 0000000..053841f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep" } */ ++ ++__attribute__ ((function_return("thunk-inline"))) ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c +new file mode 100644 +index 0000000..262e678 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=keep" } */ ++ ++__attribute__ ((function_return("thunk-extern"))) ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c +new file mode 100644 +index 0000000..c1658e9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ ++ ++extern void foo (void) __attribute__ ((function_return("keep"))); ++ ++void ++foo (void) ++{ ++} ++ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +new file mode 100644 +index 0000000..fa24a1f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +@@ -0,0 +1,24 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ ++ ++extern void (*bar) (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ ++/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch new file mode 100644 index 0000000000..ad736913cd --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch @@ -0,0 +1,946 @@ +From 3f1c39fb543884d36e759a6dc196a8e914eb4f73 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 06/12] x86: Add -mindirect-branch-register + +Add -mindirect-branch-register to force indirect branch via register. +This is implemented by disabling patterns of indirect branch via memory, +similar to TARGET_X32. + +-mindirect-branch= and -mfunction-return= tests are updated with +-mno-indirect-branch-register to avoid false test failures when +-mindirect-branch-register is added to RUNTESTFLAGS for "make check". + +gcc/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/constraints.md (Bs): Disallow memory operand for + -mindirect-branch-register. + (Bw): Likewise. + * config/i386/predicates.md (indirect_branch_operand): Likewise. + (GOT_memory_operand): Likewise. + (call_insn_operand): Likewise. + (sibcall_insn_operand): Likewise. + (GOT32_symbol_operand): Likewise. + * config/i386/i386.md (indirect_jump): Call convert_memory_address + for -mindirect-branch-register. + (tablejump): Likewise. + (*sibcall_memory): Likewise. + (*sibcall_value_memory): Likewise. + Disallow peepholes of indirect call and jump via memory for + -mindirect-branch-register. + (*call_pop): Replace m with Bw. + (*call_value_pop): Likewise. + (*sibcall_pop_memory): Replace m with Bs. + * config/i386/i386.opt (mindirect-branch-register): New option. + * doc/invoke.texi: Document -mindirect-branch-register option. + +gcc/testsuite/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/indirect-thunk-1.c (dg-options): Add + -mno-indirect-branch-register. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. + * gcc.target/i386/indirect-thunk-register-1.c: New test. + * gcc.target/i386/indirect-thunk-register-2.c: Likewise. + * gcc.target/i386/indirect-thunk-register-3.c: Likewise. + +i386: Rename to ix86_indirect_branch_register + +Rename the variable for -mindirect-branch-register to +ix86_indirect_branch_register to match the command-line option name. + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/constraints.md (Bs): Replace + ix86_indirect_branch_thunk_register with + ix86_indirect_branch_register. + (Bw): Likewise. + * config/i386/i386.md (indirect_jump): Likewise. + (tablejump): Likewise. + (*sibcall_memory): Likewise. + (*sibcall_value_memory): Likewise. + Peepholes of indirect call and jump via memory: Likewise. + * config/i386/i386.opt: Likewise. + * config/i386/predicates.md (indirect_branch_operand): Likewise. + (GOT_memory_operand): Likewise. + (call_insn_operand): Likewise. + (sibcall_insn_operand): Likewise. + (GOT32_symbol_operand): Likewise. + +x86: Rewrite ix86_indirect_branch_register logic + +Rewrite ix86_indirect_branch_register logic with + +(and (not (match_test "ix86_indirect_branch_register")) + (original condition before r256662)) + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/predicates.md (constant_call_address_operand): + Rewrite ix86_indirect_branch_register logic. + (sibcall_insn_operand): Likewise. + +Don't check ix86_indirect_branch_register for GOT operand + +Since GOT_memory_operand and GOT32_symbol_operand are simple pattern +matches, don't check ix86_indirect_branch_register here. If needed, +-mindirect-branch= will convert indirect branch via GOT slot to a call +and return thunk. + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/constraints.md (Bs): Update + ix86_indirect_branch_register check. Don't check + ix86_indirect_branch_register with GOT_memory_operand. + (Bw): Likewise. + * config/i386/predicates.md (GOT_memory_operand): Don't check + ix86_indirect_branch_register here. + (GOT32_symbol_operand): Likewise. + +i386: Rewrite indirect_branch_operand logic + + Backport from mainline + 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/predicates.md (indirect_branch_operand): Rewrite + ix86_indirect_branch_register logic. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/constraints.md | 6 ++-- + gcc/config/i386/i386.md | 34 ++++++++++++++-------- + gcc/config/i386/i386.opt | 4 +++ + gcc/config/i386/predicates.md | 21 +++++++------ + gcc/doc/invoke.texi | 6 +++- + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- + .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++ + .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++ + .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +- + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +- + 47 files changed, 147 insertions(+), 63 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c + +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md +index 1a4c701..9204c8e 100644 +--- a/gcc/config/i386/constraints.md ++++ b/gcc/config/i386/constraints.md +@@ -172,14 +172,16 @@ + + (define_constraint "Bs" + "@internal Sibcall memory operand." +- (ior (and (not (match_test "TARGET_X32")) ++ (ior (and (not (match_test "ix86_indirect_branch_register")) ++ (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand")))) + + (define_constraint "Bw" + "@internal Call memory operand." +- (ior (and (not (match_test "TARGET_X32")) ++ (ior (and (not (match_test "ix86_indirect_branch_register")) ++ (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") + (match_operand 0 "GOT_memory_operand")))) +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index 2da671e..05a88ff 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11805,7 +11805,7 @@ + [(set (pc) (match_operand 0 "indirect_branch_operand"))] + "" + { +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_register) + operands[0] = convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump = true; + }) +@@ -11859,7 +11859,7 @@ + OPTAB_DIRECT); + } + +- if (TARGET_X32) ++ if (TARGET_X32 || ix86_indirect_branch_register) + operands[0] = convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump = true; + }) +@@ -12048,7 +12048,7 @@ + [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) + (match_operand 1)) + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] +- "!TARGET_X32" ++ "!TARGET_X32 && !ix86_indirect_branch_register" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +@@ -12057,7 +12057,9 @@ + (match_operand:W 1 "memory_operand")) + (call (mem:QI (match_dup 0)) + (match_operand 3))] +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) ++ "!TARGET_X32 ++ && !ix86_indirect_branch_register ++ && SIBLING_CALL_P (peep2_next_insn (1)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" + [(parallel [(call (mem:QI (match_dup 1)) +@@ -12070,7 +12072,9 @@ + (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) + (call (mem:QI (match_dup 0)) + (match_operand 3))] +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) ++ "!TARGET_X32 ++ && !ix86_indirect_branch_register ++ && SIBLING_CALL_P (peep2_next_insn (2)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) +@@ -12092,7 +12096,7 @@ + }) + + (define_insn "*call_pop" +- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz")) ++ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) + (match_operand 1)) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) +@@ -12112,7 +12116,7 @@ + [(set_attr "type" "call")]) + + (define_insn "*sibcall_pop_memory" +- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m")) ++ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) + (match_operand 1)) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) +@@ -12166,7 +12170,9 @@ + [(set (match_operand:W 0 "register_operand") + (match_operand:W 1 "memory_operand")) + (set (pc) (match_dup 0))] +- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])" ++ "!TARGET_X32 ++ && !ix86_indirect_branch_register ++ && peep2_reg_dead_p (2, operands[0])" + [(set (pc) (match_dup 1))]) + + ;; Call subroutine, returning value in operand 0 +@@ -12244,7 +12250,7 @@ + (call (mem:QI (match_operand:W 1 "memory_operand" "m")) + (match_operand 2))) + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] +- "!TARGET_X32" ++ "!TARGET_X32 && !ix86_indirect_branch_register" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) + +@@ -12254,7 +12260,9 @@ + (set (match_operand 2) + (call (mem:QI (match_dup 0)) + (match_operand 3)))] +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) ++ "!TARGET_X32 ++ && !ix86_indirect_branch_register ++ && SIBLING_CALL_P (peep2_next_insn (1)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" + [(parallel [(set (match_dup 2) +@@ -12269,7 +12277,9 @@ + (set (match_operand 2) + (call (mem:QI (match_dup 0)) + (match_operand 3)))] +- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) ++ "!TARGET_X32 ++ && !ix86_indirect_branch_register ++ && SIBLING_CALL_P (peep2_next_insn (2)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" + [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) +@@ -12294,7 +12304,7 @@ + + (define_insn "*call_value_pop" + [(set (match_operand 0) +- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz")) ++ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) + (match_operand 2))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index ad5916f..a97f84f 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -921,3 +921,7 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) + + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) ++ ++mindirect-branch-register ++Target Report Var(ix86_indirect_branch_register) Init(0) ++Force indirect call and jump via register. +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md +index 93dda7b..d1f0a7d 100644 +--- a/gcc/config/i386/predicates.md ++++ b/gcc/config/i386/predicates.md +@@ -593,7 +593,8 @@ + ;; Test for a valid operand for indirect branch. + (define_predicate "indirect_branch_operand" + (ior (match_operand 0 "register_operand") +- (and (not (match_test "TARGET_X32")) ++ (and (not (match_test "ix86_indirect_branch_register")) ++ (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")))) + + ;; Return true if OP is a memory operands that can be used in sibcalls. +@@ -636,20 +637,22 @@ + (ior (match_test "constant_call_address_operand + (op, mode == VOIDmode ? mode : Pmode)") + (match_operand 0 "call_register_no_elim_operand") +- (ior (and (not (match_test "TARGET_X32")) +- (match_operand 0 "memory_operand")) +- (and (match_test "TARGET_X32 && Pmode == DImode") +- (match_operand 0 "GOT_memory_operand"))))) ++ (and (not (match_test "ix86_indirect_branch_register")) ++ (ior (and (not (match_test "TARGET_X32")) ++ (match_operand 0 "memory_operand")) ++ (and (match_test "TARGET_X32 && Pmode == DImode") ++ (match_operand 0 "GOT_memory_operand")))))) + + ;; Similarly, but for tail calls, in which we cannot allow memory references. + (define_special_predicate "sibcall_insn_operand" + (ior (match_test "constant_call_address_operand + (op, mode == VOIDmode ? mode : Pmode)") + (match_operand 0 "register_no_elim_operand") +- (ior (and (not (match_test "TARGET_X32")) +- (match_operand 0 "sibcall_memory_operand")) +- (and (match_test "TARGET_X32 && Pmode == DImode") +- (match_operand 0 "GOT_memory_operand"))))) ++ (and (not (match_test "ix86_indirect_branch_register")) ++ (ior (and (not (match_test "TARGET_X32")) ++ (match_operand 0 "sibcall_memory_operand")) ++ (and (match_test "TARGET_X32 && Pmode == DImode") ++ (match_operand 0 "GOT_memory_operand")))))) + + ;; Return true if OP is a 32-bit GOT symbol operand. + (define_predicate "GOT32_symbol_operand" +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index fa63dc5..ad9f295 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1170,7 +1170,7 @@ See RS/6000 and PowerPC Options. + -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol + -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol + -mmitigate-rop -mindirect-branch=@var{choice} @gol +--mfunction-return=@var{choice}} ++-mfunction-return=@var{choice} -mindirect-branch-register} + + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -24241,6 +24241,10 @@ object file. You can control this behavior for a specific function by + using the function attribute @code{function_return}. + @xref{Function Attributes}. + ++@item -mindirect-branch-register ++@opindex -mindirect-branch-register ++Force indirect call and jump via register. ++ + @end table + + These @samp{-m} switches are supported in addition to the above +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +index e365ef5..60d0988 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +index 05a51ad..aac7516 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +index 3c0d4c3..9e24a38 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +index 14d4ef6..127b5d9 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +index b4836c3..fcaa18d 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +index 1f06bd1..e464928 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +index bc6b47a..17c2d0f 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +index 2257be3..9194ccf 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +index e9cfdc5..e51f261 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +index f938db0..4aeec18 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +index 4e58599..ac0e599 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +index b8d5024..573cf1e 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +index 455adab..b2b37fc 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +index 4595b84..4a43e19 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ + + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +index 5e3e118..ac84ab6 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { ! x32 } } } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ + + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +index 2801aa4..ce655e8 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { ! x32 } } } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ + + void (*dispatch) (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +index 70b4fb3..d34485a 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ + + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +index 3baf03e..0e19830 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ + + void bar (char *); + char buf[10]; +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +index edeb264..579441f 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +index 1d00413..c92e6f2 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +index 06ebf1c..d9964c2 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +index 1c8f944..d4dca4d 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +index 21740ac..5c07e02 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +index a77c1f4..3eb4406 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +index 86e9fd1..aece938 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +index 3ecde87..3aba5e8 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +index df32a19..0f0181d 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +index 9540996..2eef6f3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +index f3db6e2..e825a10 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + typedef void (*dispatch_t)(long offset); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +index 0f687c3..c6d77e1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +index b27c6fc..6454827 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target *-*-linux* } } */ +-/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ + + extern void bar (void); + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +index 764a375..c67066c 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + void func0 (void); + void func1 (void); +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c +new file mode 100644 +index 0000000..7d396a3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c +new file mode 100644 +index 0000000..e7e616b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c +@@ -0,0 +1,20 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ ++/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c +new file mode 100644 +index 0000000..5320e92 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++void ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ ++/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +index 3a6727b..e6fea84 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ + + extern void (*bar) (void); + +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +index b8f6818..e239ec4 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ + + extern void (*bar) (void); + +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +index 01b0a02..fa31813 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ + + extern void (*bar) (void); + +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +index 4b497b5..fd5b41f 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ + + extern void (*bar) (void); + extern int foo (void) __attribute__ ((function_return("thunk"))); +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +index 4ae4c44..d606373 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ + + extern void (*bar) (void); + +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +index 5b5bc76..75e45e2 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ + + extern void (*bar) (void); + +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +index fa24a1f..d1db41c 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ + + extern void (*bar) (void); + +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch new file mode 100644 index 0000000000..cec84fefb2 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch @@ -0,0 +1,139 @@ +From 8f0efd692eb8db06d6c00b759c872bd2170b7f7b Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Sat, 6 Jan 2018 22:29:56 -0800 +Subject: [PATCH 07/12] x86: Add 'V' register operand modifier + +Add 'V', a special modifier which prints the name of the full integer +register without '%'. For + +extern void (*func_p) (void); + +void +foo (void) +{ + asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p)); +} + +it generates: + +foo: + movq func_p(%rip), %rax + call __x86_indirect_thunk_rax + ret + +gcc/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (print_reg): Print the name of the full + integer register without '%'. + (ix86_print_operand): Handle 'V'. + * doc/extend.texi: Document 'V' modifier. + +gcc/testsuite/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/indirect-thunk-register-4.c: New test. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 13 ++++++++++++- + gcc/doc/extend.texi | 3 +++ + gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++ + 3 files changed, 28 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 34e26a3..eeca7e5 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -16869,6 +16869,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse, + If CODE is 'h', pretend the reg is the 'high' byte register. + If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. + If CODE is 'd', duplicate the operand for AVX instruction. ++ If CODE is 'V', print naked full integer register name without %. + */ + + void +@@ -16879,7 +16880,7 @@ print_reg (rtx x, int code, FILE *file) + unsigned int regno; + bool duplicated; + +- if (ASSEMBLER_DIALECT == ASM_ATT) ++ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V') + putc ('%', file); + + if (x == pc_rtx) +@@ -16922,6 +16923,14 @@ print_reg (rtx x, int code, FILE *file) + && regno != FPSR_REG + && regno != FPCR_REG); + ++ if (code == 'V') ++ { ++ if (GENERAL_REGNO_P (regno)) ++ msize = GET_MODE_SIZE (word_mode); ++ else ++ error ("'V' modifier on non-integer register"); ++ } ++ + duplicated = code == 'd' && TARGET_AVX; + + switch (msize) +@@ -17035,6 +17044,7 @@ print_reg (rtx x, int code, FILE *file) + & -- print some in-use local-dynamic symbol name. + H -- print a memory address offset by 8; used for sse high-parts + Y -- print condition for XOP pcom* instruction. ++ V -- print naked full integer register name without %. + + -- print a branch hint as 'cs' or 'ds' prefix + ; -- print a semicolon (after prefixes due to bug in older gas). + ~ -- print "i" if TARGET_AVX2, "f" otherwise. +@@ -17259,6 +17269,7 @@ ix86_print_operand (FILE *file, rtx x, int code) + case 'X': + case 'P': + case 'p': ++ case 'V': + break; + + case 's': +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index 2cb6bd1..76ba1d4 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -8511,6 +8511,9 @@ The table below shows the list of supported modifiers and their effects. + @tab @code{2} + @end multitable + ++@code{V} is a special modifier which prints the name of the full integer ++register without @code{%}. ++ + @anchor{x86floatingpointasmoperands} + @subsubsection x86 Floating-Point @code{asm} Operands + +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +new file mode 100644 +index 0000000..f0cd9b7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mindirect-branch=keep -fno-pic" } */ ++ ++extern void (*func_p) (void); ++ ++void ++foo (void) ++{ ++ asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); ++} ++ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { target ia32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { target { ! ia32 } } } } */ +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch new file mode 100644 index 0000000000..d8a581013a --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch @@ -0,0 +1,304 @@ +From 8e0d9bf93e2e2ec03c544572aef4b03a8e7090f3 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <hjl.tools@gmail.com> +Date: Sat, 13 Jan 2018 18:01:54 -0800 +Subject: [PATCH 08/12] x86: Disallow -mindirect-branch=/-mfunction-return= + with -mcmodel=large + +Since the thunk function may not be reachable in large code model, +-mcmodel=large is incompatible with -mindirect-branch=thunk, +-mindirect-branch=thunk-extern, -mfunction-return=thunk and +-mfunction-return=thunk-extern. Issue an error when they are used with +-mcmodel=large. + +gcc/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (ix86_set_indirect_branch_type): Disallow + -mcmodel=large with -mindirect-branch=thunk, + -mindirect-branch=thunk-extern, -mfunction-return=thunk and + -mfunction-return=thunk-extern. + * doc/invoke.texi: Document -mcmodel=large is incompatible with + -mindirect-branch=thunk, -mindirect-branch=thunk-extern, + -mfunction-return=thunk and -mfunction-return=thunk-extern. + +gcc/testsuite/ + + Backport from mainline + 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/indirect-thunk-10.c: New test. + * gcc.target/i386/indirect-thunk-8.c: Likewise. + * gcc.target/i386/indirect-thunk-9.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-10.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-11.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-9.c: Likewise. + * gcc.target/i386/ret-thunk-17.c: Likewise. + * gcc.target/i386/ret-thunk-18.c: Likewise. + * gcc.target/i386/ret-thunk-19.c: Likewise. + * gcc.target/i386/ret-thunk-20.c: Likewise. + * gcc.target/i386/ret-thunk-21.c: Likewise. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 26 ++++++++++++++++++++++ + gcc/doc/invoke.texi | 11 +++++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | 7 ++++++ + .../gcc.target/i386/indirect-thunk-attr-10.c | 9 ++++++++ + .../gcc.target/i386/indirect-thunk-attr-11.c | 9 ++++++++ + .../gcc.target/i386/indirect-thunk-attr-9.c | 9 ++++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-17.c | 7 ++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-18.c | 8 +++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-19.c | 8 +++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-20.c | 9 ++++++++ + gcc/testsuite/gcc.target/i386/ret-thunk-21.c | 9 ++++++++ + 13 files changed, 126 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index eeca7e5..9c038be 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -6389,6 +6389,19 @@ ix86_set_indirect_branch_type (tree fndecl) + } + else + cfun->machine->indirect_branch_type = ix86_indirect_branch; ++ ++ /* -mcmodel=large is not compatible with -mindirect-branch=thunk ++ nor -mindirect-branch=thunk-extern. */ ++ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) ++ && ((cfun->machine->indirect_branch_type ++ == indirect_branch_thunk_extern) ++ || (cfun->machine->indirect_branch_type ++ == indirect_branch_thunk))) ++ error ("%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not " ++ "compatible", ++ ((cfun->machine->indirect_branch_type ++ == indirect_branch_thunk_extern) ++ ? "thunk-extern" : "thunk")); + } + + if (cfun->machine->function_return_type == indirect_branch_unset) +@@ -6414,6 +6427,19 @@ ix86_set_indirect_branch_type (tree fndecl) + } + else + cfun->machine->function_return_type = ix86_function_return; ++ ++ /* -mcmodel=large is not compatible with -mfunction-return=thunk ++ nor -mfunction-return=thunk-extern. */ ++ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) ++ && ((cfun->machine->function_return_type ++ == indirect_branch_thunk_extern) ++ || (cfun->machine->function_return_type ++ == indirect_branch_thunk))) ++ error ("%<-mfunction-return=%s%> and %<-mcmodel=large%> are not " ++ "compatible", ++ ((cfun->machine->function_return_type ++ == indirect_branch_thunk_extern) ++ ? "thunk-extern" : "thunk")); + } + } + +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index ad9f295..48e827f 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -24230,6 +24230,11 @@ to external call and return thunk provided in a separate object file. + You can control this behavior for a specific function by using the + function attribute @code{indirect_branch}. @xref{Function Attributes}. + ++Note that @option{-mcmodel=large} is incompatible with ++@option{-mindirect-branch=thunk} nor ++@option{-mindirect-branch=thunk-extern} since the thunk function may ++not be reachable in large code model. ++ + @item -mfunction-return=@var{choice} + @opindex -mfunction-return + Convert function return with @var{choice}. The default is @samp{keep}, +@@ -24241,6 +24246,12 @@ object file. You can control this behavior for a specific function by + using the function attribute @code{function_return}. + @xref{Function Attributes}. + ++Note that @option{-mcmodel=large} is incompatible with ++@option{-mfunction-return=thunk} nor ++@option{-mfunction-return=thunk-extern} since the thunk function may ++not be reachable in large code model. ++ ++ + @item -mindirect-branch-register + @opindex -mindirect-branch-register + Force indirect call and jump via register. +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c +new file mode 100644 +index 0000000..a0674bd +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-inline -mfunction-return=keep -mcmodel=large" } */ ++ ++void ++bar (void) ++{ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c +new file mode 100644 +index 0000000..7a80a89 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk -mfunction-return=keep -mcmodel=large" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c +new file mode 100644 +index 0000000..d4d45c5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=thunk-extern -mfunction-return=keep -mcmodel=large" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c +new file mode 100644 +index 0000000..3a2aead +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk-extern"))) ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c +new file mode 100644 +index 0000000..8e52f03 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk-inline"))) ++void ++bar (void) ++{ ++} +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c +new file mode 100644 +index 0000000..bdaa4f6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((indirect_branch("thunk"))) ++void ++bar (void) ++{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c +new file mode 100644 +index 0000000..0605e2c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c +@@ -0,0 +1,7 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=keep -mcmodel=large" } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c +new file mode 100644 +index 0000000..307019d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c +@@ -0,0 +1,8 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c +new file mode 100644 +index 0000000..772617f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c +@@ -0,0 +1,8 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ ++ ++__attribute__ ((function_return("thunk"))) ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c +new file mode 100644 +index 0000000..1e9f9bd +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((function_return("thunk-extern"))) ++void ++bar (void) ++{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ ++} +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c +new file mode 100644 +index 0000000..eea07f7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile { target { lp64 } } } */ ++/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ ++/* { dg-additional-options "-fPIC" { target fpic } } */ ++ ++__attribute__ ((function_return("thunk-inline"))) ++void ++bar (void) ++{ ++} +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch new file mode 100644 index 0000000000..7364a2c36a --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch @@ -0,0 +1,126 @@ +From 3eff2adada2b1667b0e76496fa559e0c248ecd84 Mon Sep 17 00:00:00 2001 +From: uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Thu, 25 Jan 2018 19:39:01 +0000 +Subject: [PATCH 09/12] Use INVALID_REGNUM in indirect thunk processing + + Backport from mainline + 2018-01-17 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.c (indirect_thunk_name): Declare regno + as unsigned int. Compare regno with INVALID_REGNUM. + (output_indirect_thunk): Ditto. + (output_indirect_thunk_function): Ditto. + (ix86_code_end): Declare regno as unsigned int. Use INVALID_REGNUM + in the call to output_indirect_thunk_function. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257067 138bc75d-0d04-0410-961f-82ee72b054a4 + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 9c038be..4012657 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -11087,16 +11087,16 @@ static int indirect_thunks_bnd_used; + /* Fills in the label name that should be used for the indirect thunk. */ + + static void +-indirect_thunk_name (char name[32], int regno, bool need_bnd_p, +- bool ret_p) ++indirect_thunk_name (char name[32], unsigned int regno, ++ bool need_bnd_p, bool ret_p) + { +- if (regno >= 0 && ret_p) ++ if (regno != INVALID_REGNUM && ret_p) + gcc_unreachable (); + + if (USE_HIDDEN_LINKONCE) + { + const char *bnd = need_bnd_p ? "_bnd" : ""; +- if (regno >= 0) ++ if (regno != INVALID_REGNUM) + { + const char *reg_prefix; + if (LEGACY_INT_REGNO_P (regno)) +@@ -11114,7 +11114,7 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p, + } + else + { +- if (regno >= 0) ++ if (regno != INVALID_REGNUM) + { + if (need_bnd_p) + ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); +@@ -11166,7 +11166,7 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p, + */ + + static void +-output_indirect_thunk (bool need_bnd_p, int regno) ++output_indirect_thunk (bool need_bnd_p, unsigned int regno) + { + char indirectlabel1[32]; + char indirectlabel2[32]; +@@ -11196,7 +11196,7 @@ output_indirect_thunk (bool need_bnd_p, int regno) + + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); + +- if (regno >= 0) ++ if (regno != INVALID_REGNUM) + { + /* MOV. */ + rtx xops[2]; +@@ -11220,12 +11220,12 @@ output_indirect_thunk (bool need_bnd_p, int regno) + } + + /* Output a funtion with a call and return thunk for indirect branch. +- If BND_P is true, the BND prefix is needed. If REGNO != -1, the +- function address is in REGNO. Otherwise, the function address is ++ If BND_P is true, the BND prefix is needed. If REGNO != INVALID_REGNUM, ++ the function address is in REGNO. Otherwise, the function address is + on the top of stack. */ + + static void +-output_indirect_thunk_function (bool need_bnd_p, int regno) ++output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) + { + char name[32]; + tree decl; +@@ -11274,7 +11274,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) + ASM_OUTPUT_LABEL (asm_out_file, name); + } + +- if (regno < 0) ++ if (regno == INVALID_REGNUM) + { + /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ + char alias[32]; +@@ -11348,16 +11348,16 @@ static void + ix86_code_end (void) + { + rtx xops[2]; +- int regno; ++ unsigned int regno; + + if (indirect_thunk_needed) +- output_indirect_thunk_function (false, -1); ++ output_indirect_thunk_function (false, INVALID_REGNUM); + if (indirect_thunk_bnd_needed) +- output_indirect_thunk_function (true, -1); ++ output_indirect_thunk_function (true, INVALID_REGNUM); + + for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) + { +- int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; ++ unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; + if ((indirect_thunks_used & (1 << i))) + output_indirect_thunk_function (false, regno); + +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch new file mode 100644 index 0000000000..080d741983 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch @@ -0,0 +1,46 @@ +From c4300d9ad683e693c90d02d4f1b13183bf2d4acc Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Fri, 2 Feb 2018 16:47:02 +0000 +Subject: [PATCH 10/12] i386: Pass INVALID_REGNUM as invalid register number + + Backport from mainline + * config/i386/i386.c (ix86_output_function_return): Pass + INVALID_REGNUM, instead of -1, as invalid register number to + indirect_thunk_name and output_indirect_thunk. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257341 138bc75d-0d04-0410-961f-82ee72b054a4 + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 4012657..66502ee 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -28056,7 +28056,8 @@ ix86_output_function_return (bool long_p) + { + bool need_thunk = (cfun->machine->function_return_type + == indirect_branch_thunk); +- indirect_thunk_name (thunk_name, -1, need_bnd_p, true); ++ indirect_thunk_name (thunk_name, INVALID_REGNUM, need_bnd_p, ++ true); + if (need_bnd_p) + { + indirect_thunk_bnd_needed |= need_thunk; +@@ -28069,7 +28070,7 @@ ix86_output_function_return (bool long_p) + } + } + else +- output_indirect_thunk (need_bnd_p, -1); ++ output_indirect_thunk (need_bnd_p, INVALID_REGNUM); + + return ""; + } +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch new file mode 100644 index 0000000000..3b036fbe18 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch @@ -0,0 +1,453 @@ +From b3a2269c7884378a9afd394ac7e669aab0443b57 Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Mon, 26 Feb 2018 15:29:30 +0000 +Subject: [PATCH 11/12] i386: Update -mfunction-return= for return with pop + +When -mfunction-return= is used, simple_return_pop_internal should pop +return address into ECX register, adjust stack by bytes to pop from stack +and jump to the return thunk via ECX register. + +Revision 257992 removed the bool argument from ix86_output_indirect_jmp. +Update comments to reflect it. + +Tested on i686 and x86-64. + + Backport from mainline + * config/i386/i386.c (ix86_output_indirect_jmp): Update comments. + + PR target/84530 + * config/i386/i386-protos.h (ix86_output_indirect_jmp): Remove + the bool argument. + (ix86_output_indirect_function_return): New prototype. + (ix86_split_simple_return_pop_internal): Likewise. + * config/i386/i386.c (indirect_return_via_cx): New. + (indirect_return_via_cx_bnd): Likewise. + (indirect_thunk_name): Handle return va CX_REG. + (output_indirect_thunk_function): Create alias for + __x86_return_thunk_[re]cx and __x86_return_thunk_[re]cx_bnd. + (ix86_output_indirect_jmp): Remove the bool argument. + (ix86_output_indirect_function_return): New function. + (ix86_split_simple_return_pop_internal): Likewise. + * config/i386/i386.md (*indirect_jump): Don't pass false + to ix86_output_indirect_jmp. + (*tablejump_1): Likewise. + (simple_return_pop_internal): Change it to define_insn_and_split. + Call ix86_split_simple_return_pop_internal to split it for + -mfunction-return=. + (simple_return_indirect_internal): Call + ix86_output_indirect_function_return instead of + ix86_output_indirect_jmp. + +gcc/testsuite/ + + Backport from mainline + PR target/84530 + * gcc.target/i386/ret-thunk-22.c: New test. + * gcc.target/i386/ret-thunk-23.c: Likewise. + * gcc.target/i386/ret-thunk-24.c: Likewise. + * gcc.target/i386/ret-thunk-25.c: Likewise. + * gcc.target/i386/ret-thunk-26.c: Likewise. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/i386-protos.h | 4 +- + gcc/config/i386/i386.c | 127 +++++++++++++++++++++++---- + gcc/config/i386/i386.md | 11 ++- + gcc/testsuite/gcc.target/i386/ret-thunk-22.c | 15 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-23.c | 15 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-24.c | 15 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-25.c | 15 ++++ + gcc/testsuite/gcc.target/i386/ret-thunk-26.c | 40 +++++++++ + 8 files changed, 222 insertions(+), 20 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-22.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-23.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-24.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-25.c + create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-26.c + +diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h +index 620d70e..c7a0ccb5 100644 +--- a/gcc/config/i386/i386-protos.h ++++ b/gcc/config/i386/i386-protos.h +@@ -311,8 +311,10 @@ extern enum attr_cpu ix86_schedule; + #endif + + extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); +-extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); ++extern const char * ix86_output_indirect_jmp (rtx call_op); + extern const char * ix86_output_function_return (bool long_p); ++extern const char * ix86_output_indirect_function_return (rtx ret_op); ++extern void ix86_split_simple_return_pop_internal (rtx); + extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, + enum machine_mode mode); + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 66502ee..21c3c18 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -11080,6 +11080,12 @@ static int indirect_thunks_used; + by call and return thunks functions with the BND prefix. */ + static int indirect_thunks_bnd_used; + ++/* True if return thunk function via CX is needed. */ ++static bool indirect_return_via_cx; ++/* True if return thunk function via CX with the BND prefix is ++ needed. */ ++static bool indirect_return_via_cx_bnd; ++ + #ifndef INDIRECT_LABEL + # define INDIRECT_LABEL "LIND" + #endif +@@ -11090,12 +11096,13 @@ static void + indirect_thunk_name (char name[32], unsigned int regno, + bool need_bnd_p, bool ret_p) + { +- if (regno != INVALID_REGNUM && ret_p) ++ if (regno != INVALID_REGNUM && regno != CX_REG && ret_p) + gcc_unreachable (); + + if (USE_HIDDEN_LINKONCE) + { + const char *bnd = need_bnd_p ? "_bnd" : ""; ++ const char *ret = ret_p ? "return" : "indirect"; + if (regno != INVALID_REGNUM) + { + const char *reg_prefix; +@@ -11103,14 +11110,11 @@ indirect_thunk_name (char name[32], unsigned int regno, + reg_prefix = TARGET_64BIT ? "r" : "e"; + else + reg_prefix = ""; +- sprintf (name, "__x86_indirect_thunk%s_%s%s", +- bnd, reg_prefix, reg_names[regno]); ++ sprintf (name, "__x86_%s_thunk%s_%s%s", ++ ret, bnd, reg_prefix, reg_names[regno]); + } + else +- { +- const char *ret = ret_p ? "return" : "indirect"; +- sprintf (name, "__x86_%s_thunk%s", ret, bnd); +- } ++ sprintf (name, "__x86_%s_thunk%s", ret, bnd); + } + else + { +@@ -11274,9 +11278,23 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) + ASM_OUTPUT_LABEL (asm_out_file, name); + } + ++ /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or ++ __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd. */ ++ bool need_alias; + if (regno == INVALID_REGNUM) ++ need_alias = true; ++ else if (regno == CX_REG) ++ { ++ if (need_bnd_p) ++ need_alias = indirect_return_via_cx_bnd; ++ else ++ need_alias = indirect_return_via_cx; ++ } ++ else ++ need_alias = false; ++ ++ if (need_alias) + { +- /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ + char alias[32]; + + indirect_thunk_name (alias, regno, need_bnd_p, true); +@@ -28019,18 +28037,17 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, + else + ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); + } +-/* Output indirect jump. CALL_OP is the jump target. Jump is a +- function return if RET_P is true. */ ++ ++/* Output indirect jump. CALL_OP is the jump target. */ + + const char * +-ix86_output_indirect_jmp (rtx call_op, bool ret_p) ++ix86_output_indirect_jmp (rtx call_op) + { + if (cfun->machine->indirect_branch_type != indirect_branch_keep) + { +- /* We can't have red-zone if this isn't a function return since +- "call" in the indirect thunk pushes the return address onto +- stack, destroying red-zone. */ +- if (!ret_p && ix86_red_zone_size != 0) ++ /* We can't have red-zone since "call" in the indirect thunk ++ pushes the return address onto stack, destroying red-zone. */ ++ if (ix86_red_zone_size != 0) + gcc_unreachable (); + + ix86_output_indirect_branch (call_op, "%0", true); +@@ -28081,6 +28098,86 @@ ix86_output_function_return (bool long_p) + return "rep%; ret"; + } + ++/* Output indirect function return. RET_OP is the function return ++ target. */ ++ ++const char * ++ix86_output_indirect_function_return (rtx ret_op) ++{ ++ if (cfun->machine->function_return_type != indirect_branch_keep) ++ { ++ char thunk_name[32]; ++ bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); ++ unsigned int regno = REGNO (ret_op); ++ gcc_assert (regno == CX_REG); ++ ++ if (cfun->machine->function_return_type ++ != indirect_branch_thunk_inline) ++ { ++ bool need_thunk = (cfun->machine->function_return_type ++ == indirect_branch_thunk); ++ indirect_thunk_name (thunk_name, regno, need_bnd_p, true); ++ if (need_bnd_p) ++ { ++ if (need_thunk) ++ { ++ indirect_return_via_cx_bnd = true; ++ indirect_thunks_bnd_used |= 1 << CX_REG; ++ } ++ fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); ++ } ++ else ++ { ++ if (need_thunk) ++ { ++ indirect_return_via_cx = true; ++ indirect_thunks_used |= 1 << CX_REG; ++ } ++ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); ++ } ++ } ++ else ++ output_indirect_thunk (need_bnd_p, regno); ++ ++ return ""; ++ } ++ else ++ return "%!jmp\t%A0"; ++} ++ ++/* Split simple return with popping POPC bytes from stack to indirect ++ branch with stack adjustment . */ ++ ++void ++ix86_split_simple_return_pop_internal (rtx popc) ++{ ++ struct machine_function *m = cfun->machine; ++ rtx ecx = gen_rtx_REG (SImode, CX_REG); ++ rtx_insn *insn; ++ ++ /* There is no "pascal" calling convention in any 64bit ABI. */ ++ gcc_assert (!TARGET_64BIT); ++ ++ insn = emit_insn (gen_pop (ecx)); ++ m->fs.cfa_offset -= UNITS_PER_WORD; ++ m->fs.sp_offset -= UNITS_PER_WORD; ++ ++ rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); ++ x = gen_rtx_SET (stack_pointer_rtx, x); ++ add_reg_note (insn, REG_CFA_ADJUST_CFA, x); ++ add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx)); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ ++ x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, popc); ++ x = gen_rtx_SET (stack_pointer_rtx, x); ++ insn = emit_insn (x); ++ add_reg_note (insn, REG_CFA_ADJUST_CFA, x); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ ++ /* Now return address is in ECX. */ ++ emit_jump_insn (gen_simple_return_indirect_internal (ecx)); ++} ++ + /* Output the assembly for a call instruction. */ + + const char * +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index 05a88ff..857466a 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11813,7 +11813,7 @@ + (define_insn "*indirect_jump" + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] + "" +- "* return ix86_output_indirect_jmp (operands[0], false);" ++ "* return ix86_output_indirect_jmp (operands[0]);" + [(set (attr "type") + (if_then_else (match_test "(cfun->machine->indirect_branch_type + != indirect_branch_keep)") +@@ -11868,7 +11868,7 @@ + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) + (use (label_ref (match_operand 1)))] + "" +- "* return ix86_output_indirect_jmp (operands[0], false);" ++ "* return ix86_output_indirect_jmp (operands[0]);" + [(set (attr "type") + (if_then_else (match_test "(cfun->machine->indirect_branch_type + != indirect_branch_keep)") +@@ -12520,11 +12520,14 @@ + (set_attr "prefix_rep" "1") + (set_attr "modrm" "0")]) + +-(define_insn "simple_return_pop_internal" ++(define_insn_and_split "simple_return_pop_internal" + [(simple_return) + (use (match_operand:SI 0 "const_int_operand"))] + "reload_completed" + "%!ret\t%0" ++ "&& cfun->machine->function_return_type != indirect_branch_keep" ++ [(const_int 0)] ++ "ix86_split_simple_return_pop_internal (operands[0]); DONE;" + [(set_attr "length" "3") + (set_attr "atom_unit" "jeu") + (set_attr "length_immediate" "2") +@@ -12535,7 +12538,7 @@ + [(simple_return) + (use (match_operand:SI 0 "register_operand" "r"))] + "reload_completed" +- "* return ix86_output_indirect_jmp (operands[0], true);" ++ "* return ix86_output_indirect_function_return (operands[0]);" + [(set (attr "type") + (if_then_else (match_test "(cfun->machine->indirect_branch_type + != indirect_branch_keep)") +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-22.c b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c +new file mode 100644 +index 0000000..89e086d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c +@@ -0,0 +1,15 @@ ++/* PR target/r84530 */ ++/* { dg-do compile { target ia32 } } */ ++/* { dg-options "-O2 -mfunction-return=thunk" } */ ++ ++struct s { _Complex unsigned short x; }; ++struct s gs = { 100 + 200i }; ++struct s __attribute__((noinline)) foo (void) { return gs; } ++ ++/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ ++/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-23.c b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c +new file mode 100644 +index 0000000..43f0cca +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c +@@ -0,0 +1,15 @@ ++/* PR target/r84530 */ ++/* { dg-do compile { target ia32 } } */ ++/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ ++ ++struct s { _Complex unsigned short x; }; ++struct s gs = { 100 + 200i }; ++struct s __attribute__((noinline)) foo (void) { return gs; } ++ ++/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ ++/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not {\tpause} } } */ ++/* { dg-final { scan-assembler-not {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-24.c b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c +new file mode 100644 +index 0000000..8729e35 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c +@@ -0,0 +1,15 @@ ++/* PR target/r84530 */ ++/* { dg-do compile { target ia32 } } */ ++/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ ++ ++struct s { _Complex unsigned short x; }; ++struct s gs = { 100 + 200i }; ++struct s __attribute__((noinline)) foo (void) { return gs; } ++ ++/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ ++/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-25.c b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c +new file mode 100644 +index 0000000..f73553c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c +@@ -0,0 +1,15 @@ ++/* PR target/r84530 */ ++/* { dg-do compile { target ia32 } } */ ++/* { dg-options "-O2 -mfunction-return=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ ++ ++struct s { _Complex unsigned short x; }; ++struct s gs = { 100 + 200i }; ++struct s __attribute__((noinline)) foo (void) { return gs; } ++ ++/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ ++/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_bnd_ecx" } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler {\tpause} } } */ ++/* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c +new file mode 100644 +index 0000000..9144e98 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c +@@ -0,0 +1,40 @@ ++/* PR target/r84530 */ ++/* { dg-do run } */ ++/* { dg-options "-Os -mfunction-return=thunk" } */ ++ ++struct S { int i; }; ++__attribute__((const, noinline, noclone)) ++struct S foo (int x) ++{ ++ struct S s; ++ s.i = x; ++ return s; ++} ++ ++int a[2048], b[2048], c[2048], d[2048]; ++struct S e[2048]; ++ ++__attribute__((noinline, noclone)) void ++bar (void) ++{ ++ int i; ++ for (i = 0; i < 1024; i++) ++ { ++ e[i] = foo (i); ++ a[i+2] = a[i] + a[i+1]; ++ b[10] = b[10] + i; ++ c[i] = c[2047 - i]; ++ d[i] = d[i + 1]; ++ } ++} ++ ++int ++main () ++{ ++ int i; ++ bar (); ++ for (i = 0; i < 1024; i++) ++ if (e[i].i != i) ++ __builtin_abort (); ++ return 0; ++} +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch new file mode 100644 index 0000000000..b50ac5cb02 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch @@ -0,0 +1,1004 @@ +From 7ba192d11a43d24ce427a3dfce0ad0592bd52830 Mon Sep 17 00:00:00 2001 +From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Mon, 26 Feb 2018 17:00:46 +0000 +Subject: [PATCH 12/12] i386: Add TARGET_INDIRECT_BRANCH_REGISTER + +For + +--- +struct C { + virtual ~C(); + virtual void f(); +}; + +void +f (C *p) +{ + p->f(); + p->f(); +} +--- + +-mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: + +_Z1fP1C: +.LFB0: + .cfi_startproc + pushq %rbx + .cfi_def_cfa_offset 16 + .cfi_offset 3, -16 + movq (%rdi), %rax + movq %rdi, %rbx + jmp .LIND1 +.LIND0: + pushq 16(%rax) + jmp __x86_indirect_thunk +.LIND1: + call .LIND0 + movq (%rbx), %rax + movq %rbx, %rdi + popq %rbx + .cfi_def_cfa_offset 8 + movq 16(%rax), %rax + jmp __x86_indirect_thunk_rax + .cfi_endproc + +x86-64 is supposed to have asynchronous unwind tables by default, but +there is nothing that reflects the change in the (relative) frame +address after .LIND0. That region really has to be moved outside of +the .cfi_startproc/.cfi_endproc bracket. + +This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect +branch via register whenever -mindirect-branch= is used. Now, +-mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: + +_Z1fP1C: +.LFB0: + .cfi_startproc + pushq %rbx + .cfi_def_cfa_offset 16 + .cfi_offset 3, -16 + movq (%rdi), %rax + movq %rdi, %rbx + movq 16(%rax), %rax + call __x86_indirect_thunk_rax + movq (%rbx), %rax + movq %rbx, %rdi + popq %rbx + .cfi_def_cfa_offset 8 + movq 16(%rax), %rax + jmp __x86_indirect_thunk_rax + .cfi_endproc + +so that "-mindirect-branch=thunk-extern" is equivalent to +"-mindirect-branch=thunk-extern -mindirect-branch-register", which is +used by Linux kernel. + +gcc/ + + Backport from mainline + PR target/84039 + * config/i386/constraints.md (Bs): Replace + ix86_indirect_branch_register with + TARGET_INDIRECT_BRANCH_REGISTER. + (Bw): Likewise. + * config/i386/i386.md (indirect_jump): Likewise. + (tablejump): Likewise. + (*sibcall_memory): Likewise. + (*sibcall_value_memory): Likewise. + Peepholes of indirect call and jump via memory: Likewise. + (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER. + (*sibcall_value_GOT_32): Likewise. + * config/i386/predicates.md (indirect_branch_operand): Likewise. + (GOT_memory_operand): Likewise. + (call_insn_operand): Likewise. + (sibcall_insn_operand): Likewise. + (GOT32_symbol_operand): Likewise. + * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New. + +gcc/testsuite/ + + Backport from mainline + PR target/84039 + * gcc.target/i386/indirect-thunk-1.c: Updated. + * gcc.target/i386/indirect-thunk-2.c: Likewise. + * gcc.target/i386/indirect-thunk-3.c: Likewise. + * gcc.target/i386/indirect-thunk-4.c: Likewise. + * gcc.target/i386/indirect-thunk-5.c: Likewise. + * gcc.target/i386/indirect-thunk-6.c: Likewise. + * gcc.target/i386/indirect-thunk-7.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. + * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. + * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. + * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. + * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. + * gcc.target/i386/ret-thunk-9.c: Likewise. + * gcc.target/i386/ret-thunk-10.c: Likewise. + * gcc.target/i386/ret-thunk-11.c: Likewise. + * gcc.target/i386/ret-thunk-12.c: Likewise. + * gcc.target/i386/ret-thunk-13.c: Likewise. + * gcc.target/i386/ret-thunk-14.c: Likewise. + * gcc.target/i386/ret-thunk-15.c: Likewise. + +Upstream-Status: Pending + +Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> + +--- + gcc/config/i386/constraints.md | 4 ++-- + gcc/config/i386/i386.h | 5 ++++ + gcc/config/i386/i386.md | 28 +++++++++++++--------- + gcc/config/i386/predicates.md | 6 ++--- + gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 5 ++-- + gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 5 ++-- + gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 5 ++-- + gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 5 ++-- + gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 6 +++-- + gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 12 ++++++---- + gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-attr-1.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-attr-2.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-attr-3.c | 3 +-- + .../gcc.target/i386/indirect-thunk-attr-4.c | 3 +-- + .../gcc.target/i386/indirect-thunk-attr-5.c | 9 ++++--- + .../gcc.target/i386/indirect-thunk-attr-6.c | 9 ++++--- + .../gcc.target/i386/indirect-thunk-attr-7.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-bnd-1.c | 6 ++--- + .../gcc.target/i386/indirect-thunk-bnd-2.c | 6 ++--- + .../gcc.target/i386/indirect-thunk-bnd-3.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-bnd-4.c | 7 +++--- + .../gcc.target/i386/indirect-thunk-extern-1.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-extern-2.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-extern-3.c | 9 ++++--- + .../gcc.target/i386/indirect-thunk-extern-4.c | 6 ++--- + .../gcc.target/i386/indirect-thunk-extern-5.c | 6 +++-- + .../gcc.target/i386/indirect-thunk-extern-6.c | 8 +++---- + .../gcc.target/i386/indirect-thunk-extern-7.c | 5 ++-- + .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- + .../gcc.target/i386/indirect-thunk-inline-5.c | 3 ++- + .../gcc.target/i386/indirect-thunk-inline-6.c | 3 ++- + .../gcc.target/i386/indirect-thunk-inline-7.c | 4 ++-- + gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 9 +++---- + gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 9 +++---- + gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 8 +++---- + gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 5 ++-- + gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 7 +++--- + gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 7 +++--- + gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 13 ++++------ + 43 files changed, 128 insertions(+), 141 deletions(-) + +diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md +index 9204c8e..ef684a9 100644 +--- a/gcc/config/i386/constraints.md ++++ b/gcc/config/i386/constraints.md +@@ -172,7 +172,7 @@ + + (define_constraint "Bs" + "@internal Sibcall memory operand." +- (ior (and (not (match_test "ix86_indirect_branch_register")) ++ (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) + (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") +@@ -180,7 +180,7 @@ + + (define_constraint "Bw" + "@internal Call memory operand." +- (ior (and (not (match_test "ix86_indirect_branch_register")) ++ (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) + (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index b34bc11..1816d71 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2676,6 +2676,11 @@ extern void debug_dispatch_window (int); + #define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0) + #define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0) + ++ ++#define TARGET_INDIRECT_BRANCH_REGISTER \ ++ (ix86_indirect_branch_register \ ++ || cfun->machine->indirect_branch_type != indirect_branch_keep) ++ + #define IX86_HLE_ACQUIRE (1 << 16) + #define IX86_HLE_RELEASE (1 << 17) + +diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md +index 857466a..6a6dc26 100644 +--- a/gcc/config/i386/i386.md ++++ b/gcc/config/i386/i386.md +@@ -11805,7 +11805,7 @@ + [(set (pc) (match_operand 0 "indirect_branch_operand"))] + "" + { +- if (TARGET_X32 || ix86_indirect_branch_register) ++ if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) + operands[0] = convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump = true; + }) +@@ -11859,7 +11859,7 @@ + OPTAB_DIRECT); + } + +- if (TARGET_X32 || ix86_indirect_branch_register) ++ if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) + operands[0] = convert_memory_address (word_mode, operands[0]); + cfun->machine->has_local_indirect_jump = true; + }) +@@ -12029,7 +12029,10 @@ + (match_operand:SI 0 "register_no_elim_operand" "U") + (match_operand:SI 1 "GOT32_symbol_operand")))) + (match_operand 2))] +- "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" ++ "!TARGET_MACHO ++ && !TARGET_64BIT ++ && !TARGET_INDIRECT_BRANCH_REGISTER ++ && SIBLING_CALL_P (insn)" + { + rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]); + fnaddr = gen_const_mem (Pmode, fnaddr); +@@ -12048,7 +12051,7 @@ + [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) + (match_operand 1)) + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] +- "!TARGET_X32 && !ix86_indirect_branch_register" ++ "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +@@ -12058,7 +12061,7 @@ + (call (mem:QI (match_dup 0)) + (match_operand 3))] + "!TARGET_X32 +- && !ix86_indirect_branch_register ++ && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (peep2_next_insn (1)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" +@@ -12073,7 +12076,7 @@ + (call (mem:QI (match_dup 0)) + (match_operand 3))] + "!TARGET_X32 +- && !ix86_indirect_branch_register ++ && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (peep2_next_insn (2)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" +@@ -12171,7 +12174,7 @@ + (match_operand:W 1 "memory_operand")) + (set (pc) (match_dup 0))] + "!TARGET_X32 +- && !ix86_indirect_branch_register ++ && !TARGET_INDIRECT_BRANCH_REGISTER + && peep2_reg_dead_p (2, operands[0])" + [(set (pc) (match_dup 1))]) + +@@ -12229,7 +12232,10 @@ + (match_operand:SI 1 "register_no_elim_operand" "U") + (match_operand:SI 2 "GOT32_symbol_operand")))) + (match_operand 3)))] +- "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" ++ "!TARGET_MACHO ++ && !TARGET_64BIT ++ && !TARGET_INDIRECT_BRANCH_REGISTER ++ && SIBLING_CALL_P (insn)" + { + rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]); + fnaddr = gen_const_mem (Pmode, fnaddr); +@@ -12250,7 +12256,7 @@ + (call (mem:QI (match_operand:W 1 "memory_operand" "m")) + (match_operand 2))) + (unspec [(const_int 0)] UNSPEC_PEEPSIB)] +- "!TARGET_X32 && !ix86_indirect_branch_register" ++ "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) + +@@ -12261,7 +12267,7 @@ + (call (mem:QI (match_dup 0)) + (match_operand 3)))] + "!TARGET_X32 +- && !ix86_indirect_branch_register ++ && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (peep2_next_insn (1)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" +@@ -12278,7 +12284,7 @@ + (call (mem:QI (match_dup 0)) + (match_operand 3)))] + "!TARGET_X32 +- && !ix86_indirect_branch_register ++ && !TARGET_INDIRECT_BRANCH_REGISTER + && SIBLING_CALL_P (peep2_next_insn (2)) + && !reg_mentioned_p (operands[0], + CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" +diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md +index d1f0a7d..5f8a98f 100644 +--- a/gcc/config/i386/predicates.md ++++ b/gcc/config/i386/predicates.md +@@ -593,7 +593,7 @@ + ;; Test for a valid operand for indirect branch. + (define_predicate "indirect_branch_operand" + (ior (match_operand 0 "register_operand") +- (and (not (match_test "ix86_indirect_branch_register")) ++ (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) + (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")))) + +@@ -637,7 +637,7 @@ + (ior (match_test "constant_call_address_operand + (op, mode == VOIDmode ? mode : Pmode)") + (match_operand 0 "call_register_no_elim_operand") +- (and (not (match_test "ix86_indirect_branch_register")) ++ (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") +@@ -648,7 +648,7 @@ + (ior (match_test "constant_call_address_operand + (op, mode == VOIDmode ? mode : Pmode)") + (match_operand 0 "register_no_elim_operand") +- (and (not (match_test "ix86_indirect_branch_register")) ++ (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) + (ior (and (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand")) + (and (match_test "TARGET_X32 && Pmode == DImode") +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +index 60d0988..6e94d2c 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c +@@ -11,9 +11,8 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +index aac7516..3c46707 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c +@@ -11,9 +11,8 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +index 9e24a38..2c7fb52 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c +@@ -12,9 +12,8 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +index 127b5d9..0d3f895 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c +@@ -12,9 +12,8 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +index fcaa18d..fb26c00 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c +@@ -9,8 +9,10 @@ foo (void) + bar (); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +index e464928..aa03fbd 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c +@@ -10,9 +10,13 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 { target x32 } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler {\tpause} } } */ + /* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +index 17c2d0f..3c72036 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c +@@ -35,9 +35,8 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +index 9194ccf..7106407 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c +@@ -14,9 +14,8 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +index e51f261..27c7e5b 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c +@@ -12,9 +12,8 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +index 4aeec18..89a2bac 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c +@@ -14,10 +14,9 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler {\tpause} } } */ + /* { dg-final { scan-assembler {\tlfence} } } */ + /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +index ac0e599..3eb83c3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c +@@ -13,10 +13,9 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler {\tpause} } } */ + /* { dg-final { scan-assembler {\tlfence} } } */ + /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +index 573cf1e..0098dd1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c +@@ -14,9 +14,8 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +index b2b37fc..ece8de1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c +@@ -13,9 +13,8 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +index 4a43e19..d53fc88 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c +@@ -36,9 +36,8 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +index ac84ab6..73d16ba 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c +@@ -10,9 +10,9 @@ foo (void) + dispatch (buf); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "bnd ret" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +index ce655e8..856751a 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c +@@ -11,10 +11,8 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "bnd ret" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +index d34485a..42312f6 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c +@@ -10,8 +10,9 @@ foo (void) + bar (buf); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "bnd ret" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +index 0e19830..c8ca102 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c +@@ -11,10 +11,9 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ +-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ +-/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 1 } } */ + /* { dg-final { scan-assembler "bnd ret" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ + /* { dg-final { scan-assembler {\tlfence} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +index 579441f..c09dd0a 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c +@@ -11,9 +11,8 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +index c92e6f2..826425a 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c +@@ -11,9 +11,8 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +index d9964c2..3856268 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c +@@ -12,9 +12,8 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ ++/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +index d4dca4d..1ae49b1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c +@@ -12,9 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +index 5c07e02..5328239 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c +@@ -9,8 +9,10 @@ foo (void) + bar (); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +index 3eb4406..8ae4348 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c +@@ -10,8 +10,8 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ +-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ +-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +index aece938..2b9a33e 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c +@@ -35,9 +35,8 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ + /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +index 3aba5e8..869d904 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch(offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +index 0f0181d..c5c16ed 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c +@@ -11,7 +11,7 @@ male_indirect_jump (long offset) + dispatch[offset](offset); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +index 2eef6f3..4a63ebe 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +index e825a10..a395ffc 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c +@@ -12,7 +12,7 @@ male_indirect_jump (long offset) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +index c6d77e1..21cbfd3 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c +@@ -9,7 +9,8 @@ foo (void) + bar (); + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +index 6454827..d1300f1 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c +@@ -10,7 +10,8 @@ foo (void) + return 0; + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ ++/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +index c67066c..ea00924 100644 +--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c +@@ -35,8 +35,8 @@ bar (int i) + } + } + +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%(r|e)ax" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler {\tpause} } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +index e6fea84..af9023a 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c +@@ -15,9 +15,6 @@ foo (void) + /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ + /* { dg-final { scan-assembler-times {\tpause} 2 } } */ + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +index e239ec4..ba467c5 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c +@@ -15,9 +15,6 @@ foo (void) + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +index fa31813..43e57ca 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c +@@ -15,8 +15,6 @@ foo (void) + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +index fd5b41f..55f156c 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c +@@ -14,9 +14,8 @@ foo (void) + /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ + /* { dg-final { scan-assembler-times {\tpause} 2 } } */ + /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ + /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ + /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ + /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ +-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +index d606373..1c79043 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c +@@ -16,7 +16,6 @@ foo (void) + /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +index 75e45e2..58aba31 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c +@@ -16,7 +16,6 @@ foo (void) + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler-times {\tpause} 1 } } */ + /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +index d1db41c..d2df8b8 100644 +--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c ++++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c +@@ -14,11 +14,8 @@ foo (void) + /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ + /* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ +-/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ +-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ +-/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ +-/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ +-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ +-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ ++/* { dg-final { scan-assembler-times {\tpause} 2 } } */ ++/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ ++/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ ++/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ +-- +2.7.4 + diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/CVE-2016-6131.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/CVE-2016-6131.patch new file mode 100644 index 0000000000..3cdbb2d171 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/CVE-2016-6131.patch @@ -0,0 +1,223 @@ +From 59a0e4bd8391962f62600ae3ac95ab0fba74d464 Mon Sep 17 00:00:00 2001 +From: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> +Date: Thu, 4 Aug 2016 16:53:18 +0000 +Subject: [PATCH] Fix for PR71696 in Libiberty Demangler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[BZ #71696] -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71696 + +2016-08-04 Marcel Böhme <boehme.marcel@gmail.com> + + PR c++/71696 + * cplus-dem.c: Prevent infinite recursion when there is a cycle + in the referencing of remembered mangled types. + (work_stuff): New stack to keep track of the remembered mangled + types that are currently being processed. + (push_processed_type): New method to push currently processed + remembered type onto the stack. + (pop_processed_type): New method to pop currently processed + remembered type from the stack. + (work_stuff_copy_to_from): Copy values of new variables. + (delete_non_B_K_work_stuff): Free stack memory. + (demangle_args): Push/Pop currently processed remembered type. + (do_type): Do not demangle a cyclic reference and push/pop + referenced remembered type. + +cherry-picked from commit of +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239143 138bc75d-0d04-0410-961f-82ee72b054a4 + +Upstream-Status: Backport [master] +CVE: CVE-2016-6131 +Signed-off-by: Yuanjie Huang <yuanjie.huang@windriver.com> +--- + libiberty/ChangeLog | 17 ++++++++ + libiberty/cplus-dem.c | 78 ++++++++++++++++++++++++++++++++--- + libiberty/testsuite/demangle-expected | 18 ++++++++ + 3 files changed, 108 insertions(+), 5 deletions(-) + +Index: gcc-6.4.0/libiberty/cplus-dem.c +=================================================================== +--- gcc-6.4.0.orig/libiberty/cplus-dem.c ++++ gcc-6.4.0/libiberty/cplus-dem.c +@@ -144,6 +144,9 @@ struct work_stuff + string* previous_argument; /* The last function argument demangled. */ + int nrepeats; /* The number of times to repeat the previous + argument. */ ++ int *proctypevec; /* Indices of currently processed remembered typevecs. */ ++ int proctypevec_size; ++ int nproctypes; + }; + + #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) +@@ -435,6 +438,10 @@ iterate_demangle_function (struct work_s + + static void remember_type (struct work_stuff *, const char *, int); + ++static void push_processed_type (struct work_stuff *, int); ++ ++static void pop_processed_type (struct work_stuff *); ++ + static void remember_Btype (struct work_stuff *, const char *, int, int); + + static int register_Btype (struct work_stuff *); +@@ -1301,6 +1308,10 @@ work_stuff_copy_to_from (struct work_stu + memcpy (to->btypevec[i], from->btypevec[i], len); + } + ++ if (from->proctypevec) ++ to->proctypevec = ++ XDUPVEC (int, from->proctypevec, from->proctypevec_size); ++ + if (from->ntmpl_args) + to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); + +@@ -1329,11 +1340,17 @@ delete_non_B_K_work_stuff (struct work_s + /* Discard the remembered types, if any. */ + + forget_types (work); +- if (work -> typevec != NULL) ++ if (work->typevec != NULL) + { +- free ((char *) work -> typevec); +- work -> typevec = NULL; +- work -> typevec_size = 0; ++ free ((char *) work->typevec); ++ work->typevec = NULL; ++ work->typevec_size = 0; ++ } ++ if (work->proctypevec != NULL) ++ { ++ free (work->proctypevec); ++ work->proctypevec = NULL; ++ work->proctypevec_size = 0; + } + if (work->tmpl_argvec) + { +@@ -3552,6 +3569,8 @@ static int + do_type (struct work_stuff *work, const char **mangled, string *result) + { + int n; ++ int i; ++ int is_proctypevec; + int done; + int success; + string decl; +@@ -3564,6 +3583,7 @@ do_type (struct work_stuff *work, const + + done = 0; + success = 1; ++ is_proctypevec = 0; + while (success && !done) + { + int member; +@@ -3616,8 +3636,15 @@ do_type (struct work_stuff *work, const + success = 0; + } + else ++ for (i = 0; i < work->nproctypes; i++) ++ if (work -> proctypevec [i] == n) ++ success = 0; ++ ++ if (success) + { +- remembered_type = work -> typevec[n]; ++ is_proctypevec = 1; ++ push_processed_type (work, n); ++ remembered_type = work->typevec[n]; + mangled = &remembered_type; + } + break; +@@ -3840,6 +3867,9 @@ do_type (struct work_stuff *work, const + string_delete (result); + string_delete (&decl); + ++ if (is_proctypevec) ++ pop_processed_type (work); ++ + if (success) + /* Assume an integral type, if we're not sure. */ + return (int) ((tk == tk_none) ? tk_integral : tk); +@@ -4252,6 +4282,41 @@ do_arg (struct work_stuff *work, const c + } + + static void ++push_processed_type (struct work_stuff *work, int typevec_index) ++{ ++ if (work->nproctypes >= work->proctypevec_size) ++ { ++ if (!work->proctypevec_size) ++ { ++ work->proctypevec_size = 4; ++ work->proctypevec = XNEWVEC (int, work->proctypevec_size); ++ } ++ else ++ { ++ if (work->proctypevec_size < 16) ++ /* Double when small. */ ++ work->proctypevec_size *= 2; ++ else ++ { ++ /* Grow slower when large. */ ++ if (work->proctypevec_size > (INT_MAX / 3) * 2) ++ xmalloc_failed (INT_MAX); ++ work->proctypevec_size = (work->proctypevec_size * 3 / 2); ++ } ++ work->proctypevec ++ = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size); ++ } ++ } ++ work->proctypevec [work->nproctypes++] = typevec_index; ++} ++ ++static void ++pop_processed_type (struct work_stuff *work) ++{ ++ work->nproctypes--; ++} ++ ++static void + remember_type (struct work_stuff *work, const char *start, int len) + { + char *tem; +@@ -4515,10 +4580,13 @@ demangle_args (struct work_stuff *work, + { + string_append (declp, ", "); + } ++ push_processed_type (work, t); + if (!do_arg (work, &tem, &arg)) + { ++ pop_processed_type (work); + return (0); + } ++ pop_processed_type (work); + if (PRINT_ARG_TYPES) + { + string_appends (declp, &arg); +Index: gcc-6.4.0/libiberty/testsuite/demangle-expected +=================================================================== +--- gcc-6.4.0.orig/libiberty/testsuite/demangle-expected ++++ gcc-6.4.0/libiberty/testsuite/demangle-expected +@@ -4491,3 +4491,21 @@ void eat<int*, Foo()::{lambda(auto:1*, a + + _Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_ + void eat<int*, void Bar<short>()::{lambda(short*, auto:1*, auto:2*)#2}>(int*&, void Bar<short>()::{lambda(short*, auto:1*, auto:2*)#2}&) ++# ++# Tests write access violation PR70926 ++ ++0__Ot2m02R5T0000500000 ++0__Ot2m02R5T0000500000 ++# ++ ++0__GT50000000000_ ++0__GT50000000000_ ++# ++ ++__t2m05B500000000000000000_ ++__t2m05B500000000000000000_ ++# ++# Tests stack overflow PR71696 ++ ++__10%0__S4_0T0T0 ++%0<>::%0(%0<>) diff --git a/meta/recipes-devtools/gcc/gcc-cross-canadian_6.2.bb b/meta/recipes-devtools/gcc/gcc-cross-canadian_6.4.bb index bf53c5cd78..bf53c5cd78 100644 --- a/meta/recipes-devtools/gcc/gcc-cross-canadian_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-cross-canadian_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-cross-initial_6.2.bb b/meta/recipes-devtools/gcc/gcc-cross-initial_6.4.bb index 4c73e5ce61..4c73e5ce61 100644 --- a/meta/recipes-devtools/gcc/gcc-cross-initial_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-cross-initial_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-cross_6.2.bb b/meta/recipes-devtools/gcc/gcc-cross_6.4.bb index b43cca0c52..b43cca0c52 100644 --- a/meta/recipes-devtools/gcc/gcc-cross_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-cross_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-crosssdk-initial_6.2.bb b/meta/recipes-devtools/gcc/gcc-crosssdk-initial_6.4.bb index fd90e1140f..fd90e1140f 100644 --- a/meta/recipes-devtools/gcc/gcc-crosssdk-initial_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-crosssdk-initial_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-crosssdk_6.2.bb b/meta/recipes-devtools/gcc/gcc-crosssdk_6.4.bb index 40a6c4feff..40a6c4feff 100644 --- a/meta/recipes-devtools/gcc/gcc-crosssdk_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-crosssdk_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-runtime.inc b/meta/recipes-devtools/gcc/gcc-runtime.inc index 15252f1a40..d5339b9a19 100644 --- a/meta/recipes-devtools/gcc/gcc-runtime.inc +++ b/meta/recipes-devtools/gcc/gcc-runtime.inc @@ -27,6 +27,8 @@ RUNTIMELIBITM_mipsisa64r6 = "" RUNTIMELIBITM_mipsisa64r6el = "" RUNTIMELIBITM_nios2 = "" RUNTIMELIBITM_microblaze = "" +RUNTIMELIBITM_riscv32 = "" +RUNTIMELIBITM_riscv64 = "" RUNTIMETARGET = "libssp libstdc++-v3 libgomp libatomic ${RUNTIMELIBITM} \ ${@bb.utils.contains_any('FORTRAN', [',fortran',',f77'], 'libquadmath', '', d)} \ diff --git a/meta/recipes-devtools/gcc/gcc-runtime_6.2.bb b/meta/recipes-devtools/gcc/gcc-runtime_6.4.bb index 8f31e7792e..8f31e7792e 100644 --- a/meta/recipes-devtools/gcc/gcc-runtime_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-runtime_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-sanitizers_6.2.bb b/meta/recipes-devtools/gcc/gcc-sanitizers_6.4.bb index 601f666023..601f666023 100644 --- a/meta/recipes-devtools/gcc/gcc-sanitizers_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-sanitizers_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc-source_6.2.bb b/meta/recipes-devtools/gcc/gcc-source_6.4.bb index b890fa33ea..b890fa33ea 100644 --- a/meta/recipes-devtools/gcc/gcc-source_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc-source_6.4.bb diff --git a/meta/recipes-devtools/gcc/gcc_6.2.bb b/meta/recipes-devtools/gcc/gcc_6.4.bb index b0a523cae2..b0a523cae2 100644 --- a/meta/recipes-devtools/gcc/gcc_6.2.bb +++ b/meta/recipes-devtools/gcc/gcc_6.4.bb diff --git a/meta/recipes-devtools/gcc/libgcc-initial_6.2.bb b/meta/recipes-devtools/gcc/libgcc-initial_6.4.bb index 19f253fce8..19f253fce8 100644 --- a/meta/recipes-devtools/gcc/libgcc-initial_6.2.bb +++ b/meta/recipes-devtools/gcc/libgcc-initial_6.4.bb diff --git a/meta/recipes-devtools/gcc/libgcc_6.2.bb b/meta/recipes-devtools/gcc/libgcc_6.4.bb index a5152f28e9..a5152f28e9 100644 --- a/meta/recipes-devtools/gcc/libgcc_6.2.bb +++ b/meta/recipes-devtools/gcc/libgcc_6.4.bb diff --git a/meta/recipes-devtools/gcc/libgfortran_6.2.bb b/meta/recipes-devtools/gcc/libgfortran_6.4.bb index 71dd8b4bdc..71dd8b4bdc 100644 --- a/meta/recipes-devtools/gcc/libgfortran_6.2.bb +++ b/meta/recipes-devtools/gcc/libgfortran_6.4.bb diff --git a/meta/recipes-devtools/pax-utils/pax-utils_1.1.6.bb b/meta/recipes-devtools/pax-utils/pax-utils_1.1.6.bb index 5cc546301c..d450a04215 100644 --- a/meta/recipes-devtools/pax-utils/pax-utils_1.1.6.bb +++ b/meta/recipes-devtools/pax-utils/pax-utils_1.1.6.bb @@ -7,8 +7,7 @@ HOMEPAGE = "http://www.gentoo.org/proj/en/hardened/pax-utils.xml" LICENSE = "GPLv2+" LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a" -SRC_URI = "http://gentoo.osuosl.org/distfiles/pax-utils-${PV}.tar.xz \ -" +SRC_URI = "https://dev.gentoo.org/~vapier/dist/pax-utils-${PV}.tar.xz" SRC_URI[md5sum] = "96f56a5a10ed50f2448c5ccebd27764f" SRC_URI[sha256sum] = "f5436c517bea40f7035ec29a6f34034c739b943f2e3a080d76df5dfd7fd41b12" diff --git a/meta/recipes-devtools/python/python.inc b/meta/recipes-devtools/python/python.inc index 79a431c7ea..a8c48e8f8d 100644 --- a/meta/recipes-devtools/python/python.inc +++ b/meta/recipes-devtools/python/python.inc @@ -16,6 +16,8 @@ SRC_URI[sha256sum] = "d7837121dd5652a05fef807c361909d255d173280c4e1a4ded94d73d80 # also, exclude pre-releases for both python 2.x and 3.x UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>2(\.\d+)+).tar" +CVE_PRODUCT = "python" + PYTHON_MAJMIN = "2.7" inherit autotools diff --git a/meta/recipes-devtools/python/python3/python-3.3-multilib.patch b/meta/recipes-devtools/python/python3/python-3.3-multilib.patch index 860190340e..08c4403cbf 100644 --- a/meta/recipes-devtools/python/python3/python-3.3-multilib.patch +++ b/meta/recipes-devtools/python/python3/python-3.3-multilib.patch @@ -1,16 +1,34 @@ -Upstream-Status: Pending - -get the sys.lib from python itself and do not use hardcoded value of 'lib' +From 51fe6f22d0ba113674fb358bd11d75fe659bd26e Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Tue, 14 May 2013 15:00:26 -0700 +Subject: [PATCH 01/13] get the sys.lib from python itself and do not use + hardcoded value of 'lib' 02/2015 Rebased for 3.4.2 +Upstream-Status: Pending Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com> -Index: Python-3.5.2/Include/pythonrun.h -=================================================================== ---- Python-3.5.2.orig/Include/pythonrun.h -+++ Python-3.5.2/Include/pythonrun.h +--- + Include/pythonrun.h | 3 +++ + Lib/distutils/command/install.py | 4 +++- + Lib/pydoc.py | 2 +- + Lib/site.py | 4 ++-- + Lib/sysconfig.py | 18 +++++++++--------- + Lib/trace.py | 4 ++-- + Makefile.pre.in | 7 +++++-- + Modules/getpath.c | 10 +++++++++- + Python/getplatform.c | 20 ++++++++++++++++++++ + Python/sysmodule.c | 4 ++++ + configure.ac | 35 +++++++++++++++++++++++++++++++++++ + setup.py | 9 ++++----- + 12 files changed, 97 insertions(+), 23 deletions(-) + +diff --git a/Include/pythonrun.h b/Include/pythonrun.h +index 9c2e813..2f79cb6 100644 +--- a/Include/pythonrun.h ++++ b/Include/pythonrun.h @@ -23,6 +23,9 @@ typedef struct { } PyCompilerFlags; #endif @@ -21,10 +39,10 @@ Index: Python-3.5.2/Include/pythonrun.h #ifndef Py_LIMITED_API PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); -Index: Python-3.5.2/Lib/distutils/command/install.py -=================================================================== ---- Python-3.5.2.orig/Lib/distutils/command/install.py -+++ Python-3.5.2/Lib/distutils/command/install.py +diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py +index 67db007..b46b45b 100644 +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py @@ -19,6 +19,8 @@ from site import USER_BASE from site import USER_SITE HAS_USER_SITE = True @@ -43,10 +61,10 @@ Index: Python-3.5.2/Lib/distutils/command/install.py 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', 'scripts': '$base/bin', 'data' : '$base', -Index: Python-3.5.2/Lib/pydoc.py -=================================================================== ---- Python-3.5.2.orig/Lib/pydoc.py -+++ Python-3.5.2/Lib/pydoc.py +diff --git a/Lib/pydoc.py b/Lib/pydoc.py +index 3ca08c9..6528730 100755 +--- a/Lib/pydoc.py ++++ b/Lib/pydoc.py @@ -384,7 +384,7 @@ class Doc: docmodule = docclass = docroutine = docother = docproperty = docdata = fail @@ -56,10 +74,75 @@ Index: Python-3.5.2/Lib/pydoc.py "python%d.%d" % sys.version_info[:2])): """Return the location of module docs or None""" -Index: Python-3.5.2/Lib/trace.py -=================================================================== ---- Python-3.5.2.orig/Lib/trace.py -+++ Python-3.5.2/Lib/trace.py +diff --git a/Lib/site.py b/Lib/site.py +index 3f78ef5..511931e 100644 +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -303,12 +303,12 @@ def getsitepackages(prefixes=None): + seen.add(prefix) + + if os.sep == '/': +- sitepackages.append(os.path.join(prefix, "lib", ++ sitepackages.append(os.path.join(prefix, sys.lib, + "python" + sys.version[:3], + "site-packages")) + else: + sitepackages.append(prefix) +- sitepackages.append(os.path.join(prefix, "lib", "site-packages")) ++ sitepackages.append(os.path.join(prefix, sys.lib, "site-packages")) + if sys.platform == "darwin": + # for framework builds *only* we add the standard Apple + # locations. +diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py +index 9c34be0..3d1181a 100644 +--- a/Lib/sysconfig.py ++++ b/Lib/sysconfig.py +@@ -20,10 +20,10 @@ __all__ = [ + + _INSTALL_SCHEMES = { + 'posix_prefix': { +- 'stdlib': '{installed_base}/lib/python{py_version_short}', +- 'platstdlib': '{platbase}/lib/python{py_version_short}', ++ 'stdlib': '{installed_base}/'+sys.lib+'/python{py_version_short}', ++ 'platstdlib': '{platbase}/'+sys.lib+'/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', +- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{platbase}/'+sys.lib+'/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': +@@ -32,10 +32,10 @@ _INSTALL_SCHEMES = { + 'data': '{base}', + }, + 'posix_home': { +- 'stdlib': '{installed_base}/lib/python', +- 'platstdlib': '{base}/lib/python', ++ 'stdlib': '{installed_base}/'+sys.lib+'/python', ++ 'platstdlib': '{base}/'+sys.lib+'/python', + 'purelib': '{base}/lib/python', +- 'platlib': '{base}/lib/python', ++ 'platlib': '{base}/'+sys.lib+'/python', + 'include': '{installed_base}/include/python', + 'platinclude': '{installed_base}/include/python', + 'scripts': '{base}/bin', +@@ -61,10 +61,10 @@ _INSTALL_SCHEMES = { + 'data': '{userbase}', + }, + 'posix_user': { +- 'stdlib': '{userbase}/lib/python{py_version_short}', +- 'platstdlib': '{userbase}/lib/python{py_version_short}', ++ 'stdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', ++ 'platstdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', +- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{userbase}/'+sys.lib+'/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', +diff --git a/Lib/trace.py b/Lib/trace.py +index f108266..7fd83f2 100755 +--- a/Lib/trace.py ++++ b/Lib/trace.py @@ -749,10 +749,10 @@ def main(argv=None): # should I also call expanduser? (after all, could use $HOME) @@ -73,11 +156,11 @@ Index: Python-3.5.2/Lib/trace.py "python" + sys.version[:3])) s = os.path.normpath(s) ignore_dirs.append(s) -Index: Python-3.5.2/Makefile.pre.in -=================================================================== ---- Python-3.5.2.orig/Makefile.pre.in -+++ Python-3.5.2/Makefile.pre.in -@@ -106,6 +106,8 @@ PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 109f402..61a41e2 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -106,6 +106,8 @@ PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARE # Machine-dependent subdirectories MACHDEP= @MACHDEP@ @@ -95,7 +178,7 @@ Index: Python-3.5.2/Makefile.pre.in ABIFLAGS= @ABIFLAGS@ # Detailed destination directories -@@ -755,6 +757,7 @@ Modules/getpath.o: $(srcdir)/Modules/get +@@ -755,6 +757,7 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile -DEXEC_PREFIX='"$(exec_prefix)"' \ -DVERSION='"$(VERSION)"' \ -DVPATH='"$(VPATH)"' \ @@ -103,7 +186,7 @@ Index: Python-3.5.2/Makefile.pre.in -o $@ $(srcdir)/Modules/getpath.c Programs/python.o: $(srcdir)/Programs/python.c -@@ -835,7 +838,7 @@ $(OPCODE_H): $(srcdir)/Lib/opcode.py $(O +@@ -835,7 +838,7 @@ $(OPCODE_H): $(srcdir)/Lib/opcode.py $(OPCODE_H_SCRIPT) Python/compile.o Python/symtable.o Python/ast.o: $(GRAMMAR_H) $(AST_H) Python/getplatform.o: $(srcdir)/Python/getplatform.c @@ -112,10 +195,10 @@ Index: Python-3.5.2/Makefile.pre.in Python/importdl.o: $(srcdir)/Python/importdl.c $(CC) -c $(PY_CORE_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c -Index: Python-3.5.2/Modules/getpath.c -=================================================================== ---- Python-3.5.2.orig/Modules/getpath.c -+++ Python-3.5.2/Modules/getpath.c +diff --git a/Modules/getpath.c b/Modules/getpath.c +index 18deb60..a01c3f8 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c @@ -105,6 +105,13 @@ #error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined" #endif @@ -147,10 +230,10 @@ Index: Python-3.5.2/Modules/getpath.c if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { Py_FatalError( -Index: Python-3.5.2/Python/getplatform.c -=================================================================== ---- Python-3.5.2.orig/Python/getplatform.c -+++ Python-3.5.2/Python/getplatform.c +diff --git a/Python/getplatform.c b/Python/getplatform.c +index 6899140..66a49c6 100644 +--- a/Python/getplatform.c ++++ b/Python/getplatform.c @@ -10,3 +10,23 @@ Py_GetPlatform(void) { return PLATFORM; @@ -175,10 +258,10 @@ Index: Python-3.5.2/Python/getplatform.c +{ + return LIB; +} -Index: Python-3.5.2/Python/sysmodule.c -=================================================================== ---- Python-3.5.2.orig/Python/sysmodule.c -+++ Python-3.5.2/Python/sysmodule.c +diff --git a/Python/sysmodule.c b/Python/sysmodule.c +index 8d7e05a..d9dee0f 100644 +--- a/Python/sysmodule.c ++++ b/Python/sysmodule.c @@ -1790,6 +1790,10 @@ _PySys_Init(void) PyUnicode_FromString(Py_GetCopyright())); SET_SYS_FROM_STRING("platform", @@ -190,93 +273,10 @@ Index: Python-3.5.2/Python/sysmodule.c SET_SYS_FROM_STRING("executable", PyUnicode_FromWideChar( Py_GetProgramFullPath(), -1)); -Index: Python-3.5.2/setup.py -=================================================================== ---- Python-3.5.2.orig/setup.py -+++ Python-3.5.2/setup.py -@@ -495,7 +495,7 @@ class PyBuildExt(build_ext): - # directories (i.e. '.' and 'Include') must be first. See issue - # 10520. - if not cross_compiling: -- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') -+ add_dir_to_list(self.compiler.library_dirs, os.path.join('/usr/local', sys.lib)) - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # only change this for cross builds for 3.3, issues on Mageia - if cross_compiling: -@@ -553,8 +553,7 @@ class PyBuildExt(build_ext): - # be assumed that no additional -I,-L directives are needed. - if not cross_compiling: - lib_dirs = self.compiler.library_dirs + [ -- '/lib64', '/usr/lib64', -- '/lib', '/usr/lib', -+ '/' + sys.lib, '/usr/' + sys.lib, - ] - inc_dirs = self.compiler.include_dirs + ['/usr/include'] - else: -@@ -746,11 +745,11 @@ class PyBuildExt(build_ext): - elif curses_library: - readline_libs.append(curses_library) - elif self.compiler.find_library_file(lib_dirs + -- ['/usr/lib/termcap'], -+ ['/usr/'+sys.lib+'/termcap'], - 'termcap'): - readline_libs.append('termcap') - exts.append( Extension('readline', ['readline.c'], -- library_dirs=['/usr/lib/termcap'], -+ library_dirs=['/usr/'+sys.lib+'/termcap'], - extra_link_args=readline_extra_link_args, - libraries=readline_libs) ) - else: -Index: Python-3.5.2/Lib/sysconfig.py -=================================================================== ---- Python-3.5.2.orig/Lib/sysconfig.py -+++ Python-3.5.2/Lib/sysconfig.py -@@ -20,10 +20,10 @@ __all__ = [ - - _INSTALL_SCHEMES = { - 'posix_prefix': { -- 'stdlib': '{installed_base}/lib/python{py_version_short}', -- 'platstdlib': '{platbase}/lib/python{py_version_short}', -+ 'stdlib': '{installed_base}/'+sys.lib+'/python{py_version_short}', -+ 'platstdlib': '{platbase}/'+sys.lib+'/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', -- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': -@@ -32,10 +32,10 @@ _INSTALL_SCHEMES = { - 'data': '{base}', - }, - 'posix_home': { -- 'stdlib': '{installed_base}/lib/python', -- 'platstdlib': '{base}/lib/python', -+ 'stdlib': '{installed_base}/'+sys.lib+'/python', -+ 'platstdlib': '{base}/'+sys.lib+'/python', - 'purelib': '{base}/lib/python', -- 'platlib': '{base}/lib/python', -+ 'platlib': '{base}/'+sys.lib+'/python', - 'include': '{installed_base}/include/python', - 'platinclude': '{installed_base}/include/python', - 'scripts': '{base}/bin', -@@ -61,10 +61,10 @@ _INSTALL_SCHEMES = { - 'data': '{userbase}', - }, - 'posix_user': { -- 'stdlib': '{userbase}/lib/python{py_version_short}', -- 'platstdlib': '{userbase}/lib/python{py_version_short}', -+ 'stdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', -+ 'platstdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', -- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', -+ 'platlib': '{userbase}/'+sys.lib+'/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', -Index: Python-3.5.2/configure.ac -=================================================================== ---- Python-3.5.2.orig/configure.ac -+++ Python-3.5.2/configure.ac +diff --git a/configure.ac b/configure.ac +index 707324d..e8d59a3 100644 +--- a/configure.ac ++++ b/configure.ac @@ -883,6 +883,41 @@ PLATDIR=plat-$MACHDEP AC_SUBST(PLATDIR) AC_SUBST(PLATFORM_TRIPLET) @@ -319,3 +319,43 @@ Index: Python-3.5.2/configure.ac AC_MSG_CHECKING([for -Wl,--no-as-needed]) save_LDFLAGS="$LDFLAGS" +diff --git a/setup.py b/setup.py +index 6d26deb..7b14215 100644 +--- a/setup.py ++++ b/setup.py +@@ -495,7 +495,7 @@ class PyBuildExt(build_ext): + # directories (i.e. '.' and 'Include') must be first. See issue + # 10520. + if not cross_compiling: +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') ++ add_dir_to_list(self.compiler.library_dirs, os.path.join('/usr/local', sys.lib)) + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + # only change this for cross builds for 3.3, issues on Mageia + if cross_compiling: +@@ -553,8 +553,7 @@ class PyBuildExt(build_ext): + # be assumed that no additional -I,-L directives are needed. + if not cross_compiling: + lib_dirs = self.compiler.library_dirs + [ +- '/lib64', '/usr/lib64', +- '/lib', '/usr/lib', ++ '/' + sys.lib, '/usr/' + sys.lib, + ] + inc_dirs = self.compiler.include_dirs + ['/usr/include'] + else: +@@ -746,11 +745,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(lib_dirs + +- ['/usr/lib/termcap'], ++ ['/usr/'+sys.lib+'/termcap'], + 'termcap'): + readline_libs.append('termcap') + exts.append( Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib/termcap'], ++ library_dirs=['/usr/'+sys.lib+'/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs) ) + else: +-- +2.11.0 + diff --git a/meta/recipes-devtools/qemu/qemu/memfd.patch b/meta/recipes-devtools/qemu/qemu/memfd.patch new file mode 100644 index 0000000000..62e8d3800b --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/memfd.patch @@ -0,0 +1,57 @@ +Upstream-Status: Backport +Signed-off-by: Ross Burton <ross.burton@intel.com> + +From 75e5b70e6b5dcc4f2219992d7cffa462aa406af0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonzini@redhat.com> +Date: Tue, 28 Nov 2017 11:51:27 +0100 +Subject: [PATCH] memfd: fix configure test +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Recent glibc added memfd_create in sys/mman.h. This conflicts with +the definition in util/memfd.c: + + /builddir/build/BUILD/qemu-2.11.0-rc1/util/memfd.c:40:12: error: static declaration of memfd_create follows non-static declaration + +Fix the configure test, and remove the sys/memfd.h inclusion since the +file actually does not exist---it is a typo in the memfd_create(2) man +page. + +Cc: Marc-André Lureau <marcandre.lureau@redhat.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + configure | 2 +- + util/memfd.c | 4 +--- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/configure b/configure +index 9c8aa5a98b..99ccc1725a 100755 +--- a/configure ++++ b/configure +@@ -3923,7 +3923,7 @@ fi + # check if memfd is supported + memfd=no + cat > $TMPC << EOF +-#include <sys/memfd.h> ++#include <sys/mman.h> + + int main(void) + { +diff --git a/util/memfd.c b/util/memfd.c +index 4571d1aba8..412e94a405 100644 +--- a/util/memfd.c ++++ b/util/memfd.c +@@ -31,9 +31,7 @@ + + #include "qemu/memfd.h" + +-#ifdef CONFIG_MEMFD +-#include <sys/memfd.h> +-#elif defined CONFIG_LINUX ++#if defined CONFIG_LINUX && !defined CONFIG_MEMFD + #include <sys/syscall.h> + #include <asm/unistd.h> + +-- +2.11.0 diff --git a/meta/recipes-devtools/qemu/qemu_2.7.0.bb b/meta/recipes-devtools/qemu/qemu_2.7.0.bb index 85aadecf09..65ae539dc4 100644 --- a/meta/recipes-devtools/qemu/qemu_2.7.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.7.0.bb @@ -14,6 +14,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ file://0003-fix-CVE-2016-7908.patch \ file://0004-fix-CVE-2016-7909.patch \ file://04b33e21866412689f18b7ad6daf0a54d8f959a7.patch \ + file://memfd.patch \ " SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" diff --git a/meta/recipes-devtools/ruby/ruby.inc b/meta/recipes-devtools/ruby/ruby.inc index fde67e9407..d71989889e 100644 --- a/meta/recipes-devtools/ruby/ruby.inc +++ b/meta/recipes-devtools/ruby/ruby.inc @@ -8,10 +8,10 @@ HOMEPAGE = "http://www.ruby-lang.org/" SECTION = "devel/ruby" LICENSE = "Ruby | BSD | GPLv2" LIC_FILES_CHKSUM = "\ - file://COPYING;md5=837b32593517ae48b9c3b5c87a5d288c \ + file://COPYING;md5=8a960b08d972f43f91ae84a6f00dcbfb \ file://BSDL;md5=19aaf65c88a40b508d17ae4be539c4b5\ file://GPL;md5=b234ee4d69f5fce4486a80fdaf4a4263\ - file://LEGAL;md5=c440adb575ba4e6e2344c2630b6a5584\ + file://LEGAL;md5=daf349ad59dd19bd8c919171bff3c5d6 \ " DEPENDS = "ruby-native zlib openssl tcl libyaml db gdbm readline" @@ -22,6 +22,7 @@ SRC_URI = "http://cache.ruby-lang.org/pub/ruby/${SHRT_VER}/ruby-${PV}.tar.gz \ file://extmk.patch \ file://0002-Obey-LDFLAGS-for-the-link-of-libruby.patch \ " +UPSTREAM_CHECK_URI = "https://www.ruby-lang.org/en/downloads/" inherit autotools diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch b/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch deleted file mode 100644 index 2b8772ba41..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2016-7798.patch +++ /dev/null @@ -1,164 +0,0 @@ -cipher: don't set dummy encryption key in Cipher#initialize -Remove the encryption key initialization from Cipher#initialize. This -is effectively a revert of r32723 ("Avoid possible SEGV from AES -encryption/decryption", 2011-07-28). - -r32723, which added the key initialization, was a workaround for -Ruby Bug #2768. For some certain ciphers, calling EVP_CipherUpdate() -before setting an encryption key caused segfault. It was not a problem -until OpenSSL implemented GCM mode - the encryption key could be -overridden by repeated calls of EVP_CipherInit_ex(). But, it is not the -case for AES-GCM ciphers. Setting a key, an IV, a key, in this order -causes the IV to be reset to an all-zero IV. - -The problem of Bug #2768 persists on the current versions of OpenSSL. -So, make Cipher#update raise an exception if a key is not yet set by the -user. Since encrypting or decrypting without key does not make any -sense, this should not break existing applications. - -Users can still call Cipher#key= and Cipher#iv= multiple times with -their own responsibility. - -Reference: https://bugs.ruby-lang.org/issues/2768 -Reference: https://bugs.ruby-lang.org/issues/8221 - -Upstream-Status: Backport -CVE: CVE-2016-7798 - -Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> - -Index: ruby-2.2.2/ext/openssl/ossl_cipher.c -=================================================================== ---- ruby-2.2.2.orig/ext/openssl/ossl_cipher.c -+++ ruby-2.2.2/ext/openssl/ossl_cipher.c -@@ -35,6 +35,7 @@ - */ - VALUE cCipher; - VALUE eCipherError; -+static ID id_key_set; - - static VALUE ossl_cipher_alloc(VALUE klass); - static void ossl_cipher_free(void *ptr); -@@ -119,7 +120,6 @@ ossl_cipher_initialize(VALUE self, VALUE - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *cipher; - char *name; -- unsigned char key[EVP_MAX_KEY_LENGTH]; - - name = StringValuePtr(str); - GetCipherInit(self, ctx); -@@ -131,14 +131,7 @@ ossl_cipher_initialize(VALUE self, VALUE - if (!(cipher = EVP_get_cipherbyname(name))) { - ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name); - } -- /* -- * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows -- * uninitialized key, but other EVPs (such as AES) does not allow it. -- * Calling EVP_CipherUpdate() without initializing key causes SEGV so we -- * set the data filled with "\0" as the key by default. -- */ -- memset(key, 0, EVP_MAX_KEY_LENGTH); -- if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1) -+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - - return self; -@@ -256,6 +249,8 @@ ossl_cipher_init(int argc, VALUE *argv, - if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { - ossl_raise(eCipherError, NULL); - } -+ if (p_key) -+ rb_ivar_set(self, id_key_set, Qtrue); - - return self; - } -@@ -343,6 +338,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VAL - OPENSSL_cleanse(key, sizeof key); - OPENSSL_cleanse(iv, sizeof iv); - -+ rb_ivar_set(self, id_key_set, Qtrue); -+ - return Qnil; - } - -@@ -396,6 +393,9 @@ ossl_cipher_update(int argc, VALUE *argv - - rb_scan_args(argc, argv, "11", &data, &str); - -+ if (!RTEST(rb_attr_get(self, id_key_set))) -+ ossl_raise(eCipherError, "key not set"); -+ - StringValue(data); - in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LEN(data)) == 0) -@@ -495,6 +495,8 @@ ossl_cipher_set_key(VALUE self, VALUE ke - if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) - ossl_raise(eCipherError, NULL); - -+ rb_ivar_set(self, id_key_set, Qtrue); -+ - return key; - } - -@@ -1013,5 +1015,7 @@ Init_ossl_cipher(void) - rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); - rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); - rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); -+ -+ id_key_set = rb_intern_const("key_set"); - } - -Index: ruby-2.2.2/test/openssl/test_cipher.rb -=================================================================== ---- ruby-2.2.2.orig/test/openssl/test_cipher.rb -+++ ruby-2.2.2/test/openssl/test_cipher.rb -@@ -80,6 +80,7 @@ class OpenSSL::TestCipher < Test::Unit:: - - def test_empty_data - @c1.encrypt -+ @c1.random_key - assert_raise(ArgumentError){ @c1.update("") } - end - -@@ -127,13 +128,10 @@ class OpenSSL::TestCipher < Test::Unit:: - assert_equal(pt, c2.update(ct) + c2.final) - } - end -- -- def test_AES_crush -- 500.times do -- assert_nothing_raised("[Bug #2768]") do -- # it caused OpenSSL SEGV by uninitialized key -- OpenSSL::Cipher::AES128.new("ECB").update "." * 17 -- end -+ def test_update_raise_if_key_not_set -+ assert_raise(OpenSSL::Cipher::CipherError) do -+ # it caused OpenSSL SEGV by uninitialized key [Bug #2768] -+ OpenSSL::Cipher::AES128.new("ECB").update "." * 17 - end - end - end -@@ -236,6 +234,23 @@ class OpenSSL::TestCipher < Test::Unit:: - end - - end -+ def test_aes_gcm_key_iv_order_issue -+ pt = "[ruby/openssl#49]" -+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt -+ cipher.key = "x" * 16 -+ cipher.iv = "a" * 12 -+ ct1 = cipher.update(pt) << cipher.final -+ tag1 = cipher.auth_tag -+ -+ cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt -+ cipher.iv = "a" * 12 -+ cipher.key = "x" * 16 -+ ct2 = cipher.update(pt) << cipher.final -+ tag2 = cipher.auth_tag -+ -+ assert_equal ct1, ct2 -+ assert_equal tag1, tag2 -+ end if has_cipher?("aes-128-gcm") - - private - diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch deleted file mode 100644 index cbcd18c788..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 1648afef33c1d97fb203c82291b8a61269e85d3b Mon Sep 17 00:00:00 2001 -From: Kazuki Yamaguchi <k@rhe.jp> -Date: Mon, 19 Sep 2016 15:38:44 +0900 -Subject: [PATCH] asn1: fix out-of-bounds read in decoding constructed objects - -OpenSSL::ASN1.{decode,decode_all,traverse} have a bug of out-of-bounds -read. int_ossl_asn1_decode0_cons() does not give the correct available -length to ossl_asn1_decode() when decoding the inner components of a -constructed object. This can cause out-of-bounds read if a crafted input -given. - -Reference: https://hackerone.com/reports/170316 - -Upstream-Status: Backport -CVE: CVE-2017-14033 - -Signed-off-by: Rajkumar Veer<rveer@mvista.com> ---- - ext/openssl/ossl_asn1.c | 13 ++++++------- - test/test_asn1.rb | 23 +++++++++++++++++++++++ - 2 files changed, 29 insertions(+), 7 deletions(-) ---- a/ext/openssl/ossl_asn1.c -+++ b/ext/openssl/ossl_asn1.c -@@ -871,19 +871,18 @@ - { - VALUE value, asn1data, ary; - int infinite; -- long off = *offset; -+ long available_len, off = *offset; - - infinite = (j == 0x21); - ary = rb_ary_new(); - -- while (length > 0 || infinite) { -+ available_len = infinite ? max_len : length; -+ while (available_len > 0 ) { - long inner_read = 0; -- value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read); -+ value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); - *num_read += inner_read; -- max_len -= inner_read; -+ available_len -= inner_read; - rb_ary_push(ary, value); -- if (length > 0) -- length -= inner_read; - - if (infinite && - NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC && -@@ -974,7 +973,7 @@ - if(j & V_ASN1_CONSTRUCTED) { - *pp += hlen; - off += hlen; -- asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read); -+ asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); - inner_read += hlen; - } - else { ---- a/test/openssl/test_asn1.rb -+++ b/test/openssl/test_asn1.rb -@@ -595,6 +595,29 @@ - assert_equal(false, asn1.value[3].infinite_length) - end - -+ def test_decode_constructed_overread -+ test = %w{ 31 06 31 02 30 02 05 00 } -+ # ^ <- invalid -+ raw = [test.join].pack("H*") -+ ret = [] -+ assert_raise(OpenSSL::ASN1::ASN1Error) { -+ OpenSSL::ASN1.traverse(raw) { |x| ret << x } -+ } -+ assert_equal 2, ret.size -+ assert_equal 17, ret[0][6] -+ assert_equal 17, ret[1][6] -+ -+ test = %w{ 31 80 30 03 00 00 } -+ # ^ <- invalid -+ raw = [test.join].pack("H*") -+ ret = [] -+ assert_raise(OpenSSL::ASN1::ASN1Error) { -+ OpenSSL::ASN1.traverse(raw) { |x| ret << x } -+ } -+ assert_equal 1, ret.size -+ assert_equal 17, ret[0][6] -+ end -+ - private - - def assert_universal(tag, asn1) diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch deleted file mode 100644 index 073d214d88..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 8f782fd8e181d9cfe9387ded43a5ca9692266b85 Mon Sep 17 00:00:00 2001 -From: Florian Frank <flori@ping.de> -Date: Thu, 2 Mar 2017 12:12:33 +0100 -Subject: [PATCH] Fix arbitrary heap exposure problem - -Upstream-Status: Backport -CVE: CVE-2017-14064 - -Signed-off-by: Rajkumar Veer<rveer@mvista.com> ---- - ext/json/ext/generator/generator.c | 12 ++++++------ - ext/json/ext/generator/generator.h | 1 - - 2 files changed, 6 insertions(+), 7 deletions(-) ---- a/ext/json/generator/generator.c -+++ b/ext/json/generator/generator.c -@@ -301,7 +301,7 @@ - char *result; - if (len <= 0) return NULL; - result = ALLOC_N(char, len); -- memccpy(result, ptr, 0, len); -+ memcpy(result, ptr, len); - return result; - } - -@@ -1055,7 +1055,7 @@ - } - } else { - if (state->indent) ruby_xfree(state->indent); -- state->indent = strdup(RSTRING_PTR(indent)); -+ state->indent = fstrndup(RSTRING_PTR(indent), len); - state->indent_len = len; - } - return Qnil; -@@ -1093,7 +1093,7 @@ - } - } else { - if (state->space) ruby_xfree(state->space); -- state->space = strdup(RSTRING_PTR(space)); -+ state->space = fstrndup(RSTRING_PTR(space), len); - state->space_len = len; - } - return Qnil; -@@ -1129,7 +1129,7 @@ - } - } else { - if (state->space_before) ruby_xfree(state->space_before); -- state->space_before = strdup(RSTRING_PTR(space_before)); -+ state->space_before = fstrndup(RSTRING_PTR(space_before), len); - state->space_before_len = len; - } - return Qnil; -@@ -1166,7 +1166,7 @@ - } - } else { - if (state->object_nl) ruby_xfree(state->object_nl); -- state->object_nl = strdup(RSTRING_PTR(object_nl)); -+ state->object_nl = fstrndup(RSTRING_PTR(object_nl), len); - state->object_nl_len = len; - } - return Qnil; -@@ -1201,7 +1201,7 @@ - } - } else { - if (state->array_nl) ruby_xfree(state->array_nl); -- state->array_nl = strdup(RSTRING_PTR(array_nl)); -+ state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); - state->array_nl_len = len; - } - return Qnil; ---- a/ext/json/generator/generator.h -+++ b/ext/json/generator/generator.h -@@ -1,7 +1,6 @@ - #ifndef _GENERATOR_H_ - #define _GENERATOR_H_ - --#include <string.h> - #include <math.h> - #include <ctype.h> - diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-9226.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-9226.patch deleted file mode 100644 index fc783e8a15..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-9226.patch +++ /dev/null @@ -1,33 +0,0 @@ -commit f015fbdd95f76438cd86366467bb2b39870dd7c6 -Author: K.Kosako <kosako@sofnec.co.jp> -Date: Fri May 19 15:44:47 2017 +0900 - - fix #55 : Byte value expressed in octal must be smaller than 256 - -Upstream-Status: Backport - -CVE: CVE-2017-9226 -Signed-off-by: Thiruvadi Rajaraman <tajaraman@mvista.com> - -Index: ruby-2.2.5/regparse.c -=================================================================== ---- ruby-2.2.5.orig/regparse.c 2017-09-12 16:33:21.977835068 +0530 -+++ ruby-2.2.5/regparse.c 2017-09-12 16:34:40.987117744 +0530 -@@ -3222,7 +3222,7 @@ - PUNFETCH; - prev = p; - num = scan_unsigned_octal_number(&p, end, 3, enc); -- if (num < 0) return ONIGERR_TOO_BIG_NUMBER; -+ if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER; - if (p == prev) { /* can't read nothing. */ - num = 0; /* but, it's not error */ - } -@@ -3676,7 +3676,7 @@ - if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) { - prev = p; - num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc); -- if (num < 0) return ONIGERR_TOO_BIG_NUMBER; -+ if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER; - if (p == prev) { /* can't read nothing. */ - num = 0; /* but, it's not error */ - } diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-9227.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-9227.patch deleted file mode 100644 index f6eaefb7fd..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-9227.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 9690d3ab1f9bcd2db8cbe1fe3ee4a5da606b8814 -Author: K.Kosako <kosako@sofnec.co.jp> -Date: Tue May 23 16:15:35 2017 +0900 - - fix #58 : access to invalid address by reg->dmin value - -Upstream-Status: backport - -CVE: CVE-2017-9227 -Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> - -Index: ruby-2.2.5/regexec.c -=================================================================== ---- ruby-2.2.5.orig/regexec.c 2014-09-15 21:48:41.000000000 +0530 -+++ ruby-2.2.5/regexec.c 2017-08-30 12:18:04.054828426 +0530 -@@ -3678,6 +3678,8 @@ - } - else { - UChar *q = p + reg->dmin; -+ -+ if (q >= end) return 0; /* fail */ - while (p < q) p += enclen(reg->enc, p, end); - } - } diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-9228.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-9228.patch deleted file mode 100644 index dc911bb20b..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-9228.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 3b63d12038c8d8fc278e81c942fa9bec7c704c8b -Author: K.Kosako <kosako@sofnec.co.jp> -Date: Wed May 24 13:43:25 2017 +0900 - - fix #60 : invalid state(CCS_VALUE) in parse_char_class() - -Upstream-Status: Backport - -CVE: CVE-2017-9228 -Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> - -Index: ruby-2.2.5/regparse.c -=================================================================== ---- ruby-2.2.5.orig/regparse.c 2014-09-16 08:14:10.000000000 +0530 -+++ ruby-2.2.5/regparse.c 2017-08-30 11:58:25.774275722 +0530 -@@ -4458,7 +4458,9 @@ - } - } - -- *state = CCS_VALUE; -+ if (*state != CCS_START) -+ *state = CCS_VALUE; -+ - *type = CCV_CLASS; - return 0; - } diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-9229.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-9229.patch deleted file mode 100644 index 75bdfada57..0000000000 --- a/meta/recipes-devtools/ruby/ruby/CVE-2017-9229.patch +++ /dev/null @@ -1,36 +0,0 @@ -commit b690371bbf97794b4a1d3f295d4fb9a8b05d402d -Author: K.Kosako <kosako@sofnec.co.jp> -Date: Wed May 24 10:27:04 2017 +0900 - - fix #59 : access to invalid address by reg->dmax value - -Upstream-Status: Backport - -CVE: CVE-2017-9229 -Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> - -Index: ruby-2.2.5/regexec.c -=================================================================== ---- ruby-2.2.5.orig/regexec.c 2017-09-13 12:17:08.429254209 +0530 -+++ ruby-2.2.5/regexec.c 2017-09-13 12:24:03.365312311 +0530 -@@ -3763,6 +3763,12 @@ - } - else { - if (reg->dmax != ONIG_INFINITE_DISTANCE) { -+ if (p - str < reg->dmax) { -+ *low = (UChar* )str; -+ if (low_prev) -+ *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low, end); -+ } -+ else { - *low = p - reg->dmax; - if (*low > s) { - *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s, -@@ -3776,6 +3782,7 @@ - *low_prev = onigenc_get_prev_char_head(reg->enc, - (pprev ? pprev : str), *low, end); - } -+ } - } - } - /* no needs to adjust *high, *high is used as range check only */ diff --git a/meta/recipes-devtools/ruby/ruby/prevent-gc.patch b/meta/recipes-devtools/ruby/ruby/prevent-gc.patch deleted file mode 100644 index 2eaa955fba..0000000000 --- a/meta/recipes-devtools/ruby/ruby/prevent-gc.patch +++ /dev/null @@ -1,32 +0,0 @@ -Fix marshaling with gcc7. Based on upstream revision 57410: -https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57410 -https://github.com/ruby/ruby/commit/7c1b30a602ab109d8d5388d7dfb3c5b180ba24e1 -https://bugs.ruby-lang.org/issues/13150 - -with the upstream patches intent ported to Ruby 2.2.5 - -Upstream-Status: Backport - -Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> - -Index: ruby-2.2.5/marshal.c -=================================================================== ---- ruby-2.2.5.orig/marshal.c -+++ ruby-2.2.5/marshal.c -@@ -17,7 +17,6 @@ - #include "ruby/io.h" - #include "ruby/st.h" - #include "ruby/util.h" -- - #include <math.h> - #ifdef HAVE_FLOAT_H - #include <float.h> -@@ -985,7 +984,7 @@ marshal_dump(int argc, VALUE *argv) - VALUE obj, port, a1, a2; - int limit = -1; - struct dump_arg *arg; -- VALUE wrapper; /* used to avoid memory leak in case of exception */ -+ volatile VALUE wrapper; /* used to avoid memory leak in case of exception */ - - port = Qnil; - rb_scan_args(argc, argv, "12", &obj, &a1, &a2); diff --git a/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9224.patch b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9224.patch new file mode 100644 index 0000000000..848139b7e3 --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9224.patch @@ -0,0 +1,41 @@ +From 690313a061f7a4fa614ec5cc8368b4f2284e059b Mon Sep 17 00:00:00 2001 +From: "K.Kosako" <kosako@sofnec.co.jp> +Date: Tue, 23 May 2017 10:28:58 +0900 +Subject: [PATCH] fix #57 : DATA_ENSURE() check must be before data access + +--- + regexec.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- end of original header + +CVE: CVE-2017-9224 + +Context modified so that patch applies for version 2.4.1. + +Upstream-Status: Pending +Signed-off-by: Joe Slater <joe.slater@windriver.com> + + +diff --git a/regexec.c b/regexec.c +index 35fef11..d4e577d 100644 +--- a/regexec.c ++++ b/regexec.c +@@ -1473,14 +1473,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, + NEXT; + + CASE(OP_EXACT1) MOP_IN(OP_EXACT1); +-#if 0 + DATA_ENSURE(1); + if (*p != *s) goto fail; + p++; s++; +-#endif +- if (*p != *s++) goto fail; +- DATA_ENSURE(0); +- p++; + MOP_OUT; + break; + +-- +1.7.9.5 + diff --git a/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9226.patch b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9226.patch new file mode 100644 index 0000000000..0f2a4307cc --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9226.patch @@ -0,0 +1,41 @@ +From b4bf968ad52afe14e60a2dc8a95d3555c543353a Mon Sep 17 00:00:00 2001 +From: "K.Kosako" <kosako@sofnec.co.jp> +Date: Thu, 18 May 2017 17:05:27 +0900 +Subject: [PATCH] fix #55 : check too big code point value for single byte + value in next_state_val() + +--- + regparse.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- end of original header + +CVE: CVE-2017-9226 + +Add check for octal number bigger than 255. + +Upstream-Status: Pending +Signed-off-by: Joe Slater <joe.slater@windriver.com> + + +--- ruby-2.4.1.orig/regparse.c ++++ ruby-2.4.1/regparse.c +@@ -3644,7 +3644,7 @@ fetch_token(OnigToken* tok, UChar** src, + if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) { + prev = p; + num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc); +- if (num < 0) return ONIGERR_TOO_BIG_NUMBER; ++ if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER; + if (p == prev) { /* can't read nothing. */ + num = 0; /* but, it's not error */ + } +@@ -4450,6 +4450,9 @@ next_state_val(CClassNode* cc, CClassNod + switch (*state) { + case CCS_VALUE: + if (*type == CCV_SB) { ++ if (*vs > 0xff) ++ return ONIGERR_INVALID_CODE_POINT_VALUE; ++ + BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs)); + if (IS_NOT_NULL(asc_cc)) + BITSET_SET_BIT(asc_cc->bs, (int )(*vs)); diff --git a/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9227.patch b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9227.patch new file mode 100644 index 0000000000..85e7ccb369 --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9227.patch @@ -0,0 +1,32 @@ +From 9690d3ab1f9bcd2db8cbe1fe3ee4a5da606b8814 Mon Sep 17 00:00:00 2001 +From: "K.Kosako" <kosako@sofnec.co.jp> +Date: Tue, 23 May 2017 16:15:35 +0900 +Subject: [PATCH] fix #58 : access to invalid address by reg->dmin value + +--- + regexec.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- end of original header + +CVE: CVE-2017-9227 + +Upstream-Status: Inappropriate [not author] +Signed-off-by: Joe Slater <joe.slater@windriver.com> + +diff --git a/regexec.c b/regexec.c +index d4e577d..2fa0f3d 100644 +--- a/regexec.c ++++ b/regexec.c +@@ -3154,6 +3154,8 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s, + } + else { + UChar *q = p + reg->dmin; ++ ++ if (q >= end) return 0; /* fail */ + while (p < q) p += enclen(reg->enc, p, end); + } + } +-- +1.7.9.5 + diff --git a/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9228.patch b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9228.patch new file mode 100644 index 0000000000..d8bfba486c --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9228.patch @@ -0,0 +1,34 @@ +From 3b63d12038c8d8fc278e81c942fa9bec7c704c8b Mon Sep 17 00:00:00 2001 +From: "K.Kosako" <kosako@sofnec.co.jp> +Date: Wed, 24 May 2017 13:43:25 +0900 +Subject: [PATCH] fix #60 : invalid state(CCS_VALUE) in parse_char_class() + +--- + regparse.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- end of original header + +CVE: CVE-2017-9228 + +Upstream-Status: Inappropriate [not author] +Signed-off-by: Joe Slater <joe.slater@windriver.com> + +diff --git a/regparse.c b/regparse.c +index 69875fa..1988747 100644 +--- a/regparse.c ++++ b/regparse.c +@@ -4081,7 +4081,9 @@ next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type, + } + } + +- *state = CCS_VALUE; ++ if (*state != CCS_START) ++ *state = CCS_VALUE; ++ + *type = CCV_CLASS; + return 0; + } +-- +1.7.9.5 + diff --git a/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9229.patch b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9229.patch new file mode 100644 index 0000000000..6e765bf6dc --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/ruby-CVE-2017-9229.patch @@ -0,0 +1,59 @@ +From b690371bbf97794b4a1d3f295d4fb9a8b05d402d Mon Sep 17 00:00:00 2001 +From: "K.Kosako" <kosako@sofnec.co.jp> +Date: Wed, 24 May 2017 10:27:04 +0900 +Subject: [PATCH] fix #59 : access to invalid address by reg->dmax value + +--- + regexec.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +--- end of original header + +CVE: CVE-2017-9229 + +Upstream-Status: Inappropriate [not author] +Signed-off-by: Joe Slater <joe.slater@windriver.com> + +diff --git a/regexec.c b/regexec.c +index 49bcc50..c0626ef 100644 +--- a/regexec.c ++++ b/regexec.c +@@ -3756,18 +3756,25 @@ forward_search_range(regex_t* reg, const + } + else { + if (reg->dmax != ONIG_INFINITE_DISTANCE) { +- *low = p - reg->dmax; +- if (*low > s) { +- *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s, +- *low, end, (const UChar** )low_prev); +- if (low_prev && IS_NULL(*low_prev)) +- *low_prev = onigenc_get_prev_char_head(reg->enc, +- (pprev ? pprev : s), *low, end); ++ if (p - str < reg->dmax) { ++ *low = (UChar* )str; ++ if (low_prev) ++ *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low, end); + } + else { +- if (low_prev) +- *low_prev = onigenc_get_prev_char_head(reg->enc, +- (pprev ? pprev : str), *low, end); ++ *low = p - reg->dmax; ++ if (*low > s) { ++ *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s, ++ *low, end, (const UChar** )low_prev); ++ if (low_prev && IS_NULL(*low_prev)) ++ *low_prev = onigenc_get_prev_char_head(reg->enc, ++ (pprev ? pprev : s), *low, end); ++ } ++ else { ++ if (low_prev) ++ *low_prev = onigenc_get_prev_char_head(reg->enc, ++ (pprev ? pprev : str), *low, end); ++ } + } + } + } +-- +1.7.9.5 + diff --git a/meta/recipes-devtools/ruby/ruby_2.2.5.bb b/meta/recipes-devtools/ruby/ruby_2.4.3.bb index 750ddc690f..668bc96901 100644 --- a/meta/recipes-devtools/ruby/ruby_2.2.5.bb +++ b/meta/recipes-devtools/ruby/ruby_2.4.3.bb @@ -1,17 +1,15 @@ require ruby.inc -SRC_URI[md5sum] = "bd8e349d4fb2c75d90817649674f94be" -SRC_URI[sha256sum] = "30c4b31697a4ca4ea0c8db8ad30cf45e6690a0f09687e5d483c933c03ca335e3" - -SRC_URI += "file://prevent-gc.patch \ - file://CVE-2016-7798.patch \ - file://CVE-2017-9227.patch \ - file://CVE-2017-9228.patch \ - file://CVE-2017-9226.patch \ - file://CVE-2017-9229.patch \ - file://CVE-2017-14033.patch \ - file://CVE-2017-14064.patch \ -" +SRC_URI += " \ + file://ruby-CVE-2017-9224.patch \ + file://ruby-CVE-2017-9226.patch \ + file://ruby-CVE-2017-9227.patch \ + file://ruby-CVE-2017-9228.patch \ + file://ruby-CVE-2017-9229.patch \ + " + +SRC_URI[md5sum] = "a00e0d49b454f4c0e528e7852d642925" +SRC_URI[sha256sum] = "fd0375582c92045aa7d31854e724471fb469e11a4b08ff334d39052ccaaa3a98" # it's unknown to configure script, but then passed to extconf.rb # maybe it's not really needed as we're hardcoding the result with @@ -25,6 +23,8 @@ PACKAGECONFIG[valgrind] = "--with-valgrind=yes, --with-valgrind=no, valgrind" PACKAGECONFIG[gpm] = "--with-gmp=yes, --with-gmp=no, gmp" PACKAGECONFIG[ipv6] = ",--enable-wide-getaddrinfo," +EXTRA_AUTORECONF += "--exclude=aclocal" + EXTRA_OECONF = "\ --disable-versioned-paths \ --disable-rpath \ diff --git a/meta/recipes-devtools/unfs3/unfs3/0001-daemon.c-Libtirpc-porting-fixes.patch b/meta/recipes-devtools/unfs3/unfs3/0001-daemon.c-Libtirpc-porting-fixes.patch new file mode 100644 index 0000000000..6eee6748f9 --- /dev/null +++ b/meta/recipes-devtools/unfs3/unfs3/0001-daemon.c-Libtirpc-porting-fixes.patch @@ -0,0 +1,37 @@ +From c7a2a65d6c2a433312540c207860740d6e4e7629 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Sun, 11 Mar 2018 17:32:54 -0700 +Subject: [PATCH] daemon.c: Libtirpc porting fixes + +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- +Upstream-Status: Pending + + daemon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/daemon.c b/daemon.c +index 22f30f6..028a181 100644 +--- a/daemon.c ++++ b/daemon.c +@@ -117,7 +117,7 @@ void logmsg(int prio, const char *fmt, ...) + */ + struct in_addr get_remote(struct svc_req *rqstp) + { +- return (svc_getcaller(rqstp->rq_xprt))->sin_addr; ++ return ((struct sockaddr_in*)svc_getcaller(rqstp->rq_xprt))->sin_addr; + } + + /* +@@ -125,7 +125,7 @@ struct in_addr get_remote(struct svc_req *rqstp) + */ + short get_port(struct svc_req *rqstp) + { +- return (svc_getcaller(rqstp->rq_xprt))->sin_port; ++ return ((struct sockaddr_in*)svc_getcaller(rqstp->rq_xprt))->sin_port; + } + + /* +-- +2.16.2 + diff --git a/meta/recipes-devtools/unfs3/unfs3_0.9.22.r497.bb b/meta/recipes-devtools/unfs3/unfs3_0.9.22.r497.bb index e7574fb72a..0069425d23 100644 --- a/meta/recipes-devtools/unfs3/unfs3_0.9.22.r497.bb +++ b/meta/recipes-devtools/unfs3/unfs3_0.9.22.r497.bb @@ -9,9 +9,11 @@ RECIPE_UPSTREAM_DATE = "Oct 08, 2015" CHECK_DATE = "Dec 10, 2015" DEPENDS = "flex-native bison-native flex" -DEPENDS_append_libc-musl = " libtirpc" +DEPENDS += "libtirpc" DEPENDS_append_class-nativesdk = " flex-nativesdk" +ASNEEDED = "" + MOD_PV = "497" S = "${WORKDIR}/trunk" SRC_URI = "svn://svn.code.sf.net/p/unfs3/code;module=trunk;rev=${MOD_PV};protocol=http \ @@ -22,7 +24,8 @@ SRC_URI = "svn://svn.code.sf.net/p/unfs3/code;module=trunk;rev=${MOD_PV};protoco file://rename_fh_cache.patch \ file://relative_max_socket_path_len.patch \ file://tcp_no_delay.patch \ - " + file://0001-daemon.c-Libtirpc-porting-fixes.patch \ + " SRC_URI[md5sum] = "3687acc4ee992e536472365dd99712a7" SRC_URI[sha256sum] = "274b43ada9c6eea1da26eb7010d72889c5278984ba0b50dff4e093057d4d64f8" @@ -30,7 +33,8 @@ BBCLASSEXTEND = "native nativesdk" inherit autotools EXTRA_OECONF_append_class-native = " --sbindir=${bindir}" -CFLAGS_append_libc-musl = " -I${STAGING_INCDIR}/tirpc" +CFLAGS_append = " -I${STAGING_INCDIR}/tirpc" +LDFLAGS_append = " -ltirpc" # Turn off these header detects else the inode search # will walk entire file systems and this is a real problem |