toolchain/binutils: backport stable patches
authorHauke Mehrtens <hauke@hauke-m.de>
Sat, 31 Dec 2022 20:11:35 +0000 (21:11 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 31 Dec 2022 20:52:53 +0000 (21:52 +0100)
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>
toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch [new file with mode: 0644]
toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch [new file with mode: 0644]

diff --git a/toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch b/toolchain/binutils/patches/2.39/005-ld-fix-NEWS-typos.patch
new file mode 100644 (file)
index 0000000..39c61d9
--- /dev/null
@@ -0,0 +1,27 @@
+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.
diff --git a/toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch b/toolchain/binutils/patches/2.39/008-gas-Dwarf-properly-skip-zero-size-functions.patch
new file mode 100644 (file)
index 0000000..055da84
--- /dev/null
@@ -0,0 +1,90 @@
+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.  */
diff --git a/toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch b/toolchain/binutils/patches/2.39/009-PR29462-internal-error-in-relocate-at-powerpc.cc-107.patch
new file mode 100644 (file)
index 0000000..e325d3b
--- /dev/null
@@ -0,0 +1,270 @@
+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);
diff --git a/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch b/toolchain/binutils/patches/2.39/011-PR29466-APP-NO_APP-with-.linefile.patch
new file mode 100644 (file)
index 0000000..f7b5819
--- /dev/null
@@ -0,0 +1,167 @@
+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 ""
diff --git a/toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch b/toolchain/binutils/patches/2.39/039-LoongArch-ld-Fix-relocation-error-of-pcrel.patch
new file mode 100644 (file)
index 0000000..67e499d
--- /dev/null
@@ -0,0 +1,128 @@
+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
diff --git a/toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch b/toolchain/binutils/patches/2.39/043-Re-PR29466-APP-NO_APP-with-linefile.patch
new file mode 100644 (file)
index 0000000..1de501a
--- /dev/null
@@ -0,0 +1,27 @@
+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 {
diff --git a/toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch b/toolchain/binutils/patches/2.39/050-PowerPC64-pcrel-got-relocs-against-local-symbols.patch
new file mode 100644 (file)
index 0000000..5c89f68
--- /dev/null
@@ -0,0 +1,38 @@
+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:
diff --git a/toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch b/toolchain/binutils/patches/2.39/055-Re-PowerPC64-pcrel-got-relocs-against-local-symbols.patch
new file mode 100644 (file)
index 0000000..19b80c3
--- /dev/null
@@ -0,0 +1,94 @@
+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:
diff --git a/toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch b/toolchain/binutils/patches/2.39/058-elf-Reset-alignment-for-each-PT_LOAD-segment.patch
new file mode 100644 (file)
index 0000000..aaf7a1b
--- /dev/null
@@ -0,0 +1,89 @@
+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
diff --git a/toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch b/toolchain/binutils/patches/2.39/063-PR29542-PowerPC-gold-internal-error-in-get_output_vi.patch
new file mode 100644 (file)
index 0000000..0d66b77
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch b/toolchain/binutils/patches/2.39/116-arm-Use-DWARF-numbering-convention-for-pseudo-regist.patch
new file mode 100644 (file)
index 0000000..82a015e
--- /dev/null
@@ -0,0 +1,301 @@
+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  .*