diff --git a/gas/Makefile.am b/gas/Makefile.am
index 0e98ca3ec85..fe92997129c 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -408,7 +408,8 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(srcdir)/config \
 # How to link with both our special library facilities
 # and the system's installed libraries.
 
-GASLIBS = @OPCODES_LIB@ ../bfd/libbfd.la ../libiberty/libiberty.a
+# FIXME:
+GASLIBS = @OPCODES_LIB@ ../bfd/libbfd.la ../libiberty/libiberty.a /home/david/coding-3/gcc-newgit-canvas-2023/build/gcc/libdiagnostics.so
 
 # Files to be copied away after each stage in building.
 STAGESTUFF = *.@OBJEXT@ $(noinst_PROGRAMS)
diff --git a/gas/Makefile.in b/gas/Makefile.in
index fae3a47c144..2161d68f9c7 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -885,7 +885,9 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(srcdir)/config \
 
 # How to link with both our special library facilities
 # and the system's installed libraries.
-GASLIBS = @OPCODES_LIB@ ../bfd/libbfd.la ../libiberty/libiberty.a
+
+# FIXME:
+GASLIBS = @OPCODES_LIB@ ../bfd/libbfd.la ../libiberty/libiberty.a /home/david/coding-3/gcc-newgit-canvas-2023/build/gcc/libdiagnostics.so
 
 # Files to be copied away after each stage in building.
 STAGESTUFF = *.@OBJEXT@ $(noinst_PROGRAMS)
diff --git a/gas/as.c b/gas/as.c
index 6839c841588..2a8ce3734a0 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -1300,6 +1300,7 @@ gas_early_init (int *argcp, char ***argvp)
 static void
 gas_init (void)
 {
+  messages_init ();
   symbol_begin ();
   frag_init ();
   subsegs_begin ();
@@ -1486,6 +1487,8 @@ main (int argc, char ** argv)
 
   input_scrub_end ();
 
+  messages_end ();
+
   /* Use xexit instead of return, because under VMS environments they
      may not place the same interpretation on the value given.  */
   if (had_errors () != 0)
diff --git a/gas/as.h b/gas/as.h
index 99ffe77afd2..9d878a87df5 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -474,6 +474,9 @@ void   as_bad_value_out_of_range (const char *, offsetT, offsetT, offsetT,
 void   print_version_id (void);
 char * app_push (void);
 
+void messages_init (void);
+void messages_end (void);
+
 /* Number of littlenums required to hold an extended precision number.	*/
 #define MAX_LITTLENUMS 6
 
diff --git a/gas/messages.c b/gas/messages.c
index 7c018acf69f..1854560dae7 100644
--- a/gas/messages.c
+++ b/gas/messages.c
@@ -21,6 +21,14 @@
 #include <limits.h>
 #include <signal.h>
 
+// FIXME: do some configury thing for this
+#define USE_LIBDIAGNOSTICS 1
+
+#if USE_LIBDIAGNOSTICS
+// FIXME: need to fix this path, obviously
+#include "/home/david/coding-3/gcc-newgit-canvas-2023/src/gcc/libdiagnostics.h"
+#endif
+
 /* If the system doesn't provide strsignal, we get it defined in
    libiberty but no declaration is supplied.  Because, reasons. */
 #if !defined (HAVE_STRSIGNAL) && !defined (strsignal)
@@ -101,6 +109,29 @@ had_warnings (void)
   return warning_count;
 }
 
+#if USE_LIBDIAGNOSTICS
+static diagnostic_manager *diag_mgr;
+#endif
+
+void messages_init (void)
+{
+#if USE_LIBDIAGNOSTICS
+  diag_mgr = diagnostic_manager_new ();
+  diagnostic_manager_add_text_sink (diag_mgr, stderr,
+				    DIAGNOSTIC_COLORIZE_IF_TTY);
+  diagnostic_manager_add_sarif_sink (diag_mgr, stderr,
+				     DIAGNOSTIC_SARIF_VERSION_2_1_0);
+#endif
+}
+
+void messages_end (void)
+{
+#if USE_LIBDIAGNOSTICS
+  diagnostic_manager_release (diag_mgr);
+  diag_mgr = NULL;
+#endif
+}
+
 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
    and exit with a nonzero error code.  */
 
@@ -182,6 +213,20 @@ as_warn_internal (const char *file, unsigned int line, char *buffer)
       context = true;
     }
 
+#if USE_LIBDIAGNOSTICS
+  const diagnostic_file *file_obj
+    = diagnostic_manager_new_file (diag_mgr, file, NULL);
+
+  const diagnostic_physical_location *loc
+    = diagnostic_manager_new_location_from_file_and_line (diag_mgr,
+							  file_obj,
+							  line);
+
+  diagnostic *d = diagnostic_begin (diag_mgr,
+				    DIAGNOSTIC_LEVEL_WARNING);
+  diagnostic_set_location (d, loc);
+  diagnostic_finish (d, "%s", buffer);
+#else
   identify (file);
   if (file)
     {
@@ -192,6 +237,7 @@ as_warn_internal (const char *file, unsigned int line, char *buffer)
     }
   else
     fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
+#endif /* #else clause of #if USE_LIBDIAGNOSTICS */
 
   if (context)
     as_report_context ();
@@ -256,6 +302,19 @@ as_bad_internal (const char *file, unsigned int line, char *buffer)
       context = true;
     }
 
+#if USE_LIBDIAGNOSTICS
+  const diagnostic_file *file_obj
+    = diagnostic_manager_new_file (diag_mgr, file, NULL);
+  const diagnostic_physical_location *loc
+    = diagnostic_manager_new_location_from_file_and_line (diag_mgr,
+							  file_obj,
+							  line);
+
+  diagnostic *d = diagnostic_begin (diag_mgr,
+				    DIAGNOSTIC_LEVEL_ERROR);
+  diagnostic_set_location (d, loc);
+  diagnostic_finish (d, "%s", buffer);
+#else
   identify (file);
   if (file)
     {
@@ -266,6 +325,7 @@ as_bad_internal (const char *file, unsigned int line, char *buffer)
     }
   else
     fprintf (stderr, "%s%s\n", _("Error: "), buffer);
+#endif /* #else clause of #if USE_LIBDIAGNOSTICS */
 
   if (context)
     as_report_context ();
