diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 68e17c8babb..e6dd7abdf96 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -10020,7 +10020,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 		     "functions will result in a segfault at runtime\n"));
 	      else if (htab->maybe_local_ifunc_resolver)
 		info->callbacks->einfo
-		  (_("%P: warning: text relocations and GNU indirect "
+		  (_("%P: %w: text relocations and GNU indirect "
 		     "functions may result in a segfault at runtime\n"));
 	      continue;
 
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 0f5117b6beb..77bcaea7bdf 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -5017,7 +5017,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	      else
 		info->callbacks->einfo
 		  /* xgettext:c-format */
-		  (_("%H: warning: relocation to \"%s\" references a different segment\n"),
+		  (_("%H: %w: relocation to \"%s\" references a different segment\n"),
 		   input_bfd, input_section, rel->r_offset, symname);
 	    }
 
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index 881d4d8eb97..d960c34021a 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -2572,7 +2572,7 @@ check_function_ranges (asection *sec, struct bfd_link_info *info)
 	const char *f2 = func_name (&sinfo->fun[i]);
 
 	/* xgettext:c-format */
-	info->callbacks->einfo (_("warning: %s overlaps %s\n"), f1, f2);
+	info->callbacks->einfo (_("%w: %s overlaps %s\n"), f1, f2);
 	sinfo->fun[i - 1].hi = sinfo->fun[i].lo;
       }
     else if (insns_at_end (&sinfo->fun[i - 1], sinfo->fun[i].lo))
@@ -2588,7 +2588,7 @@ check_function_ranges (asection *sec, struct bfd_link_info *info)
 	{
 	  const char *f1 = func_name (&sinfo->fun[sinfo->num_fun - 1]);
 
-	  info->callbacks->einfo (_("warning: %s exceeds section size\n"), f1);
+	  info->callbacks->einfo (_("%w: %s exceeds section size\n"), f1);
 	  sinfo->fun[sinfo->num_fun - 1].hi = sec->size;
 	}
       else if (insns_at_end (&sinfo->fun[sinfo->num_fun - 1], sec->size))
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e95f9fbe651..cf68124ec12 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -18303,7 +18303,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 	    case DT_TEXTREL:
 	      if (htab->elf.ifunc_resolvers)
 		info->callbacks->einfo
-		  (_("%P: warning: text relocations and GNU indirect "
+		  (_("%P: %w: text relocations and GNU indirect "
 		     "functions may result in a segfault at runtime\n"));
 	      continue;
 	    }
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c2494b3e12e..f744cb67b76 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13472,13 +13472,13 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 		      (_("%P%X: read-only segment has dynamic relocations\n"));
 		  else if (bfd_link_dll (info))
 		    info->callbacks->einfo
-		      (_("%P: warning: creating DT_TEXTREL in a shared object\n"));
+		      (_("%P: %w: creating DT_TEXTREL in a shared object\n"));
 		  else if (bfd_link_pde (info))
 		    info->callbacks->einfo
-		      (_("%P: warning: creating DT_TEXTREL in a PDE\n"));
+		      (_("%P: %w: creating DT_TEXTREL in a PDE\n"));
 		  else
 		    info->callbacks->einfo
-		      (_("%P: warning: creating DT_TEXTREL in a PIE\n"));
+		      (_("%P: %w: creating DT_TEXTREL in a PIE\n"));
 		  break;
 		}
 	    }
