Add the patches with real changes from the binutils 2.39 stable branch.
I am not aware that we ran into any of these problems, but I think it is
better to take the existing stable patches.
They were exported like this:
git format-patch binutils-2_39...origin/binutils-2_39-branch
I removed the patches changing the version numbers only.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- /dev/null
+From 9284b63ea39cecbfc1522d9e143ecb7727d77eb5 Mon Sep 17 00:00:00 2001
+From: Martin Liska <mliska@suse.cz>
+Date: Mon, 8 Aug 2022 13:22:26 +0200
+Subject: [PATCH 005/160] ld: fix NEWS typos
+
+ld/ChangeLog:
+
+ * NEWS: Fix 2 typos.
+---
+ ld/NEWS | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/ld/NEWS
++++ b/ld/NEWS
+@@ -27,10 +27,10 @@ Changes in 2.39:
+ --enable-warn-rwx-segments=no
+ will make --no-warn-rwx-segments enabled by default.
+
+- --enable-defaul-execstack=no
++ --enable-default-execstack=no
+ will stop the creation of an executable stack simply because an input file
+ is missing a .note.GNU-stack section, even on architectures where this
+- ehaviour is the default.
++ behaviour is the default.
+
+ * TYPE=<type> is now supported in an output section description to set the
+ section type value.
--- /dev/null
+From e8cf73215187b0c08679d726a5cc7c019fa3ea2e Mon Sep 17 00:00:00 2001
+From: Jan Beulich <jbeulich@suse.com>
+Date: Wed, 10 Aug 2022 10:34:22 +0200
+Subject: [PATCH 008/160] gas/Dwarf: properly skip zero-size functions
+
+PR gas/29451
+
+While out_debug_abbrev() properly skips such functions, out_debug_info()
+mistakenly didn't. It needs to calculate the high_pc expression ahead of
+time, in order to skip emitting any data for the function if the value
+is zero.
+
+The one case which would still leave a zero-size entry is when
+symbol_get_obj(symp)->size ends up evaluating to zero. I hope we can
+expect that to not be the case, otherwise we'd need to have a way to
+post-process .debug_info contents between resolving expressions and
+actually writing the data out to the file. Even then it wouldn't be
+entirely obvious in which way to alter the data.
+
+(cherry picked from commit d7abcbcea5ddd40a3bf28758b62f35933c59f996)
+---
+ gas/dwarf2dbg.c | 39 ++++++++++++++++++++-------------------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+--- a/gas/dwarf2dbg.c
++++ b/gas/dwarf2dbg.c
+@@ -2882,6 +2882,7 @@ out_debug_info (segT info_seg, segT abbr
+ {
+ const char *name;
+ size_t len;
++ expressionS size = { .X_op = O_constant };
+
+ /* Skip warning constructs (see above). */
+ if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
+@@ -2895,6 +2896,18 @@ out_debug_info (segT info_seg, segT abbr
+ if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp))
+ continue;
+
++#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
++ size.X_add_number = S_GET_SIZE (symp);
++ if (size.X_add_number == 0 && IS_ELF
++ && symbol_get_obj (symp)->size != NULL)
++ {
++ size.X_op = O_add;
++ size.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
++ }
++#endif
++ if (size.X_op == O_constant && size.X_add_number == 0)
++ continue;
++
+ subseg_set (str_seg, 0);
+ name_sym = symbol_temp_new_now_octets ();
+ name = S_GET_NAME (symp);
+@@ -2920,29 +2933,17 @@ out_debug_info (segT info_seg, segT abbr
+ emit_expr (&exp, sizeof_address);
+
+ /* DW_AT_high_pc */
+- exp.X_op = O_constant;
+-#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
+- exp.X_add_number = S_GET_SIZE (symp);
+- if (exp.X_add_number == 0 && IS_ELF
+- && symbol_get_obj (symp)->size != NULL)
+- {
+- exp.X_op = O_add;
+- exp.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
+- }
+-#else
+- exp.X_add_number = 0;
+-#endif
+ if (DWARF2_VERSION < 4)
+ {
+- if (exp.X_op == O_constant)
+- exp.X_op = O_symbol;
+- exp.X_add_symbol = symp;
+- emit_expr (&exp, sizeof_address);
++ if (size.X_op == O_constant)
++ size.X_op = O_symbol;
++ size.X_add_symbol = symp;
++ emit_expr (&size, sizeof_address);
+ }
+- else if (exp.X_op == O_constant)
+- out_uleb128 (exp.X_add_number);
++ else if (size.X_op == O_constant)
++ out_uleb128 (size.X_add_number);
+ else
+- emit_leb128_expr (symbol_get_value_expression (exp.X_op_symbol), 0);
++ emit_leb128_expr (symbol_get_value_expression (size.X_op_symbol), 0);
+ }
+
+ /* End of children. */
--- /dev/null
+From e3b5d935247084dca057dea72be61b063fe2357a Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Wed, 10 Aug 2022 10:38:52 +0930
+Subject: [PATCH 009/160] PR29462, internal error in relocate, at
+ powerpc.cc:10796
+
+Prior to the inline plt call support (commit 08be322439), the only
+local syms with plt entries were local ifunc symbols. There shouldn't
+be stubs for other local symbols so don't look for them. The patch
+also fixes minor bugs in get_reference_flags; Many relocs are valid
+only for ppc64 and a couple only for ppc32.
+
+ PR 29462
+ * powerpc.cc (Target_powerpc::Relocate::relocate): Rename
+ use_plt_offset to pltcal_to_direct, invert logic. For relocs
+ not used with inline plt sequences against local symbols, only
+ look for stubs when the symbol is an ifunc.
+ (Target_powerpc::Scan::get_reference_flags): Correct reloc
+ handling for relocs not valid for both 32-bit and 64-bit.
+
+(cherry picked from commit 6158b25f77db11712b84e6a4609898f2615ac749)
+---
+ gold/powerpc.cc | 129 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 75 insertions(+), 54 deletions(-)
+
+--- a/gold/powerpc.cc
++++ b/gold/powerpc.cc
+@@ -7675,22 +7675,18 @@ Target_powerpc<size, big_endian>::Scan::
+
+ switch (r_type)
+ {
++ case elfcpp::R_PPC64_TOC:
++ if (size != 64)
++ break;
++ // Fall through.
+ case elfcpp::R_POWERPC_NONE:
+ case elfcpp::R_POWERPC_GNU_VTINHERIT:
+ case elfcpp::R_POWERPC_GNU_VTENTRY:
+- case elfcpp::R_PPC64_TOC:
+ // No symbol reference.
+ break;
+
+ case elfcpp::R_PPC64_ADDR64:
+ case elfcpp::R_PPC64_UADDR64:
+- case elfcpp::R_POWERPC_ADDR32:
+- case elfcpp::R_POWERPC_UADDR32:
+- case elfcpp::R_POWERPC_ADDR16:
+- case elfcpp::R_POWERPC_UADDR16:
+- case elfcpp::R_POWERPC_ADDR16_LO:
+- case elfcpp::R_POWERPC_ADDR16_HI:
+- case elfcpp::R_POWERPC_ADDR16_HA:
+ case elfcpp::R_PPC64_ADDR16_HIGHER34:
+ case elfcpp::R_PPC64_ADDR16_HIGHERA34:
+ case elfcpp::R_PPC64_ADDR16_HIGHEST34:
+@@ -7700,6 +7696,16 @@ Target_powerpc<size, big_endian>::Scan::
+ case elfcpp::R_PPC64_D34_HI30:
+ case elfcpp::R_PPC64_D34_HA30:
+ case elfcpp::R_PPC64_D28:
++ if (size != 64)
++ break;
++ // Fall through.
++ case elfcpp::R_POWERPC_ADDR32:
++ case elfcpp::R_POWERPC_UADDR32:
++ case elfcpp::R_POWERPC_ADDR16:
++ case elfcpp::R_POWERPC_UADDR16:
++ case elfcpp::R_POWERPC_ADDR16_LO:
++ case elfcpp::R_POWERPC_ADDR16_HI:
++ case elfcpp::R_POWERPC_ADDR16_HA:
+ ref = Symbol::ABSOLUTE_REF;
+ break;
+
+@@ -7710,13 +7716,14 @@ Target_powerpc<size, big_endian>::Scan::
+ ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
+ break;
+
+- case elfcpp::R_PPC64_REL64:
+- case elfcpp::R_POWERPC_REL32:
+ case elfcpp::R_PPC_LOCAL24PC:
+- case elfcpp::R_POWERPC_REL16:
+- case elfcpp::R_POWERPC_REL16_LO:
+- case elfcpp::R_POWERPC_REL16_HI:
+- case elfcpp::R_POWERPC_REL16_HA:
++ if (size != 32)
++ break;
++ // Fall through.
++ ref = Symbol::RELATIVE_REF;
++ break;
++
++ case elfcpp::R_PPC64_REL64:
+ case elfcpp::R_PPC64_REL16_HIGH:
+ case elfcpp::R_PPC64_REL16_HIGHA:
+ case elfcpp::R_PPC64_REL16_HIGHER:
+@@ -7729,36 +7736,45 @@ Target_powerpc<size, big_endian>::Scan::
+ case elfcpp::R_PPC64_REL16_HIGHEST34:
+ case elfcpp::R_PPC64_REL16_HIGHESTA34:
+ case elfcpp::R_PPC64_PCREL28:
++ if (size != 64)
++ break;
++ // Fall through.
++ case elfcpp::R_POWERPC_REL32:
++ case elfcpp::R_POWERPC_REL16:
++ case elfcpp::R_POWERPC_REL16_LO:
++ case elfcpp::R_POWERPC_REL16_HI:
++ case elfcpp::R_POWERPC_REL16_HA:
+ ref = Symbol::RELATIVE_REF;
+ break;
+
++ case elfcpp::R_PPC_PLTREL24:
++ if (size != 32)
++ break;
++ ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
++ break;
++
+ case elfcpp::R_PPC64_REL24_NOTOC:
+- if (size == 32)
++ case elfcpp::R_PPC64_REL24_P9NOTOC:
++ case elfcpp::R_PPC64_PLT16_LO_DS:
++ case elfcpp::R_PPC64_PLTSEQ_NOTOC:
++ case elfcpp::R_PPC64_PLTCALL_NOTOC:
++ case elfcpp::R_PPC64_PLT_PCREL34:
++ case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
++ if (size != 64)
+ break;
+ // Fall through.
+- case elfcpp::R_PPC64_REL24_P9NOTOC:
+ case elfcpp::R_POWERPC_REL24:
+- case elfcpp::R_PPC_PLTREL24:
+ case elfcpp::R_POWERPC_REL14:
+ case elfcpp::R_POWERPC_REL14_BRTAKEN:
+ case elfcpp::R_POWERPC_REL14_BRNTAKEN:
+ case elfcpp::R_POWERPC_PLT16_LO:
+ case elfcpp::R_POWERPC_PLT16_HI:
+ case elfcpp::R_POWERPC_PLT16_HA:
+- case elfcpp::R_PPC64_PLT16_LO_DS:
+ case elfcpp::R_POWERPC_PLTSEQ:
+- case elfcpp::R_PPC64_PLTSEQ_NOTOC:
+ case elfcpp::R_POWERPC_PLTCALL:
+- case elfcpp::R_PPC64_PLTCALL_NOTOC:
+- case elfcpp::R_PPC64_PLT_PCREL34:
+- case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
+ ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
+ break;
+
+- case elfcpp::R_POWERPC_GOT16:
+- case elfcpp::R_POWERPC_GOT16_LO:
+- case elfcpp::R_POWERPC_GOT16_HI:
+- case elfcpp::R_POWERPC_GOT16_HA:
+ case elfcpp::R_PPC64_GOT16_DS:
+ case elfcpp::R_PPC64_GOT16_LO_DS:
+ case elfcpp::R_PPC64_GOT_PCREL34:
+@@ -7768,11 +7784,16 @@ Target_powerpc<size, big_endian>::Scan::
+ case elfcpp::R_PPC64_TOC16_HA:
+ case elfcpp::R_PPC64_TOC16_DS:
+ case elfcpp::R_PPC64_TOC16_LO_DS:
++ if (size != 64)
++ break;
++ // Fall through.
++ case elfcpp::R_POWERPC_GOT16:
++ case elfcpp::R_POWERPC_GOT16_LO:
++ case elfcpp::R_POWERPC_GOT16_HI:
++ case elfcpp::R_POWERPC_GOT16_HA:
+ ref = Symbol::RELATIVE_REF;
+ break;
+
+- case elfcpp::R_POWERPC_GOT_TPREL16:
+- case elfcpp::R_POWERPC_TLS:
+ case elfcpp::R_PPC64_TLSGD:
+ case elfcpp::R_PPC64_TLSLD:
+ case elfcpp::R_PPC64_TPREL34:
+@@ -7781,6 +7802,11 @@ Target_powerpc<size, big_endian>::Scan::
+ case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
+ case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
+ case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
++ if (size != 64)
++ break;
++ // Fall through.
++ case elfcpp::R_POWERPC_GOT_TPREL16:
++ case elfcpp::R_POWERPC_TLS:
+ ref = Symbol::TLS_REF;
+ break;
+
+@@ -10671,10 +10697,8 @@ Target_powerpc<size, big_endian>::Reloca
+ bool has_stub_value = false;
+ bool localentry0 = false;
+ unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
+- bool use_plt_offset
+- = (gsym != NULL
+- ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
+- : object->local_has_plt_offset(r_sym));
++ bool pltcall_to_direct = false;
++
+ if (is_plt16_reloc<size>(r_type)
+ || r_type == elfcpp::R_PPC64_PLT_PCREL34
+ || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC
+@@ -10688,21 +10712,18 @@ Target_powerpc<size, big_endian>::Reloca
+ // that the decision depends on the PLTCALL reloc, and we don't
+ // know the address of that instruction when processing others
+ // in the sequence. So the decision needs to be made in
+- // do_relax(). For now, don't optimise inline plt calls.
+- if (gsym)
+- use_plt_offset = gsym->has_plt_offset();
+- }
+- if (use_plt_offset
+- && !is_got_reloc(r_type)
+- && !is_plt16_reloc<size>(r_type)
+- && r_type != elfcpp::R_PPC64_PLT_PCREL34
+- && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC
+- && r_type != elfcpp::R_POWERPC_PLTSEQ
+- && r_type != elfcpp::R_POWERPC_PLTCALL
+- && r_type != elfcpp::R_PPC64_PLTSEQ_NOTOC
+- && r_type != elfcpp::R_PPC64_PLTCALL_NOTOC
+- && (!psymval->is_ifunc_symbol()
+- || Scan::reloc_needs_plt_for_ifunc(target, object, r_type, false)))
++ // do_relax().
++ pltcall_to_direct = !(gsym != NULL
++ ? gsym->has_plt_offset()
++ : object->local_has_plt_offset(r_sym));
++ }
++ else if ((gsym != NULL
++ ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
++ : psymval->is_ifunc_symbol() && object->local_has_plt_offset(r_sym))
++ && !is_got_reloc(r_type)
++ && (!psymval->is_ifunc_symbol()
++ || Scan::reloc_needs_plt_for_ifunc(target, object, r_type,
++ false)))
+ {
+ if (size == 64
+ && gsym != NULL
+@@ -10796,9 +10817,9 @@ Target_powerpc<size, big_endian>::Reloca
+ gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC));
+ }
+
+- if (use_plt_offset && (is_plt16_reloc<size>(r_type)
+- || r_type == elfcpp::R_PPC64_PLT_PCREL34
+- || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
++ if (!pltcall_to_direct && (is_plt16_reloc<size>(r_type)
++ || r_type == elfcpp::R_PPC64_PLT_PCREL34
++ || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
+ {
+ const Output_data_plt_powerpc<size, big_endian>* plt;
+ if (gsym)
+@@ -10826,7 +10847,7 @@ Target_powerpc<size, big_endian>::Reloca
+ value -= target->toc_pointer();
+ }
+ }
+- else if (!use_plt_offset
++ else if (pltcall_to_direct
+ && (is_plt16_reloc<size>(r_type)
+ || r_type == elfcpp::R_POWERPC_PLTSEQ
+ || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC))
+@@ -10835,7 +10856,7 @@ Target_powerpc<size, big_endian>::Reloca
+ elfcpp::Swap<32, big_endian>::writeval(iview, nop);
+ r_type = elfcpp::R_POWERPC_NONE;
+ }
+- else if (!use_plt_offset
++ else if (pltcall_to_direct
+ && (r_type == elfcpp::R_PPC64_PLT_PCREL34
+ || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
+ {
+@@ -11316,8 +11337,8 @@ Target_powerpc<size, big_endian>::Reloca
+ }
+ else if (!has_stub_value)
+ {
+- if (!use_plt_offset && (r_type == elfcpp::R_POWERPC_PLTCALL
+- || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC))
++ if (pltcall_to_direct && (r_type == elfcpp::R_POWERPC_PLTCALL
++ || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC))
+ {
+ // PLTCALL without plt entry => convert to direct call
+ Insn* iview = reinterpret_cast<Insn*>(view);
--- /dev/null
+From 9e855cffa1fda44629e7f9b76dfa3e5a51a440e9 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Thu, 11 Aug 2022 09:51:03 +0930
+Subject: [PATCH 011/160] PR29466, APP/NO_APP with .linefile
+
+Commit 53f2b36a54b9 exposed a bug in sb_scrub_and_add_sb that could
+result in losing input. If scrubbing results in expansion past the
+holding capacity of do_scrub_chars output buffer, then do_scrub_chars
+stashes the extra input for the next call. That call never came
+because sb_scrub_and_add_sb wrongly decided it was done. Fix that by
+allowing sb_scrub_and_add_sb to see whether there is pending input.
+Also allow a little extra space so that in most cases we won't need
+to resize the output buffer.
+
+sb_scrub_and_add_sb also limited output to the size of the input,
+rather than the actual output buffer size. Fixing that resulted in a
+fail of gas/testsuite/macros/dot with an extra warning: "end of file
+not at end of a line; newline inserted". OK, so the macro in dot.s
+really does finish without end-of-line. Apparently the macro
+expansion code relied on do_scrub_chars returning early. So fix that
+too by adding a newline if needed in macro_expand_body.
+
+ PR 29466
+ * app.c (do_scrub_pending): New function.
+ * as.h: Declare it.
+ * input-scrub.c (input_scrub_include_sb): Add extra space for
+ two .linefile directives.
+ * sb.c (sb_scrub_and_add_sb): Take into account pending input.
+ Allow output to max.
+ * macro.c (macro_expand_body): Add terminating newline.
+ * testsuite/config/default.exp (SIZE, SIZEFLAGS): Define.
+ * testsuite/gas/macros/app5.d,
+ * testsuite/gas/macros/app5.s: New test.
+ * testsuite/gas/macros/macros.exp: Run it.
+
+(cherry picked from commit 4d74aab7aa562fe79d4669cdad0c32610531cbc0)
+---
+ gas/app.c | 13 +++++++++++++
+ gas/as.h | 1 +
+ gas/input-scrub.c | 6 ++++--
+ gas/macro.c | 2 ++
+ gas/sb.c | 5 +++--
+ gas/testsuite/config/default.exp | 8 ++++++++
+ gas/testsuite/gas/macros/app5.d | 6 ++++++
+ gas/testsuite/gas/macros/app5.s | 5 +++++
+ gas/testsuite/gas/macros/macros.exp | 1 +
+ 9 files changed, 43 insertions(+), 4 deletions(-)
+ create mode 100644 gas/testsuite/gas/macros/app5.d
+ create mode 100644 gas/testsuite/gas/macros/app5.s
+
+--- a/gas/app.c
++++ b/gas/app.c
+@@ -1537,3 +1537,16 @@ do_scrub_chars (size_t (*get) (char *, s
+ last_char = to[-1];
+ return to - tostart;
+ }
++
++/* Return amount of pending input. */
++
++size_t
++do_scrub_pending (void)
++{
++ size_t len = 0;
++ if (saved_input)
++ len += saved_input_len;
++ if (state == -1)
++ len += strlen (out_string);
++ return len;
++}
+--- a/gas/as.h
++++ b/gas/as.h
+@@ -460,6 +460,7 @@ void input_scrub_insert_file (char *);
+ char * input_scrub_new_file (const char *);
+ char * input_scrub_next_buffer (char **bufp);
+ size_t do_scrub_chars (size_t (*get) (char *, size_t), char *, size_t);
++size_t do_scrub_pending (void);
+ bool scan_for_multibyte_characters (const unsigned char *, const unsigned char *, bool);
+ int gen_to_words (LITTLENUM_TYPE *, int, long);
+ int had_err (void);
+--- a/gas/input-scrub.c
++++ b/gas/input-scrub.c
+@@ -278,9 +278,11 @@ input_scrub_include_sb (sb *from, char *
+
+ next_saved_file = input_scrub_push (position);
+
+- /* Allocate sufficient space: from->len + optional newline. */
++ /* Allocate sufficient space: from->len plus optional newline
++ plus two ".linefile " directives, plus a little more for other
++ expansion. */
+ newline = from->len >= 1 && from->ptr[0] != '\n';
+- sb_build (&from_sb, from->len + newline);
++ sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30);
+ if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
+ expansion = expanding_nested;
+ from_sb_expansion = expansion;
+--- a/gas/macro.c
++++ b/gas/macro.c
+@@ -1056,6 +1056,8 @@ macro_expand_body (sb *in, sb *out, form
+ loclist = f;
+ }
+
++ if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
++ sb_add_char (out, '\n');
+ return err;
+ }
+
+--- a/gas/sb.c
++++ b/gas/sb.c
+@@ -119,11 +119,12 @@ sb_scrub_and_add_sb (sb *ptr, sb *s)
+ So we loop until the input S is consumed. */
+ while (1)
+ {
+- size_t copy = s->len - (scrub_position - s->ptr);
++ size_t copy = s->len - (scrub_position - s->ptr) + do_scrub_pending ();
+ if (copy == 0)
+ break;
+ sb_check (ptr, copy);
+- ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, copy);
++ ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len,
++ ptr->max - ptr->len);
+ }
+
+ sb_to_scrub = 0;
+--- a/gas/testsuite/config/default.exp
++++ b/gas/testsuite/config/default.exp
+@@ -52,6 +52,14 @@ if ![info exists NMFLAGS] then {
+ set NMFLAGS {}
+ }
+
++if ![info exists SIZE] then {
++ set SIZE [findfile $base_dir/size]
++}
++
++if ![info exists SIZEFLAGS] then {
++ set SIZEFLAGS ""
++}
++
+ if ![info exists OBJCOPY] then {
+ set OBJCOPY [findfile $base_dir/../../binutils/objcopy]
+ }
+--- /dev/null
++++ b/gas/testsuite/gas/macros/app5.d
+@@ -0,0 +1,6 @@
++#name: APP with linefile
++#xfail: tic30-*-*
++#size: -G
++# pr29466 just check that the test assembles
++
++#pass
+--- /dev/null
++++ b/gas/testsuite/gas/macros/app5.s
+@@ -0,0 +1,5 @@
++#NO_APP
++#APP
++# 5 "foo.c" 1
++# 0 "" 2
++#NO_APP
+--- a/gas/testsuite/gas/macros/macros.exp
++++ b/gas/testsuite/gas/macros/macros.exp
+@@ -70,6 +70,7 @@ run_dump_test app2
+ run_dump_test app3
+ remote_download host "$srcdir/$subdir/app4b.s"
+ run_dump_test app4
++run_dump_test app5
+
+ run_list_test badarg ""
+
--- /dev/null
+From 509a2ec6ad3ea7eb3f4cf59538cf636a2126e4c3 Mon Sep 17 00:00:00 2001
+From: liuzhensong <liuzhensong@loongson.cn>
+Date: Fri, 2 Sep 2022 16:29:14 +0800
+Subject: [PATCH 039/160] LoongArch:ld: Fix relocation error of pcrel.
+
+ Patch for branch 2.39.
+ Need to reduce the address of pc when using
+ reloction R_LARCH_SOP_PUSH_PCREL.
+
+ bfd/
+ * elfnn-loongarch.c
+---
+ bfd/elfnn-loongarch.c | 3 +-
+ ld/testsuite/ld-loongarch-elf/pcrel-const.d | 14 +++++++
+ ld/testsuite/ld-loongarch-elf/pcrel-const.lds | 14 +++++++
+ ld/testsuite/ld-loongarch-elf/pcrel-const.s | 12 ++++++
+ ld/testsuite/ld-loongarch-elf/pr.exp | 39 +++++++++++++++++++
+ 5 files changed, 81 insertions(+), 1 deletion(-)
+ create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.d
+ create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.lds
+ create mode 100644 ld/testsuite/ld-loongarch-elf/pcrel-const.s
+ create mode 100644 ld/testsuite/ld-loongarch-elf/pr.exp
+
+--- a/bfd/elfnn-loongarch.c
++++ b/bfd/elfnn-loongarch.c
+@@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd *out
+ case R_LARCH_SOP_PUSH_PLT_PCREL:
+ unresolved_reloc = false;
+
+- if (resolved_to_const)
++ if (!is_undefweak && resolved_to_const)
+ {
+ relocation += rel->r_addend;
++ relocation -= pc;
+ break;
+ }
+ else if (is_undefweak)
+--- /dev/null
++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.d
+@@ -0,0 +1,14 @@
++#as: -mla-global-with-pcrel
++#objdump: -Drsz
++
++.*:[ ]+file format .*
++
++
++Disassembly of section .text:
++
++.* <foo>:
++#...
++[ ]+8:[ ]+02c04084[ ]+addi.d[ ]+\$a0,[ ]+\$a0,[ ]+16\(0x10\)
++#...
++0+14 <__sec_end>:
++#pass
+--- /dev/null
++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.lds
+@@ -0,0 +1,14 @@
++ENTRY(foo);
++SECTIONS
++{
++ .text : {
++ *(.text*)
++ }
++
++ .data : {
++ __sec_start = .;
++ *(.gzdata)
++ __sec_end = .;
++ }
++}
++PROVIDE(__sec_size = __sec_end);
+--- /dev/null
++++ b/ld/testsuite/ld-loongarch-elf/pcrel-const.s
+@@ -0,0 +1,12 @@
++ .text
++ .align 2
++ .globl foo
++ .type foo, @function
++foo:
++ nop
++ la.global $r4,__sec_size
++ ldptr.w $r4,$r4,0
++ jr $r1
++ .size foo, .-foo
++ .data
++ .word 1
+--- /dev/null
++++ b/ld/testsuite/ld-loongarch-elf/pr.exp
+@@ -0,0 +1,39 @@
++# Expect script for LoongArch ELF linker tests
++# Copyright (C) 2022 Free Software Foundation, Inc.
++#
++# This file is part of the GNU Binutils.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
++# MA 02110-1301, USA.
++#
++
++if ![istarget loongarch64-*-*] {
++ return
++}
++
++set link_tests [list \
++ [list \
++ "pcrel const" \
++ "-T pcrel-const.lds" "" \
++ "-mla-global-with-pcrel" \
++ { pcrel-const.s } \
++ [list \
++ [list objdump -D pcrel-const.d] \
++ ] \
++ "pcrel-const" \
++ ] \
++]
++
++run_ld_link_tests $link_tests
--- /dev/null
+From 4233be14a34d754a70b8b6f6fa42d21f35c6e030 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Sat, 10 Sep 2022 07:30:57 +0930
+Subject: [PATCH 043/160] Re: PR29466, APP/NO_APP with linefile
+
+It looks like I copied the SIZE init across from
+binutils/testsuite/config/default.exp without some necessary editing.
+
+ PR 29466
+ * testsuite/config/default.exp (SIZE): Adjust relative path.
+
+(cherry picked from commit 1180f540d5f2f7751b5309bdd6c38d69fcf699e7)
+---
+ gas/testsuite/config/default.exp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/gas/testsuite/config/default.exp
++++ b/gas/testsuite/config/default.exp
+@@ -53,7 +53,7 @@ if ![info exists NMFLAGS] then {
+ }
+
+ if ![info exists SIZE] then {
+- set SIZE [findfile $base_dir/size]
++ set SIZE [findfile $base_dir/../../binutils/size]
+ }
+
+ if ![info exists SIZEFLAGS] then {
--- /dev/null
+From 4d7bba23a39fba18d6d13a2941a3c232011a7064 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Fri, 16 Sep 2022 18:08:44 +0930
+Subject: [PATCH 050/160] PowerPC64 pcrel got relocs against local symbols
+
+Not that anyone would want to indirect via the GOT when an address can
+be loaded directly with pla, the following:
+
+ pld 3,x@got@pcrel
+x:
+
+leads to "Internal error in md_apply_fix", because the generic parts
+of assembler fixup handling convert the fx_pcrel fixup to one without
+a symbol. Stop that happening.
+
+ * config/tc-ppc.c (ppc_force_relocation): Add PLT_PCREL34 and
+ assorted GOT_PCREL34 relocs.
+
+(cherry picked from commit 49c3ed081fed6b8e2b48fdc48f805f11e4589514)
+---
+ gas/config/tc-ppc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/gas/config/tc-ppc.c
++++ b/gas/config/tc-ppc.c
+@@ -6676,6 +6676,12 @@ ppc_force_relocation (fixS *fix)
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ case BFD_RELOC_24_PLT_PCREL:
+ case BFD_RELOC_PPC64_TOC:
++ case BFD_RELOC_PPC64_PLT_PCREL34:
++ case BFD_RELOC_PPC64_GOT_PCREL34:
++ case BFD_RELOC_PPC64_GOT_TLSGD_PCREL34:
++ case BFD_RELOC_PPC64_GOT_TLSLD_PCREL34:
++ case BFD_RELOC_PPC64_GOT_TPREL_PCREL34:
++ case BFD_RELOC_PPC64_GOT_DTPREL_PCREL34:
+ return 1;
+ case BFD_RELOC_PPC_B26:
+ case BFD_RELOC_PPC_BA26:
--- /dev/null
+From 010db38b54b589ca3e95b498aba2831064970171 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Wed, 21 Sep 2022 09:06:29 +0930
+Subject: [PATCH 055/160] Re: PowerPC64 pcrel got relocs against local symbols
+
+The last patch wasn't all that shiny. There are rather a lot more
+relocations that can hit the assertion in md_apply_fix if the symbol
+is local or absolute. Fix them all.
+
+ * config/tc-ppc.c (ppc_force_relocation): Add all relocs that
+ expect a symbol in md_apply_fix. Remove tls pcrel relocs
+ already covered in general tls match range.
+
+(cherry picked from commit 8b168f1a1e09e337d2a970f204a0230c091bbe58)
+---
+ gas/config/tc-ppc.c | 58 ++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 52 insertions(+), 6 deletions(-)
+
+--- a/gas/config/tc-ppc.c
++++ b/gas/config/tc-ppc.c
+@@ -6666,8 +6666,6 @@ ppc_force_relocation (fixS *fix)
+ int
+ ppc_force_relocation (fixS *fix)
+ {
+- /* Branch prediction relocations must force a relocation, as must
+- the vtable description relocs. */
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+@@ -6676,12 +6674,60 @@ ppc_force_relocation (fixS *fix)
+ case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ case BFD_RELOC_24_PLT_PCREL:
+ case BFD_RELOC_PPC64_TOC:
++ case BFD_RELOC_16_GOTOFF:
++ case BFD_RELOC_LO16_GOTOFF:
++ case BFD_RELOC_HI16_GOTOFF:
++ case BFD_RELOC_HI16_S_GOTOFF:
++ case BFD_RELOC_LO16_PLTOFF:
++ case BFD_RELOC_HI16_PLTOFF:
++ case BFD_RELOC_HI16_S_PLTOFF:
++ case BFD_RELOC_GPREL16:
++ case BFD_RELOC_16_BASEREL:
++ case BFD_RELOC_LO16_BASEREL:
++ case BFD_RELOC_HI16_BASEREL:
++ case BFD_RELOC_HI16_S_BASEREL:
++ case BFD_RELOC_PPC_TOC16:
++ case BFD_RELOC_PPC64_TOC16_LO:
++ case BFD_RELOC_PPC64_TOC16_HI:
++ case BFD_RELOC_PPC64_TOC16_HA:
++ case BFD_RELOC_PPC64_PLTGOT16:
++ case BFD_RELOC_PPC64_PLTGOT16_LO:
++ case BFD_RELOC_PPC64_PLTGOT16_HI:
++ case BFD_RELOC_PPC64_PLTGOT16_HA:
++ case BFD_RELOC_PPC64_GOT16_DS:
++ case BFD_RELOC_PPC64_GOT16_LO_DS:
++ case BFD_RELOC_PPC64_PLT16_LO_DS:
++ case BFD_RELOC_PPC64_SECTOFF_DS:
++ case BFD_RELOC_PPC64_SECTOFF_LO_DS:
++ case BFD_RELOC_PPC64_TOC16_DS:
++ case BFD_RELOC_PPC64_TOC16_LO_DS:
++ case BFD_RELOC_PPC64_PLTGOT16_DS:
++ case BFD_RELOC_PPC64_PLTGOT16_LO_DS:
++ case BFD_RELOC_PPC_EMB_NADDR16:
++ case BFD_RELOC_PPC_EMB_NADDR16_LO:
++ case BFD_RELOC_PPC_EMB_NADDR16_HI:
++ case BFD_RELOC_PPC_EMB_NADDR16_HA:
++ case BFD_RELOC_PPC_EMB_SDAI16:
++ case BFD_RELOC_PPC_EMB_SDA2I16:
++ case BFD_RELOC_PPC_EMB_SDA2REL:
++ case BFD_RELOC_PPC_EMB_SDA21:
++ case BFD_RELOC_PPC_EMB_MRKREF:
++ case BFD_RELOC_PPC_EMB_RELSEC16:
++ case BFD_RELOC_PPC_EMB_RELST_LO:
++ case BFD_RELOC_PPC_EMB_RELST_HI:
++ case BFD_RELOC_PPC_EMB_RELST_HA:
++ case BFD_RELOC_PPC_EMB_BIT_FLD:
++ case BFD_RELOC_PPC_EMB_RELSDA:
++ case BFD_RELOC_PPC_VLE_SDA21:
++ case BFD_RELOC_PPC_VLE_SDA21_LO:
++ case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
++ case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
++ case BFD_RELOC_PPC_VLE_SDAREL_HI16A:
++ case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
++ case BFD_RELOC_PPC_VLE_SDAREL_HA16A:
++ case BFD_RELOC_PPC_VLE_SDAREL_HA16D:
+ case BFD_RELOC_PPC64_PLT_PCREL34:
+ case BFD_RELOC_PPC64_GOT_PCREL34:
+- case BFD_RELOC_PPC64_GOT_TLSGD_PCREL34:
+- case BFD_RELOC_PPC64_GOT_TLSLD_PCREL34:
+- case BFD_RELOC_PPC64_GOT_TPREL_PCREL34:
+- case BFD_RELOC_PPC64_GOT_DTPREL_PCREL34:
+ return 1;
+ case BFD_RELOC_PPC_B26:
+ case BFD_RELOC_PPC_BA26:
--- /dev/null
+From a98316d5cf970cbc99689797d84c2ea832bcdcbb Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Mon, 1 Aug 2022 16:02:39 -0700
+Subject: [PATCH 058/160] elf: Reset alignment for each PT_LOAD segment
+
+Reset alignment for each PT_LOAD segment to avoid using alignment from
+the previous PT_LOAD segment.
+
+bfd/
+
+ PR ld/29435
+ * elf.c (assign_file_positions_for_load_sections): Reset
+ alignment for each PT_LOAD segment.
+
+ld/
+
+ PR ld/29435
+ * testsuite/ld-elf/pr29435.d: New file.
+ * testsuite/ld-elf/pr29435.s: Likewise.
+
+(cherry picked from commit 59f214544c50ec7ebbca285ff2b4949f48671690)
+---
+ bfd/elf.c | 7 ++++---
+ ld/testsuite/ld-elf/pr29435.d | 11 +++++++++++
+ ld/testsuite/ld-elf/pr29435.s | 6 ++++++
+ 3 files changed, 21 insertions(+), 3 deletions(-)
+ create mode 100644 ld/testsuite/ld-elf/pr29435.d
+ create mode 100644 ld/testsuite/ld-elf/pr29435.s
+
+--- a/bfd/elf.c
++++ b/bfd/elf.c
+@@ -5438,8 +5438,6 @@ assign_file_positions_for_load_sections
+ Elf_Internal_Phdr *p;
+ file_ptr off; /* Octets. */
+ bfd_size_type maxpagesize;
+- bfd_size_type p_align;
+- bool p_align_p = false;
+ unsigned int alloc, actual;
+ unsigned int i, j;
+ struct elf_segment_map **sorted_seg_map;
+@@ -5524,7 +5522,6 @@ assign_file_positions_for_load_sections
+ qsort (sorted_seg_map, alloc, sizeof (*sorted_seg_map),
+ elf_sort_segments);
+
+- p_align = bed->p_align;
+ maxpagesize = 1;
+ if ((abfd->flags & D_PAGED) != 0)
+ {
+@@ -5559,6 +5556,8 @@ assign_file_positions_for_load_sections
+ asection **secpp;
+ bfd_vma off_adjust; /* Octets. */
+ bool no_contents;
++ bfd_size_type p_align;
++ bool p_align_p;
+
+ /* An ELF segment (described by Elf_Internal_Phdr) may contain a
+ number of sections with contents contributing to both p_filesz
+@@ -5569,6 +5568,8 @@ assign_file_positions_for_load_sections
+ p = phdrs + m->idx;
+ p->p_type = m->p_type;
+ p->p_flags = m->p_flags;
++ p_align = bed->p_align;
++ p_align_p = false;
+
+ if (m->count == 0)
+ p->p_vaddr = m->p_vaddr_offset * opb;
+--- /dev/null
++++ b/ld/testsuite/ld-elf/pr29435.d
+@@ -0,0 +1,11 @@
++#ld: -shared -z separate-code -z relro
++#xfail: ![check_shared_lib_support]
++#xfail: ![check_relro_support]
++#readelf: -Wl
++
++#failif
++#...
++ +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ .* 0x8000
++#...
++ +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ .* 0x8000
++#...
+--- /dev/null
++++ b/ld/testsuite/ld-elf/pr29435.s
+@@ -0,0 +1,6 @@
++ .text
++ .balign 0x8000
++ .globl foo
++ .type foo, %function
++foo:
++ .byte 0
--- /dev/null
+From 041c22e35de06d22566f4c71e4425c3351215e66 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Sun, 25 Sep 2022 12:07:36 +0930
+Subject: [PATCH 063/160] PR29542, PowerPC gold internal error in
+ get_output_view,
+
+We were attempting to set a BSS style section contents.
+
+ PR 29542
+ * powerpc.cc (Output_data_plt_powerpc::do_write): Don't set .plt,
+ .iplt or .lplt section contents when position independent.
+
+(cherry picked from commit c21736aed1d4877e090df60362413669dbdc391d)
+---
+ gold/powerpc.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/gold/powerpc.cc
++++ b/gold/powerpc.cc
+@@ -4338,7 +4338,8 @@ template<int size, bool big_endian>
+ void
+ Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of)
+ {
+- if (!this->sym_ents_.empty())
++ if (!this->sym_ents_.empty()
++ && !parameters->options().output_is_position_independent())
+ {
+ const section_size_type offset = this->offset();
+ const section_size_type oview_size
--- /dev/null
+From 88ac930a725b8aac8284a2738f03b843f4343dd0 Mon Sep 17 00:00:00 2001
+From: Victor Do Nascimento <Victor.DoNascimento@arm.com>
+Date: Thu, 17 Nov 2022 14:48:37 +0000
+Subject: [PATCH 116/160] arm: Use DWARF numbering convention for
+ pseudo-register representation
+
+The patch, initially submitted to trunk in
+https://sourceware.org/pipermail/binutils/2022-July/122092.html ensures correct
+support for handling .save directives for mixed-register type lists involving
+the ra_auth_code pseudo-register, whereby the support first introduced in 2.39
+(https://sourceware.org/pipermail/binutils/2022-May/120672.html) led to the
+generation of unwinder code popping registers in reversed order.
+
+gas/Changelog:
+
+ * config/tc-arm.c (REG_RA_AUTH_CODE): New.
+ (parse_dot_save): Likewise.
+ (parse_reg_list): Remove obsolete code.
+ (reg_names): Set ra_auth_code to 143.
+ (s_arm_unwind_save): Handle core and pseudo-register lists via
+ parse_dot_save.
+ (s_arm_unwind_save_mixed): Deleted.
+ (s_arm_unwind_save_pseudo): Handle one register at a time.
+ * testsuite/gas/arm/unwind-pacbti-m-readelf.d: Fix test.
+ * testsuite/gas/arm/unwind-pacbti-m.d: Likewise.
+
+(cherry picked from commit 3a368c4c248f6e9f4bda3a5369befa17a4560293)
+---
+ gas/config/tc-arm.c | 159 ++++++++++--------
+ .../gas/arm/unwind-pacbti-m-readelf.d | 4 +-
+ gas/testsuite/gas/arm/unwind-pacbti-m.d | 2 +-
+ 3 files changed, 95 insertions(+), 70 deletions(-)
+
+--- a/gas/config/tc-arm.c
++++ b/gas/config/tc-arm.c
+@@ -742,6 +742,7 @@ const char * const reg_expected_msgs[] =
+ #define REG_SP 13
+ #define REG_LR 14
+ #define REG_PC 15
++#define REG_RA_AUTH_CODE 143
+
+ /* ARM instructions take 4bytes in the object file, Thumb instructions
+ take 2: */
+@@ -1943,21 +1944,6 @@ parse_reg_list (char ** strp, enum reg_l
+
+ reg = arm_reg_parse (&str, rt);
+
+- /* Skip over allowed registers of alternative types in mixed-type
+- register lists. */
+- if (reg == FAIL && rt == REG_TYPE_PSEUDO
+- && ((reg = arm_reg_parse (&str, REG_TYPE_RN)) != FAIL))
+- {
+- cur_reg = reg;
+- continue;
+- }
+- else if (reg == FAIL && rt == REG_TYPE_RN
+- && ((reg = arm_reg_parse (&str, REG_TYPE_PSEUDO)) != FAIL))
+- {
+- cur_reg = reg;
+- continue;
+- }
+-
+ if (etype == REGLIST_CLRM)
+ {
+ if (reg == REG_SP || reg == REG_PC)
+@@ -4139,7 +4125,6 @@ s_arm_unwind_fnstart (int ignored ATTRIB
+ unwind.sp_restored = 0;
+ }
+
+-
+ /* Parse a handlerdata directive. Creates the exception handling table entry
+ for the function. */
+
+@@ -4297,15 +4282,19 @@ s_arm_unwind_personality (int ignored AT
+ /* Parse a directive saving pseudo registers. */
+
+ static void
+-s_arm_unwind_save_pseudo (long range)
++s_arm_unwind_save_pseudo (int regno)
+ {
+ valueT op;
+
+- if (range & (1 << 12))
++ switch (regno)
+ {
++ case REG_RA_AUTH_CODE:
+ /* Opcode for restoring RA_AUTH_CODE. */
+ op = 0xb4;
+ add_unwind_opcode (op, 1);
++ break;
++ default:
++ as_bad (_("Unknown register %d encountered\n"), regno);
+ }
+ }
+
+@@ -4375,6 +4364,80 @@ s_arm_unwind_save_core (long range)
+ }
+ }
+
++/* Implement correct handling of .save lists enabling the split into
++sublists where necessary, while preserving correct sublist ordering. */
++
++static void
++parse_dot_save (char **str_p, int prev_reg)
++{
++ long core_regs = 0;
++ int reg;
++ int in_range = 0;
++
++ if (**str_p == ',')
++ *str_p += 1;
++ if (**str_p == '}')
++ {
++ *str_p += 1;
++ return;
++ }
++
++ while ((reg = arm_reg_parse (str_p, REG_TYPE_RN)) != FAIL)
++ {
++ if (!in_range)
++ {
++ if (core_regs & (1 << reg))
++ as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
++ reg);
++ else if (reg <= prev_reg)
++ as_tsktsk (_("Warning: register list not in ascending order"));
++
++ core_regs |= (1 << reg);
++ prev_reg = reg;
++ if (skip_past_char(str_p, '-') != FAIL)
++ in_range = 1;
++ else if (skip_past_comma(str_p) == FAIL)
++ first_error (_("bad register list"));
++ }
++ else
++ {
++ int i;
++ if (reg <= prev_reg)
++ first_error (_("bad range in register list"));
++ for (i = prev_reg + 1; i <= reg; i++)
++ {
++ if (core_regs & (1 << i))
++ as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
++ i);
++ else
++ core_regs |= 1 << i;
++ }
++ in_range = 0;
++ }
++ }
++ if (core_regs)
++ {
++ /* Higher register numbers go in higher memory addresses. When splitting a list,
++ right-most sublist should therefore be .saved first. Use recursion for this. */
++ parse_dot_save (str_p, reg);
++ /* We're back from recursion, so emit .save insn for sublist. */
++ s_arm_unwind_save_core (core_regs);
++ return;
++ }
++ /* Handle pseudo-regs, under assumption these are emitted singly. */
++ else if ((reg = arm_reg_parse (str_p, REG_TYPE_PSEUDO)) != FAIL)
++ {
++ /* Recurse for remainder of input. Note: No assumption is made regarding which
++ register in core register set holds pseudo-register. It's not considered in
++ ordering check beyond ensuring it's not sandwiched between 2 consecutive
++ registers. */
++ parse_dot_save (str_p, prev_reg + 1);
++ s_arm_unwind_save_pseudo (reg);
++ return;
++ }
++ else
++ as_bad (BAD_SYNTAX);
++}
+
+ /* Parse a directive saving FPA registers. */
+
+@@ -4716,39 +4779,13 @@ s_arm_unwind_save_mmxwcg (void)
+ ignore_rest_of_line ();
+ }
+
+-/* Convert range and mask_range into a sequence of s_arm_unwind_core
+- and s_arm_unwind_pseudo operations. We assume that mask_range will
+- not have consecutive bits set, or that one operation per bit is
+- acceptable. */
+-
+-static void
+-s_arm_unwind_save_mixed (long range, long mask_range)
+-{
+- while (mask_range)
+- {
+- long mask_bit = mask_range & -mask_range;
+- long subrange = range & (mask_bit - 1);
+-
+- if (subrange)
+- s_arm_unwind_save_core (subrange);
+-
+- s_arm_unwind_save_pseudo (mask_bit);
+- range &= ~subrange;
+- mask_range &= ~mask_bit;
+- }
+-
+- if (range)
+- s_arm_unwind_save_core (range);
+-}
+-
+ /* Parse an unwind_save directive.
+ If the argument is non-zero, this is a .vsave directive. */
+
+ static void
+ s_arm_unwind_save (int arch_v6)
+ {
+- char *peek, *mask_peek;
+- long range, mask_range;
++ char *peek;
+ struct reg_entry *reg;
+ bool had_brace = false;
+
+@@ -4756,7 +4793,7 @@ s_arm_unwind_save (int arch_v6)
+ as_bad (MISSING_FNSTART);
+
+ /* Figure out what sort of save we have. */
+- peek = mask_peek = input_line_pointer;
++ peek = input_line_pointer;
+
+ if (*peek == '{')
+ {
+@@ -4788,20 +4825,13 @@ s_arm_unwind_save (int arch_v6)
+
+ case REG_TYPE_PSEUDO:
+ case REG_TYPE_RN:
+- mask_range = parse_reg_list (&mask_peek, REGLIST_PSEUDO);
+- range = parse_reg_list (&input_line_pointer, REGLIST_RN);
+-
+- if (range == FAIL || mask_range == FAIL)
+- {
+- as_bad (_("expected register list"));
+- ignore_rest_of_line ();
+- return;
+- }
+-
+- demand_empty_rest_of_line ();
+-
+- s_arm_unwind_save_mixed (range, mask_range);
+- return;
++ {
++ if (had_brace)
++ input_line_pointer++;
++ parse_dot_save (&input_line_pointer, -1);
++ demand_empty_rest_of_line ();
++ return;
++ }
+
+ case REG_TYPE_VFD:
+ if (arch_v6)
+@@ -23993,12 +24023,8 @@ static const struct reg_entry reg_names[
+ /* XScale accumulator registers. */
+ REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
+
+- /* DWARF ABI defines RA_AUTH_CODE to 143. It also reserves 134-142 for future
+- expansion. RA_AUTH_CODE here is given the value 143 % 134 to make it easy
+- for tc_arm_regname_to_dw2regnum to translate to DWARF reg number using
+- 134 + reg_number should the range 134 to 142 be used for more pseudo regs
+- in the future. This also helps fit RA_AUTH_CODE into a bitmask. */
+- REGDEF(ra_auth_code,12,PSEUDO),
++ /* AADWARF32 defines RA_AUTH_CODE to 143. */
++ REGDEF(ra_auth_code,143,PSEUDO),
+ };
+ #undef REGDEF
+ #undef REGNUM
+@@ -27905,7 +27931,6 @@ create_unwind_entry (int have_data)
+ return 0;
+ }
+
+-
+ /* Initialize the DWARF-2 unwind information for this procedure. */
+
+ void
+--- a/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d
++++ b/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d
+@@ -10,11 +10,11 @@ Unwind section '.ARM.exidx' at offset 0x
+
+ 0x0 <foo>: @0x0
+ Compact model index: 1
+- 0x84 0x00 pop {r14}
+ 0xb4 pop {ra_auth_code}
+ 0x84 0x00 pop {r14}
+- 0xb4 pop {ra_auth_code}
+ 0xa3 pop {r4, r5, r6, r7}
+ 0xb4 pop {ra_auth_code}
++ 0x84 0x00 pop {r14}
++ 0xb4 pop {ra_auth_code}
+ 0xa8 pop {r4, r14}
+ 0xb0 finish
+--- a/gas/testsuite/gas/arm/unwind-pacbti-m.d
++++ b/gas/testsuite/gas/arm/unwind-pacbti-m.d
+@@ -8,4 +8,4 @@
+ .*: file format.*
+
+ Contents of section .ARM.extab:
+- 0000 (00840281 b40084b4 b0a8b4a3|81028400 b48400b4 a3b4a8b0) 00000000 .*
++ 0000 (84b40281 84b4a300 b0a8b400|8102b484 00a3b484 00b4a8b0) 00000000 .*