diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index 843ef09a5842f..8ee55234cea43 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -63,8 +63,6 @@ use core::ptr::NonNull;
 use core::sync::atomic::{AtomicPtr, Ordering};
 use core::{mem, ptr};
 
-use crate::sys_common::util::dumb_print;
-
 #[stable(feature = "alloc_module", since = "1.28.0")]
 #[doc(inline)]
 pub use alloc_crate::alloc::*;
@@ -317,7 +315,7 @@ pub fn take_alloc_error_hook() -> fn(Layout) {
 }
 
 fn default_alloc_error_hook(layout: Layout) {
-    dumb_print(format_args!("memory allocation of {} bytes failed\n", layout.size()));
+    rtprintpanic!("memory allocation of {} bytes failed\n", layout.size());
 }
 
 #[cfg(not(test))]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index a8410bea7342b..02957e75a7409 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -20,7 +20,7 @@ use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::stdio::panic_output;
 use crate::sys_common::backtrace::{self, RustBacktrace};
 use crate::sys_common::rwlock::RWLock;
-use crate::sys_common::{thread_info, util};
+use crate::sys_common::thread_info;
 use crate::thread;
 
 #[cfg(not(test))]
@@ -596,15 +596,12 @@ fn rust_panic_with_hook(
         if panics > 2 {
             // Don't try to print the message in this case
             // - perhaps that is causing the recursive panics.
-            util::dumb_print(format_args!("thread panicked while processing panic. aborting.\n"));
+            rtprintpanic!("thread panicked while processing panic. aborting.\n");
         } else {
             // Unfortunately, this does not print a backtrace, because creating
             // a `Backtrace` will allocate, which we must to avoid here.
             let panicinfo = PanicInfo::internal_constructor(message, location);
-            util::dumb_print(format_args!(
-                "{}\npanicked after panic::always_abort(), aborting.\n",
-                panicinfo
-            ));
+            rtprintpanic!("{}\npanicked after panic::always_abort(), aborting.\n", panicinfo);
         }
         intrinsics::abort()
     }
@@ -637,7 +634,7 @@ fn rust_panic_with_hook(
         // have limited options. Currently our preference is to
         // just abort. In the future we may consider resuming
         // unwinding or otherwise exiting the thread cleanly.
-        util::dumb_print(format_args!("thread panicked while panicking. aborting.\n"));
+        rtprintpanic!("thread panicked while panicking. aborting.\n");
         intrinsics::abort()
     }
 
diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs
index 2a487fff54ae7..81f47a779d33b 100644
--- a/library/std/src/sys/unix/stack_overflow.rs
+++ b/library/std/src/sys/unix/stack_overflow.rs
@@ -42,6 +42,7 @@ mod imp {
     use crate::io;
     use crate::mem;
     use crate::ptr;
+    use crate::thread;
 
     use libc::MAP_FAILED;
     use libc::{mmap, munmap};
@@ -95,15 +96,16 @@ mod imp {
         info: *mut libc::siginfo_t,
         _data: *mut libc::c_void,
     ) {
-        use crate::sys_common::util::report_overflow;
-
         let guard = thread_info::stack_guard().unwrap_or(0..0);
         let addr = siginfo_si_addr(info);
 
         // If the faulting address is within the guard page, then we print a
         // message saying so and abort.
         if guard.start <= addr && addr < guard.end {
-            report_overflow();
+            rtprintpanic!(
+                "\nthread '{}' has overflowed its stack\n",
+                thread::current().name().unwrap_or("<unknown>")
+            );
             rtabort!("stack overflow");
         } else {
             // Unregister ourselves by reverting back to the default behavior.
diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs
index 39efb778207fc..755dc0a6c8b47 100644
--- a/library/std/src/sys/windows/stack_overflow.rs
+++ b/library/std/src/sys/windows/stack_overflow.rs
@@ -1,7 +1,7 @@
 #![cfg_attr(test, allow(dead_code))]
 
 use crate::sys::c;
-use crate::sys_common::util::report_overflow;
+use crate::thread;
 
 pub struct Handler;
 
@@ -24,7 +24,10 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -
         let code = rec.ExceptionCode;
 
         if code == c::EXCEPTION_STACK_OVERFLOW {
-            report_overflow();
+            rtprintpanic!(
+                "\nthread '{}' has overflowed its stack\n",
+                thread::current().name().unwrap_or("<unknown>")
+            );
         }
         c::EXCEPTION_CONTINUE_SEARCH
     }
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 7fa6977f2af26..4ef0e72adf020 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -40,7 +40,6 @@ pub mod thread_info;
 pub mod thread_local_dtor;
 pub mod thread_local_key;
 pub mod thread_parker;
-pub mod util;
 pub mod wtf8;
 
 cfg_if::cfg_if! {
diff --git a/library/std/src/sys_common/rt.rs b/library/std/src/sys_common/rt.rs
index c70f2ecc04e3a..02013ecc4ced6 100644
--- a/library/std/src/sys_common/rt.rs
+++ b/library/std/src/sys_common/rt.rs
@@ -1,4 +1,5 @@
 #![deny(unsafe_op_in_unsafe_fn)]
+#![allow(unused_macros)]
 
 use crate::sync::Once;
 use crate::sys;
@@ -38,8 +39,25 @@ pub fn cleanup() {
     });
 }
 
+// Prints to the "panic output", depending on the platform this may be:
+// - the standard error output
+// - some dedicated platform specific output
+// - nothing (so this macro is a no-op)
+macro_rules! rtprintpanic {
+    ($($t:tt)*) => {
+        if let Some(mut out) = crate::sys::stdio::panic_output() {
+            let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
+        }
+    }
+}
+
 macro_rules! rtabort {
-    ($($t:tt)*) => (crate::sys_common::util::abort(format_args!($($t)*)))
+    ($($t:tt)*) => {
+        {
+            rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*));
+            crate::sys::abort_internal();
+        }
+    }
 }
 
 macro_rules! rtassert {
@@ -50,7 +68,6 @@ macro_rules! rtassert {
     };
 }
 
-#[allow(unused_macros)] // not used on all platforms
 macro_rules! rtunwrap {
     ($ok:ident, $e:expr) => {
         match $e {
diff --git a/library/std/src/sys_common/util.rs b/library/std/src/sys_common/util.rs
deleted file mode 100644
index 9f7c3bd87952f..0000000000000
--- a/library/std/src/sys_common/util.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use crate::fmt;
-use crate::io::prelude::*;
-use crate::sys::stdio::panic_output;
-use crate::thread;
-
-pub fn dumb_print(args: fmt::Arguments<'_>) {
-    if let Some(mut out) = panic_output() {
-        let _ = out.write_fmt(args);
-    }
-}
-
-// Other platforms should use the appropriate platform-specific mechanism for
-// aborting the process.  If no platform-specific mechanism is available,
-// crate::intrinsics::abort() may be used instead.  The above implementations cover
-// all targets currently supported by libstd.
-
-pub fn abort(args: fmt::Arguments<'_>) -> ! {
-    dumb_print(format_args!("fatal runtime error: {}\n", args));
-    crate::sys::abort_internal();
-}
-
-#[allow(dead_code)] // stack overflow detection not enabled on all platforms
-pub unsafe fn report_overflow() {
-    dumb_print(format_args!(
-        "\nthread '{}' has overflowed its stack\n",
-        thread::current().name().unwrap_or("<unknown>")
-    ));
-}