@@ -15573,7 +15573,7 @@ _bfd_elf_add_dynamic_tags (bfd *output_bfd, struct bfd_link_info *info,
 	    {
 	      if (htab->ifunc_resolvers)
 		info->callbacks->einfo
-		  (_("%P: warning: GNU indirect functions with DT_TEXTREL "
+		  (_("%P: %w: GNU indirect functions with DT_TEXTREL "
 		     "may result in a segfault at runtime; recompile with %s\n"),
 		   bfd_link_dll (info) ? "-fPIC" : "-fPIE");
 
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 508fd771da3..ea3360231cb 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2309,7 +2309,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
 		      if (bfd_link_textrel_check (info))
 			/* xgettext:c-format */
 			info->callbacks->einfo
-			  (_("%P: %pB: warning: relocation "
+			  (_("%P: %pB: %w: relocation "
 			     "in read-only section `%pA'\n"),
 			   p->sec->owner, p->sec);
 		    }
diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em
index 33857b5d49c..d7c66dd2e76 100644
--- a/ld/emultempl/aix.em
+++ b/ld/emultempl/aix.em
@@ -382,7 +382,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case 'D':
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-	einfo (_("%P: warning: ignoring invalid -D number %s\n"), optarg);
+	einfo (_("%P: %w: ignoring invalid -D number %s\n"), optarg);
       else if (val != -1)
 	lang_section_start (".data", exp_intop (val), NULL);
       break;
@@ -390,7 +390,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case 'H':
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0' || (val & (val - 1)) != 0)
-	einfo (_("%P: warning: ignoring invalid -H number %s\n"), optarg);
+	einfo (_("%P: %w: ignoring invalid -H number %s\n"), optarg);
       else
 	file_align = val;
       break;
@@ -502,7 +502,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_MAXDATA:
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-	einfo (_("%P: warning: ignoring invalid -bmaxdata number %s\n"),
+	einfo (_("%P: %w: ignoring invalid -bmaxdata number %s\n"),
 	       optarg);
       else
 	maxdata = val;
@@ -511,7 +511,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
     case OPTION_MAXSTACK:
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-	einfo (_("%P: warning: ignoring invalid -bmaxstack number %s\n"),
+	einfo (_("%P: %w: ignoring invalid -bmaxstack number %s\n"),
 	       optarg);
       else
 	maxstack = val;
@@ -524,7 +524,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	  ++optarg;
 	}
       if (*optarg == '\0' || optarg[1] == '\0')
-	einfo (_("%P: warning: ignoring invalid module type %s\n"), optarg);
+	einfo (_("%P: %w: ignoring invalid module type %s\n"), optarg);
       else
 	modtype = (*optarg << 8) | optarg[1];
       break;
@@ -554,7 +554,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	 expression.  */
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-	einfo (_("%P: warning: ignoring invalid -pD number %s\n"), optarg);
+	einfo (_("%P: %w: ignoring invalid -pD number %s\n"), optarg);
       else
 	{
 	  etree_type *t;
@@ -577,7 +577,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	 within the file.  */
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')
-	einfo (_("%P: warning: ignoring invalid -pT number %s\n"), optarg);
+	einfo (_("%P: %w: ignoring invalid -pT number %s\n"), optarg);
       else
 	{
 	  etree_type *t;
@@ -1374,7 +1374,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bool import)
 		{
 		  impmember = "";
 		  if (cs != '\0')
-		    einfo (_("%P:%s:%d: warning: syntax error in import file\n"),
+		    einfo (_("%P:%s:%d: %w: syntax error in import file\n"),
 			   filename, linenumber);
 		}
 	      else
@@ -1386,7 +1386,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bool import)
 		  if (*s == ')')
 		    *s = '\0';
 		  else
-		    einfo (_("%P:%s:%d: warning: syntax error in import file\n"),
+		    einfo (_("%P:%s:%d: %w: syntax error in import file\n"),
 			   filename, linenumber);
 		}
 	    }
@@ -1421,7 +1421,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bool import)
 		  while (ISSPACE (*se))
 		    ++se;
 		  if (*se != '\0')
-		    einfo (_("%P:%s%d: warning: syntax error in "
+		    einfo (_("%P:%s%d: %w: syntax error in "
 			     "import/export file\n"),
 			   filename, linenumber);
 		}
@@ -1439,7 +1439,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bool import)
 		      address = bfd_scan_vma (s, &end, 0);
 		      if (*end != '\0')
 			{
-			  einfo (_("%P:%s:%d: warning: syntax error in "
+			  einfo (_("%P:%s:%d: %w: syntax error in "
 				   "import/export file\n"),
 				 filename, linenumber);
 
@@ -1484,7 +1484,7 @@ gld${EMULATION_NAME}_read_file (const char *filename, bool import)
 
   if (obstack_object_size (o) > 0)
     {
-      einfo (_("%P:%s:%d: warning: ignoring unterminated last line\n"),
+      einfo (_("%P:%s:%d: %w: ignoring unterminated last line\n"),
 	     filename, linenumber);
       obstack_free (o, obstack_base (o));
     }
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 8f501aed12a..4fccffff318 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -501,12 +501,12 @@ gld${EMULATION_NAME}_finish (void)
 
       if (params.thumb_entry_symbol != NULL && entry_symbol.name != NULL
 	  && entry_from_cmdline)
-	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+	einfo (_("%P: %w: '--thumb-entry %s' is overriding '-e %s'\n"),
 	       params.thumb_entry_symbol, entry_symbol.name);
       entry_symbol.name = buffer;
     }
   else
-    einfo (_("%P: warning: cannot find thumb start symbol %s\n"),
+    einfo (_("%P: %w: cannot find thumb start symbol %s\n"),
 	   h->root.string);
 }
 
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
index 29c386c61f8..026efbaaddd 100644
--- a/ld/emultempl/beos.em
+++ b/ld/emultempl/beos.em
@@ -194,7 +194,7 @@ set_pe_subsystem (void)
 	set_pe_name ("__minor_subsystem_version__",
 		     strtoul (end + 1, &end, 0));
       if (*end != '\0')
-	einfo (_("%P: warning: bad version number in -subsystem option\n"));
+	einfo (_("%P: %w: bad version number in -subsystem option\n"));
     }
 
   for (i = 0; v[i].name; i++)
diff --git a/ld/emultempl/m68hc1xelf.em b/ld/emultempl/m68hc1xelf.em
index 7aaa78a72d5..6090e0879fd 100644
--- a/ld/emultempl/m68hc1xelf.em
+++ b/ld/emultempl/m68hc1xelf.em
@@ -130,7 +130,7 @@ m68hc11_elf_${EMULATION_NAME}_before_allocation (void)
 
       if (pinfo->bank_size != region->length)
 	{
-	  einfo (_("%P: warning: the size of the 'window' memory region "
+	  einfo (_("%P: %w: the size of the 'window' memory region "
 		   "is not a power of 2; its size %d is truncated to %d\n"),
 		 region->length, pinfo->bank_size);
 	}
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
index 2d225317a25..691ff73abee 100644
--- a/ld/emultempl/msp430.em
+++ b/ld/emultempl/msp430.em
@@ -246,7 +246,7 @@ warn_no_output_section (const char *name)
     warned[i][WARN_RODATA] = true;
   else
     return;
-  einfo ("%P: warning: no input section rule matches %s in linker script\n",
+  einfo ("%P: %w: no input section rule matches %s in linker script\n",
 	 name);
 }
 
@@ -890,7 +890,7 @@ check_array_section_alignment (void)
 	  && sym->type == bfd_link_hash_defined
 	  && sym->u.def.value % 2)
 	{
-	  einfo ("%P: warning: \"%s\" symbol (%pU) is not word aligned\n",
+	  einfo ("%P: %w: \"%s\" symbol (%pU) is not word aligned\n",
 		 array_names[i][1], NULL);
 	}
     }
diff --git a/ld/emultempl/nto.em b/ld/emultempl/nto.em
index 7cda6650bc6..d68f2cc9c97 100644
--- a/ld/emultempl/nto.em
+++ b/ld/emultempl/nto.em
@@ -111,11 +111,11 @@ nto_lookup_QNX_note_section(int type)
 	    {
 	      if (!duplicated_notes_detected)
 		{
-		  einfo (_("%P: %pB: warning: duplicated QNX stack .note detected\n"),
+		  einfo (_("%P: %pB: %w: duplicated QNX stack .note detected\n"),
 			 stack_note_sec->owner);
 		  duplicated_notes_detected = true;
 		}
-	      einfo (_("%P: %pB: warning: duplicated QNX stack .note detected\n"),
+	      einfo (_("%P: %pB: %w: duplicated QNX stack .note detected\n"),
 		     sec->owner);
 	    }
 	  else
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 9ab5e6ef481..d1c56377094 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -623,7 +623,7 @@ set_pe_subsystem (void)
 	set_pe_name ("__minor_subsystem_version__",
 		      strtoul (end + 1, &end, 0));
       if (*end != '\0')
-	einfo (_("%P: warning: bad version number in -subsystem option\n"));
+	einfo (_("%P: %w: bad version number in -subsystem option\n"));
     }
 
   /* Check for numeric subsystem.  */
@@ -1045,7 +1045,7 @@ gld${EMULATION_NAME}_after_parse (void)
   /* PR ld/6744:  Warn the user if they have used an ELF-only
      option hoping it will work on PE.  */
   if (link_info.export_dynamic)
-    einfo (_("%P: warning: --export-dynamic is not supported for PE "
+    einfo (_("%P: %w: --export-dynamic is not supported for PE "
       "targets, did you mean --export-all-symbols?\n"));
 
 #ifdef PDB_H
@@ -1095,7 +1095,7 @@ change_undef (struct bfd_link_hash_entry * undef,
 
   if (pe_enable_stdcall_fixup == -1)
     {
-      einfo (_("%P: warning: resolving %s by linking to %s\n"),
+      einfo (_("%P: %w: resolving %s by linking to %s\n"),
 	     undef->root.string, sym->root.string);
 
       if (! gave_warning_message)
@@ -1126,7 +1126,7 @@ set_decoration (const char *undecorated_name,
 
   if (entry->decorated_link != NULL && !gave_warning_message)
     {
-      einfo (_("%P: warning: overwriting decorated name %s with %s\n"),
+      einfo (_("%P: %w: overwriting decorated name %s with %s\n"),
 	     entry->decorated_link->root.string, undecorated_name);
       gave_warning_message = true;
     }
@@ -1323,7 +1323,7 @@ write_build_id (bfd *abfd)
 
   if (!link_order)
     {
-      einfo (_("%P: warning: .buildid section discarded,"
+      einfo (_("%P: %w: .buildid section discarded,"
 	       " --build-id ignored\n"));
       return true;
     }
@@ -1416,7 +1416,7 @@ setup_build_id (bfd *ibfd)
 
   if (!validate_build_id_style (emit_build_id))
     {
-      einfo (_("%P: warning: unrecognized --build-id style ignored\n"));
+      einfo (_("%P: %w: unrecognized --build-id style ignored\n"));
       return false;
     }
 
@@ -1444,7 +1444,7 @@ setup_build_id (bfd *ibfd)
       return true;
     }
 
-  einfo (_("%P: warning: cannot create .buildid section,"
+  einfo (_("%P: %w: cannot create .buildid section,"
 	   " --build-id ignored\n"));
   return false;
 }
@@ -2047,12 +2047,12 @@ gld${EMULATION_NAME}_finish (void)
 	  sprintf (buffer, "0x%" PRIx64, (uint64_t) val);
 
 	  if (entry_symbol.name != NULL && entry_from_cmdline)
-	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+	    einfo (_("%P: %w: '--thumb-entry %s' is overriding '-e %s'\n"),
 		   thumb_entry_symbol, entry_symbol.name);
 	  entry_symbol.name = buffer;
 	}
       else
-	einfo (_("%P: warning: cannot find thumb start symbol %s\n"), thumb_entry_symbol);
+	einfo (_("%P: %w: cannot find thumb start symbol %s\n"), thumb_entry_symbol);
     }
 #endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_wince_pe) */
 
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 00c4ea9e15a..2f8b7737bfe 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -600,7 +600,7 @@ set_pep_subsystem (void)
 	set_pep_name ("__minor_subsystem_version__",
 		      strtoul (end + 1, &end, 0));
       if (*end != '\0')
-	einfo (_("%P: warning: bad version number in -subsystem option\n"));
+	einfo (_("%P: %w: bad version number in -subsystem option\n"));
     }
 
   /* Check for numeric subsystem.  */
@@ -1010,7 +1010,7 @@ gld${EMULATION_NAME}_after_parse (void)
   /* PR ld/6744:  Warn the user if they have used an ELF-only
      option hoping it will work on PE+.  */
   if (link_info.export_dynamic)
-    einfo (_("%P: warning: --export-dynamic is not supported for PE+ "
+    einfo (_("%P: %w: --export-dynamic is not supported for PE+ "
       "targets, did you mean --export-all-symbols?\n"));
 
 #ifdef PDB_H
@@ -1062,7 +1062,7 @@ set_decoration (const char *undecorated_name,
 
   if (entry->decorated_link != NULL && !gave_warning_message)
     {
-      einfo (_("%P: warning: overwriting decorated name %s with %s\n"),
+      einfo (_("%P: %w: overwriting decorated name %s with %s\n"),
 	     entry->decorated_link->root.string, undecorated_name);
       gave_warning_message = true;
     }
@@ -1326,7 +1326,7 @@ write_build_id (bfd *abfd)
 
   if (!link_order)
     {
-      einfo (_("%P: warning: .buildid section discarded,"
+      einfo (_("%P: %w: .buildid section discarded,"
 	       " --build-id ignored\n"));
       return true;
     }
@@ -1419,7 +1419,7 @@ setup_build_id (bfd *ibfd)
 
   if (!validate_build_id_style (emit_build_id))
     {
-      einfo (_("%P: warning: unrecognized --build-id style ignored\n"));
+      einfo (_("%P: %w: unrecognized --build-id style ignored\n"));
       return false;
     }
 
@@ -1447,7 +1447,7 @@ setup_build_id (bfd *ibfd)
       return true;
     }
 
-  einfo (_("%P: warning: cannot create .buildid section,"
+  einfo (_("%P: %w: cannot create .buildid section,"
 	   " --build-id ignored\n"));
   return false;
 }
diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em
index 3508eb7f503..52454197bc6 100644
--- a/ld/emultempl/xtensaelf.em
+++ b/ld/emultempl/xtensaelf.em
@@ -271,7 +271,7 @@ replace_instruction_table_sections (bfd *abfd, asection *sec)
       if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
 					    &message))
 	{
-	  einfo (_("%P: warning: failed to convert %s table in %pB (%s); subsequent disassembly may be incomplete\n"),
+	  einfo (_("%P: %w: failed to convert %s table in %pB (%s); subsequent disassembly may be incomplete\n"),
 		 insn_sec_name, abfd, message);
 	}
     }
@@ -402,11 +402,11 @@ check_xtensa_info (bfd *abfd, asection *info_sec)
 					  &mismatch, &errmsg))
     {
       if (mismatch)
-	einfo (_("%P: %pB: warning: incompatible Xtensa configuration (%s)\n"),
+	einfo (_("%P: %pB: %w: incompatible Xtensa configuration (%s)\n"),
 	       abfd, errmsg);
     }
   else
-    einfo (_("%P: %pB: warning: cannot parse .xtensa.info section\n"), abfd);
+    einfo (_("%P: %pB: %w: cannot parse .xtensa.info section\n"), abfd);
 
   free (data);
 }
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 04045acbf3d..b314de3d388 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -263,7 +263,7 @@ ldelf_stat_needed (lang_input_statement_type *s)
 
   if (filename_ncmp (soname, global_needed->name,
 		     suffix - global_needed->name) == 0)
-    einfo (_("%P: warning: %s, needed by %pB, may conflict with %s\n"),
+    einfo (_("%P: %w: %s, needed by %pB, may conflict with %s\n"),
 	   global_needed->name, global_needed->by, soname);
 }
 
@@ -1186,7 +1186,7 @@ ldelf_handle_dt_needed (struct elf_link_hash_table *htab,
       if (force < 2)
 	continue;
 
-      einfo (_("%P: warning: %s, needed by %pB, not found "
+      einfo (_("%P: %w: %s, needed by %pB, not found "
 	       "(try using -rpath or -rpath-link)\n"),
 	     l->name, l->by);
     }
@@ -1400,7 +1400,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
 	    }
 	}
       if (warn_eh_frame)
-	einfo (_("%P: warning: cannot create .eh_frame_hdr section,"
+	einfo (_("%P: %w: cannot create .eh_frame_hdr section,"
 		 " --eh-frame-hdr ignored\n"));
     }
 
@@ -1448,7 +1448,7 @@ write_build_id (bfd *abfd)
   asec = t->o->build_id.sec;
   if (bfd_is_abs_section (asec->output_section))
     {
-      einfo (_("%P: warning: .note.gnu.build-id section discarded,"
+      einfo (_("%P: %w: .note.gnu.build-id section discarded,"
 	       " --build-id ignored\n"));
       return true;
     }
@@ -1497,7 +1497,7 @@ ldelf_setup_build_id (bfd *ibfd)
   size = id_note_section_size (ibfd);
   if (size == 0)
     {
-      einfo (_("%P: warning: unrecognized --build-id style ignored\n"));
+      einfo (_("%P: %w: unrecognized --build-id style ignored\n"));
       return false;
     }
 
@@ -1516,7 +1516,7 @@ ldelf_setup_build_id (bfd *ibfd)
       return true;
     }
 
-  einfo (_("%P: warning: cannot create .note.gnu.build-id section,"
+  einfo (_("%P: %w: cannot create .note.gnu.build-id section,"
 	   " --build-id ignored\n"));
   return false;
 }
@@ -1537,7 +1537,7 @@ write_package_metadata (bfd *abfd)
   asec = t->o->package_metadata.sec;
   if (bfd_is_abs_section (asec->output_section))
     {
-      einfo (_("%P: warning: .note.package section discarded,"
+      einfo (_("%P: %w: .note.package section discarded,"
 	       " --package-metadata ignored\n"));
       return true;
     }
@@ -1592,7 +1592,7 @@ ldelf_setup_package_metadata (bfd *ibfd)
   json_length = strlen (ldelf_emit_note_fdo_package_metadata);
   if (json_length == 0)
     {
-      einfo (_("%P: warning: --package-metadata is empty, ignoring\n"));
+      einfo (_("%P: %w: --package-metadata is empty, ignoring\n"));
       return false;
     }
 
@@ -1602,7 +1602,7 @@ ldelf_setup_package_metadata (bfd *ibfd)
 			     0, &json_error);
   if (!json)
     {
-      einfo (_("%P: warning: --package-metadata=%s does not contain valid "
+      einfo (_("%P: %w: --package-metadata=%s does not contain valid "
 	       "JSON, ignoring: %s\n"),
 	     ldelf_emit_note_fdo_package_metadata, json_error.text);
       return false;
@@ -1631,7 +1631,7 @@ ldelf_setup_package_metadata (bfd *ibfd)
       return true;
     }
 
-  einfo (_("%P: warning: cannot create .note.package section,"
+  einfo (_("%P: %w: cannot create .note.package section,"
 	   " --package-metadata ignored\n"));
   return false;
 }
diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c
index d3448546f3a..21d51c12407 100644
--- a/ld/ldelfgen.c
+++ b/ld/ldelfgen.c
@@ -417,7 +417,7 @@ ldelf_acquire_strings_for_ctf
     {
       if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
 			       &args) < 0)
-	einfo (_("%F%P: warning: CTF strtab association failed; strings will "
+	einfo (_("%F%P: %w: CTF strtab association failed; strings will "
 		 "not be shared: %s\n"),
 	       ctf_errmsg (ctf_errno (ctf_output)));
     }
@@ -444,7 +444,7 @@ ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
       lsym.st_value = sym->st_value;
       if (ctf_link_add_linker_symbol (ctf_output, &lsym) < 0)
 	{
-	  einfo (_("%F%P: warning: CTF symbol addition failed; CTF will "
+	  einfo (_("%F%P: %w: CTF symbol addition failed; CTF will "
 		   "not be tied to symbols: %s\n"),
 		 ctf_errmsg (ctf_errno (ctf_output)));
 	}
@@ -454,7 +454,7 @@ ldelf_new_dynsym_for_ctf (struct ctf_dict *ctf_output, int symidx,
       /* Shuffle all the symbols.  */
 
       if (ctf_link_shuffle_syms (ctf_output) < 0)
-	einfo (_("%F%P: warning: CTF symbol shuffling failed; CTF will "
+	einfo (_("%F%P: %w: CTF symbol shuffling failed; CTF will "
 		 "not be tied to symbols: %s\n"),
 	       ctf_errmsg (ctf_errno (ctf_output)));
     }
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 3c8ab2d3589..a767c082085 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -559,7 +559,7 @@ fold_binary (etree_type *tree)
 		&& config.magic_demand_paged
 		&& link_info.maxpagesize != 0
 		&& (seg->value % link_info.maxpagesize) != 0)
-	      einfo (_("%P: warning: address of `%s' "
+	      einfo (_("%P: %w: address of `%s' "
 		       "isn't multiple of maximum page size\n"),
 		     segment_name);
 	    seg->used = true;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 229401c8342..ea85ffd704b 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1411,13 +1411,13 @@ lang_memory_region_lookup (const char *const name, bool create)
       if (strcmp (n->name, name) == 0)
 	{
 	  if (create)
-	    einfo (_("%P:%pS: warning: redeclaration of memory region `%s'\n"),
+	    einfo (_("%P:%pS: %w: redeclaration of memory region `%s'\n"),
 		   NULL, name);
 	  return r;
 	}
 
   if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
-    einfo (_("%P:%pS: warning: memory region `%s' not declared\n"),
+    einfo (_("%P:%pS: %w: memory region `%s' not declared\n"),
 	   NULL, name);
 
   new_region = stat_alloc (sizeof (lang_memory_region_type));
@@ -2616,7 +2616,7 @@ wont_add_section_p (asection *section,
       else if (bfd_is_abs_section (section->output_section))
 	;
       else if (link_info.non_contiguous_regions_warnings)
-	einfo (_("%P:%pS: warning: --enable-non-contiguous-regions makes "
+	einfo (_("%P:%pS: %w: --enable-non-contiguous-regions makes "
 		 "section `%pA' from `%pB' match /DISCARD/ clause.\n"),
 	       NULL, section, section->owner);
 
@@ -2640,7 +2640,7 @@ wont_add_section_p (asection *section,
 	return true;
 
       if (link_info.non_contiguous_regions_warnings && output->bfd_section)
-	einfo (_("%P:%pS: warning: --enable-non-contiguous-regions may "
+	einfo (_("%P:%pS: %w: --enable-non-contiguous-regions may "
 		 "change behaviour for section `%pA' from `%pB' (assigned to "
 		 "%pA, but additional match: %pA)\n"),
 	       NULL, section, section->owner, section->output_section,
@@ -3418,7 +3418,7 @@ open_output (const char *name)
 		  /* Oh dear - we could not find any targets that
 		     satisfy our requirements.  */
 		  if (winner == NULL)
-		    einfo (_("%P: warning: could not find any targets"
+		    einfo (_("%P: %w: could not find any targets"
 			     " that match endianness requirement\n"));
 		  else
 		    output_target = winner->name;
@@ -3631,7 +3631,7 @@ open_input_bfds (lang_statement_union_type *s,
 		     naive user expectations.  */
 		  if (os_tail != lang_os_list.tail)
 		    {
-		      einfo (_("%P: warning: %s contains output sections;"
+		      einfo (_("%P: %w: %s contains output sections;"
 			       " did you forget -T?\n"),
 			     s->input_statement.filename);
 		      *stat_ptr->tail = add.head;
@@ -3718,7 +3718,7 @@ ldlang_open_ctf (void)
 	  if (err != ECTF_NOCTFDATA)
 	    {
 	      lang_ctf_errs_warnings (NULL);
-	      einfo (_("%P: warning: CTF section in %pB not loaded; "
+	      einfo (_("%P: %w: CTF section in %pB not loaded; "
 		       "its types will be discarded: %s\n"), file->the_bfd,
 		     ctf_errmsg (err));
 	    }
@@ -3747,7 +3747,7 @@ ldlang_open_ctf (void)
   if ((ctf_output = ctf_create (&err)) != NULL)
     return;
 
-  einfo (_("%P: warning: CTF output not created: `%s'\n"),
+  einfo (_("%P: %w: CTF output not created: `%s'\n"),
 	 ctf_errmsg (err));
 
   LANG_FOR_EACH_INPUT_STATEMENT (errfile)
@@ -3790,7 +3790,7 @@ lang_merge_ctf (void)
       /* Takes ownership of file->the_ctf.  */
       if (ctf_link_add_ctf (ctf_output, file->the_ctf, file->filename) < 0)
 	{
-	  einfo (_("%P: warning: CTF section in %pB cannot be linked: `%s'\n"),
+	  einfo (_("%P: %w: CTF section in %pB cannot be linked: `%s'\n"),
 		 file->the_bfd, ctf_errmsg (ctf_errno (ctf_output)));
 	  ctf_close (file->the_ctf);
 	  file->the_ctf = NULL;
@@ -3810,7 +3810,7 @@ lang_merge_ctf (void)
   if (ctf_link (ctf_output, flags) < 0)
     {
       lang_ctf_errs_warnings (ctf_output);
-      einfo (_("%P: warning: CTF linking failed; "
+      einfo (_("%P: %w: CTF linking failed; "
 	       "output will have no CTF section: %s\n"),
 	     ctf_errmsg (ctf_errno (ctf_output)));
       if (output_sect)
@@ -3881,7 +3881,7 @@ lang_write_ctf (int late)
       lang_ctf_errs_warnings (ctf_output);
       if (!output_sect->contents)
 	{
-	  einfo (_("%P: warning: CTF section emission failed; "
+	  einfo (_("%P: %w: CTF section emission failed; "
 		   "output will have no CTF section: %s\n"),
 		 ctf_errmsg (ctf_errno (ctf_output)));
 	  output_sect->size = 0;
@@ -3920,7 +3920,7 @@ ldlang_open_ctf (void)
 
       if ((sect = bfd_get_section_by_name (file->the_bfd, ".ctf")) != NULL)
 	{
-	    einfo (_("%P: warning: CTF section in %pB not linkable: "
+	    einfo (_("%P: %w: CTF section in %pB not linkable: "
 		     "%P was built without support for CTF\n"), file->the_bfd);
 	    sect->size = 0;
 	    sect->flags |= SEC_EXCLUDE;
@@ -5947,7 +5947,7 @@ lang_size_sections_1
 				   " for loadable section `%s'\n"),
 				 bfd_section_name (os->bfd_section));
 			else
-			  einfo (_("%P: warning: no memory region specified"
+			  einfo (_("%P: %w: no memory region specified"
 				   " for loadable section `%s'\n"),
 				 bfd_section_name (os->bfd_section));
 		      }
@@ -5981,7 +5981,7 @@ lang_size_sections_1
 		    if (diff != 0
 			&& (config.warn_section_align
 			    || os->addr_tree != NULL))
-		      einfo (_("%P: warning: "
+		      einfo (_("%P: %w: "
 			       "start of section %s changed by %ld\n"),
 			     os->name, (long) diff);
 		  }
@@ -6074,7 +6074,7 @@ lang_size_sections_1
 		       so people can fix their linker scripts.  */
 
 		    if (last->vma != last->lma)
-		      einfo (_("%P: warning: dot moved backwards "
+		      einfo (_("%P: %w: dot moved backwards "
 			       "before `%s'\n"), os->name);
 		  }
 		else
@@ -7161,7 +7161,7 @@ lang_end (void)
 	  if (ts != NULL)
 	    {
 	      if (warn)
-		einfo (_("%P: warning: cannot find entry symbol %s;"
+		einfo (_("%P: %w: cannot find entry symbol %s;"
 			 " defaulting to %V\n"),
 		       entry_symbol.name,
 		       bfd_section_vma (ts));
@@ -7172,7 +7172,7 @@ lang_end (void)
 	  else
 	    {
 	      if (warn)
-		einfo (_("%P: warning: cannot find entry symbol %s;"
+		einfo (_("%P: %w: cannot find entry symbol %s;"
 			 " not setting start address\n"),
 		       entry_symbol.name);
 	    }
@@ -7180,7 +7180,7 @@ lang_end (void)
       else
 	{
 	  if (warn)
-	    einfo (_("%P: warning: cannot find entry symbol %s;"
+	    einfo (_("%P: %w: cannot find entry symbol %s;"
 		     " not setting start address\n"),
 		   entry_symbol.name);
 	}
@@ -7429,7 +7429,7 @@ ldlang_place_orphan (asection *s)
 	}
 
       if (config.orphan_handling == orphan_handling_warn)
-	einfo (_("%P: warning: orphan section `%pA' from `%pB' being "
+	einfo (_("%P: %w: orphan section `%pA' from `%pB' being "
 		 "placed in section `%s'\n"),
 	       s, s->owner, os->name);
     }
@@ -8102,7 +8102,7 @@ warn_non_contiguous_discards (void)
       for (asection *s = file->the_bfd->sections; s != NULL; s = s->next)
 	if (s->output_section == NULL
 	    && (s->flags & SEC_LINKER_CREATED) == 0)
-	  einfo (_("%P: warning: --enable-non-contiguous-regions "
+	  einfo (_("%P: %w: --enable-non-contiguous-regions "
 		   "discards section `%pA' from `%pB'\n"),
 		 s, file->the_bfd);
     }
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 9ae541a5d82..6e4cb767033 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -1090,7 +1090,7 @@ multiple_definition (struct bfd_link_info *info,
       obfd = NULL;
     }
   if (info->warn_multiple_definition)
-    einfo (_("%P: %C: warning: multiple definition of `%pT'"),
+    einfo (_("%P: %C: %w: multiple definition of `%pT'"),
 	   nbfd, nsec, nval, name);
   else
     einfo (_("%X%P: %C: multiple definition of `%pT'"),
@@ -1154,11 +1154,11 @@ multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     {
       ASSERT (otype == bfd_link_hash_common);
       if (obfd != NULL)
-	einfo (_("%P: %pB: warning: definition of `%pT' overriding common"
+	einfo (_("%P: %pB: %w: definition of `%pT' overriding common"
 		 " from %pB\n"),
 	       nbfd, name, obfd);
       else
-	einfo (_("%P: %pB: warning: definition of `%pT' overriding common\n"),
+	einfo (_("%P: %pB: %w: definition of `%pT' overriding common\n"),
 	       nbfd, name);
     }
   else if (otype == bfd_link_hash_defined
@@ -1167,11 +1167,11 @@ multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     {
       ASSERT (ntype == bfd_link_hash_common);
       if (obfd != NULL)
-	einfo (_("%P: %pB: warning: common of `%pT' overridden by definition"
+	einfo (_("%P: %pB: %w: common of `%pT' overridden by definition"
 		 " from %pB\n"),
 	       nbfd, name, obfd);
       else
-	einfo (_("%P: %pB: warning: common of `%pT' overridden by definition\n"),
+	einfo (_("%P: %pB: %w: common of `%pT' overridden by definition\n"),
 	       nbfd, name);
     }
   else
@@ -1180,32 +1180,32 @@ multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
       if (osize > nsize)
 	{
 	  if (obfd != NULL)
-	    einfo (_("%P: %pB: warning: common of `%pT' overridden"
+	    einfo (_("%P: %pB: %w: common of `%pT' overridden"
 		     " by larger common from %pB\n"),
 		   nbfd, name, obfd);
 	  else
-	    einfo (_("%P: %pB: warning: common of `%pT' overridden"
+	    einfo (_("%P: %pB: %w: common of `%pT' overridden"
 		     " by larger common\n"),
 		   nbfd, name);
 	}
       else if (nsize > osize)
 	{
 	  if (obfd != NULL)
-	    einfo (_("%P: %pB: warning: common of `%pT' overriding"
+	    einfo (_("%P: %pB: %w: common of `%pT' overriding"
 		     " smaller common from %pB\n"),
 		   nbfd, name, obfd);
 	  else
-	    einfo (_("%P: %pB: warning: common of `%pT' overriding"
+	    einfo (_("%P: %pB: %w: common of `%pT' overriding"
 		     " smaller common\n"),
 		   nbfd, name);
 	}
       else
 	{
 	  if (obfd != NULL)
-	    einfo (_("%P: %pB and %pB: warning: multiple common of `%pT'\n"),
+	    einfo (_("%P: %pB and %pB: %w: multiple common of `%pT'\n"),
 		   nbfd, obfd, name);
 	  else
-	    einfo (_("%P: %pB: warning: multiple common of `%pT'\n"),
+	    einfo (_("%P: %pB: %w: multiple common of `%pT'\n"),
 		   nbfd, name);
 	}
     }
@@ -1224,7 +1224,7 @@ add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED,
 	    bfd_vma value)
 {
   if (config.warn_constructors)
-    einfo (_("%P: warning: global constructor %s used\n"),
+    einfo (_("%P: %w: global constructor %s used\n"),
 	   h->root.string);
 
   if (!config.build_constructors)
@@ -1260,7 +1260,7 @@ constructor_callback (struct bfd_link_info *info,
   char set_name[1 + sizeof "__CTOR_LIST__"];
 
   if (config.warn_constructors)
-    einfo (_("%P: warning: global constructor %s used\n"), name);
+    einfo (_("%P: %w: global constructor %s used\n"), name);
 
   if (!config.build_constructors)
     return;
@@ -1342,11 +1342,11 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     return;
 
   if (section != NULL)
-    einfo ("%P: %C: %s%s\n", abfd, section, address, _("warning: "), warning);
+    einfo ("%P: %C: %w: %s\n", abfd, section, address, warning);
   else if (abfd == NULL)
-    einfo ("%P: %s%s\n", _("warning: "), warning);
+    einfo ("%P: %w: %s\n", warning);
   else if (symbol == NULL)
-    einfo ("%P: %pB: %s%s\n", abfd, _("warning: "), warning);
+    einfo ("%P: %pB: %w: %s\n", abfd, warning);
   else if (!symbol_warning (warning, symbol, abfd))
     {
       bfd *b;
@@ -1354,7 +1354,7 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED,
       for (b = info->input_bfds; b; b = b->link.next)
 	if (b != abfd && symbol_warning (warning, symbol, b))
 	  return;
-      einfo ("%P: %pB: %s%s\n", abfd, _("warning: "), warning);
+      einfo ("%P: %pB: %w: %s\n", abfd, warning);
     }
 }
 
@@ -1397,7 +1397,7 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg)
 	  && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
 	{
 	  /* We found a reloc for the symbol we are looking for.  */
-	  einfo ("%P: %H: %s%s\n", abfd, sec, q->address, _("warning: "),
+	  einfo ("%P: %H: %w: %s\n", abfd, sec, q->address,
 		 info->warning);
 	  info->found = true;
 	  break;
@@ -1490,7 +1490,7 @@ undefined_symbol (struct bfd_link_info *info,
 	    einfo (_("%X%P: %H: undefined reference to `%pT'\n"),
 		   abfd, section, address, name);
 	  else
-	    einfo (_("%P: %H: warning: undefined reference to `%pT'\n"),
+	    einfo (_("%P: %H: %w: undefined reference to `%pT'\n"),
 		   abfd, section, address, name);
 	}
       else if (error_count == MAX_ERRORS_IN_A_ROW)
@@ -1499,7 +1499,7 @@ undefined_symbol (struct bfd_link_info *info,
 	    einfo (_("%X%P: %D: more undefined references to `%pT' follow\n"),
 		   abfd, section, address, name);
 	  else
-	    einfo (_("%P: %D: warning: more undefined references to `%pT' follow\n"),
+	    einfo (_("%P: %D: %w: more undefined references to `%pT' follow\n"),
 		   abfd, section, address, name);
 	}
       else if (error)
@@ -1513,7 +1513,7 @@ undefined_symbol (struct bfd_link_info *info,
 	    einfo (_("%X%P: %pB: undefined reference to `%pT'\n"),
 		   abfd, name);
 	  else
-	    einfo (_("%P: %pB: warning: undefined reference to `%pT'\n"),
+	    einfo (_("%P: %pB: %w: undefined reference to `%pT'\n"),
 		   abfd, name);
 	}
       else if (error_count == MAX_ERRORS_IN_A_ROW)
@@ -1522,7 +1522,7 @@ undefined_symbol (struct bfd_link_info *info,
 	    einfo (_("%X%P: %pB: more undefined references to `%pT' follow\n"),
 		   abfd, name);
 	  else
-	    einfo (_("%P: %pB: warning: more undefined references to `%pT' follow\n"),
+	    einfo (_("%P: %pB: %w: more undefined references to `%pT' follow\n"),
 		   abfd, name);
 	}
       else if (error)
diff --git a/ld/ldmisc.c b/ld/ldmisc.c
index 180b24b3448..69290190e6a 100644
--- a/ld/ldmisc.c
+++ b/ld/ldmisc.c
@@ -64,6 +64,7 @@
  %s arbitrary string, like printf
  %u integer, like printf
  %v hex bfd_vma, no leading zeros
+ %w "warning" if --fatal-warnings isn't used or "error" otherwise.
  %x integer, like printf
 */
 
@@ -266,6 +267,11 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
 	      }
 	      break;
 
+	    case 'w':
+	      fprintf (fp, "%s", (config.fatal_warnings
+				  ? _("error") : _("warning")));
+	      break;
+
 	    case 'W':
 	      /* hex bfd_vma with 0x with no leading zeroes taking up
 		 10 spaces (including the 0x).  */
@@ -687,7 +693,7 @@ output_unknown_cmdline_warnings (void)
       if (config.fatal_warnings)
 	einfo (_("%P: error: unsupported option: %s\n"), list->warning);
       else
-	einfo (_("%P: warning: %s ignored\n"), list->warning);
+	einfo (_("%P: %w: %s ignored\n"), list->warning);
       free (list->warning);
       free (list);
     }
diff --git a/ld/pdb.c b/ld/pdb.c
index 88639d539b7..bdedc738fbb 100644
--- a/ld/pdb.c
+++ b/ld/pdb.c
@@ -1008,7 +1008,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct datasym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_LDATA32/S_GDATA32/S_LTHREAD32/S_GTHREAD32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1027,7 +1027,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (name_len == len - offsetof (struct datasym, name))
 	      {
-		einfo (_("%P: warning: name for S_LDATA32/S_GDATA32/"
+		einfo (_("%P: %w: name for S_LDATA32/S_GDATA32/"
 			 "S_LTHREAD32/S_GTHREAD32 has no terminating"
 			 " zero\n"));
 		bfd_set_error (bfd_error_bad_value);
@@ -1075,7 +1075,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct procsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_GPROC32/S_LPROC32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1087,7 +1087,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (!endptr)
 	      {
-		einfo (_("%P: warning: could not find end of"
+		einfo (_("%P: %w: could not find end of"
 			 " S_GPROC32/S_LPROC32 record\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1113,7 +1113,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (name_len == len - offsetof (struct procsym, name))
 	      {
-		einfo (_("%P: warning: name for S_GPROC32/S_LPROC32 has no"
+		einfo (_("%P: %w: name for S_GPROC32/S_LPROC32 has no"
 			 " terminating zero\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1243,7 +1243,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct udtsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_UDT\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1254,7 +1254,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (name_len == len - offsetof (struct udtsym, name))
 	      {
-		einfo (_("%P: warning: name for S_UDT has no"
+		einfo (_("%P: %w: name for S_UDT has no"
 			 " terminating zero\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1291,7 +1291,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct constsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_CONSTANT\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1308,7 +1308,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 		if (param_len == 0)
 		  {
-		    einfo (_("%P: warning: unhandled type %v within"
+		    einfo (_("%P: %w: unhandled type %v within"
 			     " S_CONSTANT\n"), val);
 		    bfd_set_error (bfd_error_bad_value);
 		    return false;
@@ -1322,7 +1322,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (name_len == len - rec_size)
 	      {
-		einfo (_("%P: warning: name for S_CONSTANT has no"
+		einfo (_("%P: %w: name for S_CONSTANT has no"
 			 " terminating zero\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1382,7 +1382,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 		  break;
 
 		default:
-		  einfo (_("%P: warning: unexpected CodeView scope start"
+		  einfo (_("%P: %w: unexpected CodeView scope start"
 			   " record %v\n"), scope_start_type);
 		  bfd_set_error (bfd_error_bad_value);
 		  return false;
@@ -1404,7 +1404,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < sizeof (struct buildinfosym))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_BUILDINFO\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1430,7 +1430,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct blocksym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_BLOCK32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1442,7 +1442,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (!endptr)
 	      {
-		einfo (_("%P: warning: could not find end of"
+		einfo (_("%P: %w: could not find end of"
 			 " S_BLOCK32 record\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1467,7 +1467,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct bprelsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_BPREL32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1491,7 +1491,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct regsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_REGISTER\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1515,7 +1515,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct regrel, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_REGREL32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1539,7 +1539,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct localsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_LOCAL\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1565,7 +1565,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct inline_site, binary_annotations))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_INLINESITE\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1577,7 +1577,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (!endptr)
 	      {
-		einfo (_("%P: warning: could not find end of"
+		einfo (_("%P: %w: could not find end of"
 			 " S_INLINESITE record\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1610,7 +1610,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < offsetof (struct thunk, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_THUNK32\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1622,7 +1622,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (!endptr)
 	      {
-		einfo (_("%P: warning: could not find end of"
+		einfo (_("%P: %w: could not find end of"
 			 " S_THUNK32 record\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1647,7 +1647,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 
 	    if (len < sizeof (struct heap_alloc_site))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_HEAPALLOCSITE\n"));
 		bfd_set_error (bfd_error_bad_value);
 		return false;
@@ -1681,7 +1681,7 @@ parse_symbols (uint8_t *data, uint32_t size, uint8_t **buf,
 	  break;
 
 	default:
-	  einfo (_("%P: warning: unrecognized CodeView record %v\n"), type);
+	  einfo (_("%P: %w: unrecognized CodeView record %v\n"), type);
 	  bfd_set_error (bfd_error_bad_value);
 	  return false;
 	}
@@ -1717,7 +1717,7 @@ calculate_symbols_size (uint8_t *data, uint32_t size, uint32_t *sym_size)
 
 	    if (len < offsetof (struct datasym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_LDATA32/S_LTHREAD32\n"));
 		return false;
 	      }
@@ -1745,7 +1745,7 @@ calculate_symbols_size (uint8_t *data, uint32_t size, uint32_t *sym_size)
 
 	    if (len < offsetof (struct procsym, name))
 	      {
-		einfo (_("%P: warning: truncated CodeView record"
+		einfo (_("%P: %w: truncated CodeView record"
 			 " S_GPROC32/S_LPROC32\n"));
 		return false;
 	      }
@@ -1762,7 +1762,7 @@ calculate_symbols_size (uint8_t *data, uint32_t size, uint32_t *sym_size)
 
 		if (!endptr)
 		  {
-		    einfo (_("%P: warning: could not find end of"
+		    einfo (_("%P: %w: could not find end of"
 			     " S_GPROC32/S_LPROC32 record\n"));
 		    return false;
 		  }
@@ -1825,7 +1825,7 @@ calculate_symbols_size (uint8_t *data, uint32_t size, uint32_t *sym_size)
 	  break;
 
 	default:
-	  einfo (_("%P: warning: unrecognized CodeView record %v\n"), type);
+	  einfo (_("%P: %w: unrecognized CodeView record %v\n"), type);
 	  return false;
 	}
 
@@ -2219,7 +2219,7 @@ handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map,
 
   if (size < sizeof (struct lf_udt_src_line))
     {
-      einfo (_("%P: warning: truncated CodeView type record"
+      einfo (_("%P: %w: truncated CodeView type record"
 	       " LF_UDT_SRC_LINE\n"));
       return false;
     }
@@ -2232,7 +2232,7 @@ handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map,
       orig_type >= TPI_FIRST_INDEX + num_types ||
       !map[orig_type - TPI_FIRST_INDEX])
     {
-      einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE"
+      einfo (_("%P: %w: CodeView type record LF_UDT_SRC_LINE"
 	       " referred to unknown type %v\n"), orig_type);
       return false;
     }
@@ -2254,7 +2254,7 @@ handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map,
       source_file_type >= TPI_FIRST_INDEX + num_types ||
       !map[source_file_type - TPI_FIRST_INDEX])
     {
-      einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE"
+      einfo (_("%P: %w: CodeView type record LF_UDT_SRC_LINE"
 	       " referred to unknown string %v\n"), source_file_type);
       return false;
     }
@@ -2263,7 +2263,7 @@ handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map,
 
   if (bfd_getl16 (str_e->data + sizeof (uint16_t)) != LF_STRING_ID)
     {
-      einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE"
+      einfo (_("%P: %w: CodeView type record LF_UDT_SRC_LINE"
 	       " pointed to unexpected record type\n"));
       return false;
     }
@@ -2312,7 +2312,7 @@ handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map,
   if (*slot)
     {
       free (e);
-      einfo (_("%P: warning: duplicate CodeView type record "
+      einfo (_("%P: %w: duplicate CodeView type record "
 	       "LF_UDT_MOD_SRC_LINE\n"));
       return false;
     }
@@ -2361,7 +2361,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_modifier, modifier))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record "
+	    einfo (_("%P: %w: truncated CodeView type record "
 		     "LF_MODIFIER\n"));
 	    return false;
 	  }
@@ -2378,7 +2378,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_pointer, attributes))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_POINTER\n"));
 	    return false;
 	  }
@@ -2395,7 +2395,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < sizeof (struct lf_procedure))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_PROCEDURE\n"));
 	    return false;
 	  }
@@ -2415,7 +2415,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < sizeof (struct lf_procedure))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_MFUNCTION\n"));
 	    return false;
 	  }
@@ -2443,7 +2443,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_arglist, args))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_ARGLIST\n"));
 	    return false;
 	  }
@@ -2453,7 +2453,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 	if (size < offsetof (struct lf_arglist, args)
 		   + (num_entries * sizeof (uint32_t)))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_ARGLIST\n"));
 	    return false;
 	  }
@@ -2478,7 +2478,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (left < sizeof (uint16_t))
 	      {
-		einfo (_("%P: warning: truncated CodeView type record"
+		einfo (_("%P: %w: truncated CodeView type record"
 			 " LF_FIELDLIST\n"));
 		return false;
 	      }
@@ -2495,7 +2495,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_member, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_MEMBER\n"));
 		      return false;
 		    }
@@ -2514,7 +2514,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (param_len == 0)
 			{
-			  einfo (_("%P: warning: unhandled type %v within"
+			  einfo (_("%P: %w: unhandled type %v within"
 				   " LF_MEMBER\n"), offset);
 			  return false;
 			}
@@ -2523,7 +2523,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (left < subtype_len)
 			{
-			  einfo (_("%P: warning: truncated CodeView type record"
+			  einfo (_("%P: %w: truncated CodeView type record"
 				  " LF_MEMBER\n"));
 			  return false;
 			}
@@ -2534,7 +2534,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (name_len == left - offsetof (struct lf_member, name))
 		    {
-		      einfo (_("%P: warning: name for LF_MEMBER has no"
+		      einfo (_("%P: %w: name for LF_MEMBER has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2548,7 +2548,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_FIELDLIST\n"));
 		      return false;
 		    }
@@ -2567,7 +2567,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_enumerate, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_ENUMERATE\n"));
 		      return false;
 		    }
@@ -2583,14 +2583,14 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (param_len == 0)
 			{
-			  einfo (_("%P: warning: unhandled type %v within"
+			  einfo (_("%P: %w: unhandled type %v within"
 				   " LF_ENUMERATE\n"), val);
 			  return false;
 			}
 
 		      if (left < subtype_len + param_len)
 			{
-			  einfo (_("%P: warning: truncated CodeView type"
+			  einfo (_("%P: %w: truncated CodeView type"
 				   " record LF_ENUMERATE\n"));
 			  return false;
 			}
@@ -2603,7 +2603,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (name_len == left - offsetof (struct lf_enumerate, name))
 		    {
-		      einfo (_("%P: warning: name for LF_ENUMERATE has no"
+		      einfo (_("%P: %w: name for LF_ENUMERATE has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2617,7 +2617,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_ENUMERATE\n"));
 		      return false;
 		    }
@@ -2634,7 +2634,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < sizeof (struct lf_index))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_INDEX\n"));
 		      return false;
 		    }
@@ -2655,7 +2655,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_onemethod, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_ONEMETHOD\n"));
 		      return false;
 		    }
@@ -2670,7 +2670,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (name_len == left - offsetof (struct lf_onemethod, name))
 		    {
-		      einfo (_("%P: warning: name for LF_ONEMETHOD has no"
+		      einfo (_("%P: %w: name for LF_ONEMETHOD has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2685,7 +2685,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_FIELDLIST\n"));
 		      return false;
 		    }
@@ -2703,7 +2703,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_method, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_METHOD\n"));
 		      return false;
 		    }
@@ -2718,7 +2718,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (name_len == left - offsetof (struct lf_method, name))
 		    {
-		      einfo (_("%P: warning: name for LF_METHOD has no"
+		      einfo (_("%P: %w: name for LF_METHOD has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2732,7 +2732,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_FIELDLIST\n"));
 		      return false;
 		    }
@@ -2751,7 +2751,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < sizeof (struct lf_bclass))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_BCLASS\n"));
 		      return false;
 		    }
@@ -2771,7 +2771,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (param_len == 0)
 			{
-			  einfo (_("%P: warning: unhandled type %v within"
+			  einfo (_("%P: %w: unhandled type %v within"
 				   " LF_BCLASS\n"), offset);
 			  return false;
 			}
@@ -2780,7 +2780,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (left < subtype_len)
 			{
-			  einfo (_("%P: warning: truncated CodeView type record"
+			  einfo (_("%P: %w: truncated CodeView type record"
 				   " LF_BCLASS\n"));
 			  return false;
 			}
@@ -2791,7 +2791,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_BCLASS\n"));
 		      return false;
 		    }
@@ -2808,7 +2808,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < sizeof (struct lf_vfunctab))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_VFUNCTAB\n"));
 		      return false;
 		    }
@@ -2831,7 +2831,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < sizeof (struct lf_vbclass))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_VBCLASS/LF_IVBCLASS\n"));
 		      return false;
 		    }
@@ -2856,7 +2856,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (param_len == 0)
 			{
-			  einfo (_("%P: warning: unhandled type %v within"
+			  einfo (_("%P: %w: unhandled type %v within"
 				   " LF_VBCLASS/LF_IVBCLASS\n"), offset);
 			  return false;
 			}
@@ -2865,7 +2865,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (left < subtype_len)
 			{
-			  einfo (_("%P: warning: truncated CodeView type record"
+			  einfo (_("%P: %w: truncated CodeView type record"
 				   " LF_VBCLASS/LF_IVBCLASS\n"));
 			  return false;
 			}
@@ -2881,7 +2881,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (param_len == 0)
 			{
-			  einfo (_("%P: warning: unhandled type %v within"
+			  einfo (_("%P: %w: unhandled type %v within"
 				   " LF_VBCLASS/LF_IVBCLASS\n"), offset);
 			  return false;
 			}
@@ -2890,7 +2890,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		      if (left < subtype_len)
 			{
-			  einfo (_("%P: warning: truncated CodeView type record"
+			  einfo (_("%P: %w: truncated CodeView type record"
 				   " LF_VBCLASS/LF_IVBCLASS\n"));
 			  return false;
 			}
@@ -2901,7 +2901,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_VBCLASS/LF_IVBCLASS\n"));
 		      return false;
 		    }
@@ -2920,7 +2920,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_static_member, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_STMEMBER\n"));
 		      return false;
 		    }
@@ -2935,7 +2935,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 		  if (name_len == left
 				  - offsetof (struct lf_static_member, name))
 		    {
-		      einfo (_("%P: warning: name for LF_STMEMBER has no"
+		      einfo (_("%P: %w: name for LF_STMEMBER has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2950,7 +2950,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_FIELDLIST\n"));
 		      return false;
 		    }
@@ -2968,7 +2968,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < offsetof (struct lf_nest_type, name))
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_NESTTYPE\n"));
 		      return false;
 		    }
@@ -2982,7 +2982,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (name_len == left - offsetof (struct lf_nest_type, name))
 		    {
-		      einfo (_("%P: warning: name for LF_NESTTYPE has no"
+		      einfo (_("%P: %w: name for LF_NESTTYPE has no"
 			       " terminating zero\n"));
 		      return false;
 		    }
@@ -2997,7 +2997,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 		  if (left < subtype_len)
 		    {
-		      einfo (_("%P: warning: truncated CodeView type record"
+		      einfo (_("%P: %w: truncated CodeView type record"
 			       " LF_FIELDLIST\n"));
 		      return false;
 		    }
@@ -3009,7 +3009,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 		}
 
 	      default:
-		einfo (_("%P: warning: unrecognized CodeView subtype %v\n"),
+		einfo (_("%P: %w: unrecognized CodeView subtype %v\n"),
 		       subtype);
 		return false;
 	      }
@@ -3024,7 +3024,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_bitfield, length))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_BITFIELD\n"));
 	    return false;
 	  }
@@ -3042,7 +3042,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_methodlist, entries))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_METHODLIST\n"));
 	    return false;
 	  }
@@ -3050,7 +3050,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 	if ((size - offsetof (struct lf_methodlist, entries))
 	    % sizeof (struct lf_methodlist_entry))
 	  {
-	    einfo (_("%P: warning: malformed CodeView type record"
+	    einfo (_("%P: %w: malformed CodeView type record"
 		     " LF_METHODLIST\n"));
 	    return false;
 	  }
@@ -3074,7 +3074,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_array, length_in_bytes))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_ARRAY\n"));
 	    return false;
 	  }
@@ -3097,7 +3097,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_class, name))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_CLASS/LF_STRUCTURE\n"));
 	    return false;
 	  }
@@ -3122,7 +3122,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (param_len == 0)
 	      {
-		einfo (_("%P: warning: unhandled type %v within"
+		einfo (_("%P: %w: unhandled type %v within"
 			 " LF_CLASS/LF_STRUCTURE\n"), num_bytes);
 		return false;
 	      }
@@ -3131,7 +3131,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (size < name_off)
 	      {
-		einfo (_("%P: warning: truncated CodeView type record"
+		einfo (_("%P: %w: truncated CodeView type record"
 			 " LF_CLASS/LF_STRUCTURE\n"));
 		return false;
 	      }
@@ -3141,7 +3141,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (name_len == size - name_off)
 	  {
-	    einfo (_("%P: warning: name for LF_CLASS/LF_STRUCTURE has no"
+	    einfo (_("%P: %w: name for LF_CLASS/LF_STRUCTURE has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3160,7 +3160,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (unique_name_len == size - len)
 	      {
-		einfo (_("%P: warning: unique name for LF_CLASS/LF_STRUCTURE"
+		einfo (_("%P: %w: unique name for LF_CLASS/LF_STRUCTURE"
 			 " has no terminating zero\n"));
 		return false;
 	      }
@@ -3184,7 +3184,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_union, name))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_UNION\n"));
 	    return false;
 	  }
@@ -3203,7 +3203,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (param_len == 0)
 	      {
-		einfo (_("%P: warning: unhandled type %v within"
+		einfo (_("%P: %w: unhandled type %v within"
 			 " LF_UNION\n"), num_bytes);
 		return false;
 	      }
@@ -3212,7 +3212,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (size < name_off)
 	      {
-		einfo (_("%P: warning: truncated CodeView type record"
+		einfo (_("%P: %w: truncated CodeView type record"
 			 " LF_UNION\n"));
 		return false;
 	      }
@@ -3222,7 +3222,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (name_len == size - name_off)
 	  {
-	    einfo (_("%P: warning: name for LF_UNION has no"
+	    einfo (_("%P: %w: name for LF_UNION has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3241,7 +3241,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (unique_name_len == size - len)
 	      {
-		einfo (_("%P: warning: unique name for LF_UNION has"
+		einfo (_("%P: %w: unique name for LF_UNION has"
 			 " no terminating zero\n"));
 		return false;
 	      }
@@ -3265,7 +3265,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_enum, name))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_ENUM\n"));
 	    return false;
 	  }
@@ -3280,7 +3280,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (name_len == size - offsetof (struct lf_enum, name))
 	  {
-	    einfo (_("%P: warning: name for LF_ENUM has no"
+	    einfo (_("%P: %w: name for LF_ENUM has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3298,7 +3298,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	    if (unique_name_len == size - len)
 	      {
-		einfo (_("%P: warning: unique name for LF_ENUM has"
+		einfo (_("%P: %w: unique name for LF_ENUM has"
 			 " no terminating zero\n"));
 		return false;
 	      }
@@ -3317,7 +3317,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_vftable, names))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_VFTABLE\n"));
 	    return false;
 	  }
@@ -3338,7 +3338,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_string_id, string))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_STRING_ID\n"));
 	    return false;
 	  }
@@ -3351,7 +3351,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (string_len == size - offsetof (struct lf_string_id, string))
 	  {
-	    einfo (_("%P: warning: string for LF_STRING_ID has no"
+	    einfo (_("%P: %w: string for LF_STRING_ID has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3368,7 +3368,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_arglist, args))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_SUBSTR_LIST\n"));
 	    return false;
 	  }
@@ -3378,7 +3378,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 	if (size < offsetof (struct lf_arglist, args)
 		   + (num_entries * sizeof (uint32_t)))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_SUBSTR_LIST\n"));
 	    return false;
 	  }
@@ -3401,7 +3401,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_build_info, strings))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_BUILDINFO\n"));
 	    return false;
 	  }
@@ -3411,7 +3411,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 	if (size < offsetof (struct lf_build_info, strings)
 		   + (num_entries * sizeof (uint32_t)))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_BUILDINFO\n"));
 	    return false;
 	  }
@@ -3434,7 +3434,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_func_id, name))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_FUNC_ID\n"));
 	    return false;
 	  }
@@ -3450,7 +3450,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (name_len == size - offsetof (struct lf_func_id, name))
 	  {
-	    einfo (_("%P: warning: string for LF_FUNC_ID has no"
+	    einfo (_("%P: %w: string for LF_FUNC_ID has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3467,7 +3467,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (size < offsetof (struct lf_mfunc_id, name))
 	  {
-	    einfo (_("%P: warning: truncated CodeView type record"
+	    einfo (_("%P: %w: truncated CodeView type record"
 		     " LF_MFUNC_ID\n"));
 	    return false;
 	  }
@@ -3483,7 +3483,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 
 	if (name_len == size - offsetof (struct lf_mfunc_id, name))
 	  {
-	    einfo (_("%P: warning: string for LF_MFUNC_ID has no"
+	    einfo (_("%P: %w: string for LF_MFUNC_ID has no"
 		     " terminating zero\n"));
 	    return false;
 	  }
@@ -3498,7 +3498,7 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num,
 				  ids, mod_num, strings);
 
     default:
-      einfo (_("%P: warning: unrecognized CodeView type %v\n"), type);
+      einfo (_("%P: %w: unrecognized CodeView type %v\n"), type);
       return false;
     }
 
@@ -3672,7 +3672,7 @@ create_linker_symbols (bfd *abfd, uint8_t **syms, uint32_t *sym_byte_size,
   cwdval = getcwd (NULL, 0);
   if (!cwdval)
     {
-      einfo (_("%P: warning: unable to get working directory\n"));
+      einfo (_("%P: %w: unable to get working directory\n"));
       return false;
     }
 
@@ -3680,7 +3680,7 @@ create_linker_symbols (bfd *abfd, uint8_t **syms, uint32_t *sym_byte_size,
 
   if (!exeval)
     {
-      einfo (_("%P: warning: unable to get program name\n"));
+      einfo (_("%P: %w: unable to get program name\n"));
       free (cwdval);
       return false;
     }
@@ -3689,7 +3689,7 @@ create_linker_symbols (bfd *abfd, uint8_t **syms, uint32_t *sym_byte_size,
 
   if (!pdbval)
     {
-      einfo (_("%P: warning: unable to get full path to PDB\n"));
+      einfo (_("%P: %w: unable to get full path to PDB\n"));
       free (exeval);
       free (cwdval);
       return false;
@@ -5145,7 +5145,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
   pdb = bfd_openw (pdb_name, "pdb");
   if (!pdb)
     {
-      einfo (_("%P: warning: cannot create PDB file: %E\n"));
+      einfo (_("%P: %w: cannot create PDB file: %E\n"));
       return false;
     }
 
@@ -5160,7 +5160,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!create_old_directory_stream (pdb))
     {
-      einfo (_("%P: warning: cannot create old directory stream "
+      einfo (_("%P: %w: cannot create old directory stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5169,7 +5169,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!info_stream)
     {
-      einfo (_("%P: warning: cannot create info stream "
+      einfo (_("%P: %w: cannot create info stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5178,7 +5178,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!tpi_stream)
     {
-      einfo (_("%P: warning: cannot create TPI stream "
+      einfo (_("%P: %w: cannot create TPI stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5187,7 +5187,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!dbi_stream)
     {
-      einfo (_("%P: warning: cannot create DBI stream "
+      einfo (_("%P: %w: cannot create DBI stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5196,7 +5196,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!ipi_stream)
     {
-      einfo (_("%P: warning: cannot create IPI stream "
+      einfo (_("%P: %w: cannot create IPI stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5205,7 +5205,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!names_stream)
     {
-      einfo (_("%P: warning: cannot create /names stream "
+      einfo (_("%P: %w: cannot create /names stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5214,7 +5214,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!sym_rec_stream)
     {
-      einfo (_("%P: warning: cannot create symbol record stream "
+      einfo (_("%P: %w: cannot create symbol record stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5223,14 +5223,14 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!publics_stream)
     {
-      einfo (_("%P: warning: cannot create publics stream "
+      einfo (_("%P: %w: cannot create publics stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
 
   if (!create_section_header_stream (pdb, abfd, &section_header_stream_num))
     {
-      einfo (_("%P: warning: cannot create section header stream "
+      einfo (_("%P: %w: cannot create section header stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
@@ -5249,7 +5249,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 			    sym_rec_stream_num, publics_stream_num,
 			    &strings, &types, &ids, sym_rec_stream, pdb_name))
     {
-      einfo (_("%P: warning: cannot populate DBI stream "
+      einfo (_("%P: %w: cannot populate DBI stream "
 	       "in PDB file: %E\n"));
       htab_delete (types.hashmap);
       htab_delete (ids.hashmap);
@@ -5258,7 +5258,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!populate_type_stream (pdb, tpi_stream, &types))
     {
-      einfo (_("%P: warning: cannot populate TPI stream "
+      einfo (_("%P: %w: cannot populate TPI stream "
 	       "in PDB file: %E\n"));
       htab_delete (types.hashmap);
       htab_delete (ids.hashmap);
@@ -5269,7 +5269,7 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!populate_type_stream (pdb, ipi_stream, &ids))
     {
-      einfo (_("%P: warning: cannot populate IPI stream "
+      einfo (_("%P: %w: cannot populate IPI stream "
 	       "in PDB file: %E\n"));
       htab_delete (ids.hashmap);
       goto end;
@@ -5281,21 +5281,21 @@ create_pdb_file (bfd *abfd, const char *pdb_name, const unsigned char *guid)
 
   if (!populate_names_stream (names_stream, &strings))
     {
-      einfo (_("%P: warning: cannot populate names stream "
+      einfo (_("%P: %w: cannot populate names stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
 
   if (!populate_publics_stream (publics_stream, abfd, sym_rec_stream))
     {
-      einfo (_("%P: warning: cannot populate publics stream "
+      einfo (_("%P: %w: cannot populate publics stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
 
   if (!populate_info_stream (pdb, info_stream, guid))
     {
-      einfo (_("%P: warning: cannot populate info stream "
+      einfo (_("%P: %w: cannot populate info stream "
 	       "in PDB file: %E\n"));
       goto end;
     }
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 95eef84f607..ea48fc6dced 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1493,7 +1493,7 @@ pe_find_data_imports (const char *symhead,
 		/* PR linker/4844.  */
 		if (!warned)
 		  {
-		    einfo (_("%P: warning: auto-importing has been activated "
+		    einfo (_("%P: %w: auto-importing has been activated "
 			     "without --enable-auto-import specified on the "
 			     "command line; this should work unless it "
 			     "involves constant data structures referencing "
diff --git a/ld/testsuite/ld-i386/pr28894.d b/ld/testsuite/ld-i386/pr28894.d
index a8d1111eb1f..cd667df39c6 100644
--- a/ld/testsuite/ld-i386/pr28894.d
+++ b/ld/testsuite/ld-i386/pr28894.d
@@ -1,3 +1,3 @@
 #as: --32
 #ld: -shared -melf_i386 --warn-shared-textrel --fatal-warnings
-#error: .*warning: creating DT_TEXTREL in a shared object
+#error: .*error: creating DT_TEXTREL in a shared object
diff --git a/ld/testsuite/ld-i386/warn1.d b/ld/testsuite/ld-i386/warn1.d
index c00fdb36dc1..5f4a967f23c 100644
--- a/ld/testsuite/ld-i386/warn1.d
+++ b/ld/testsuite/ld-i386/warn1.d
@@ -1,4 +1,4 @@
 #name: --warn-shared-textrel --fatal-warnings
 #as: --32
 #ld: -shared -melf_i386 --warn-shared-textrel --fatal-warnings
-#error: .*warning: creating DT_TEXTREL in a shared object
+#error: .*error: creating DT_TEXTREL in a shared object
