diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index c1b3f34e5a6d4..99e47bd030d64 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -832,7 +832,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
     .unwrap_or_default();
     let split_name = split_name.to_str().unwrap();
 
-    // FIXME(#60020):
+    // FIXME(#64405):
     //
     //    This should actually be
     //
@@ -847,7 +847,11 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
     //    the emission kind as `FullDebug`.
     //
     //    See https://github.com/rust-lang/rust/issues/60020 for details.
-    let kind = DebugEmissionKind::FullDebug;
+    let kind = if tcx.sess.opts.unstable_opts.force_full_debuginfo {
+        DebugEmissionKind::FullDebug
+    } else {
+        DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo)
+    };
     assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
 
     unsafe {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 014810dba9cce..6c28730c9f232 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -745,6 +745,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(export_executable_symbols, true);
     tracked!(fewer_names, Some(true));
     tracked!(flatten_format_args, true);
+    tracked!(force_full_debuginfo, false);
     tracked!(force_unstable_if_unmarked, true);
     tracked!(fuel, Some(("abc".to_string(), 99)));
     tracked!(function_sections, Some(false));
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 0548379dc2fc1..2e5b32c154008 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1425,6 +1425,8 @@ options! {
     flatten_format_args: bool = (false, parse_bool, [TRACKED],
         "flatten nested format_args!() and literals into a simplified format_args!() call \
         (default: no)"),
+    force_full_debuginfo: bool = (true, parse_bool, [TRACKED],
+        "force all codegen-units to have full debuginfo even for -C debuginfo=1. see #64405 (default: yes)"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
         "force all crates to be `rustc_private` unstable (default: no)"),
     fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
diff --git a/src/doc/unstable-book/src/compiler-flags/force-full-debuginfo.md b/src/doc/unstable-book/src/compiler-flags/force-full-debuginfo.md
new file mode 100644
index 0000000000000..23a74ee6c0f23
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/force-full-debuginfo.md
@@ -0,0 +1,16 @@
+# `force-full-debuginfo`
+
+The tracking issue for this feature is: [#64405](https://github.com/rust-lang/rust/issues/64405).
+
+---
+
+The option `-Z force-full-debuginfo` controls whether `-C debuginfo=1` generates full debug info for
+a codegen-unit.  Due to an oversight, debuginfo=1 (which should only mean "line tables") generated
+additional debuginfo for many years.  Due to backwards compatibility concerns, we are not yet
+changing that meaning, but instead adding this flag to allow opting-in to the new, reduced, debuginfo.
+
+Supported options for this value are:
+- `yes` - the default, include full debuginfo for the codegen unit
+- `no`  - include only line info for the codegen unit
+
+The default for this option may change in the future, but it is unlikely to be stabilized.
diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout
index 5ad38e4fd9821..ea028d7f6e278 100644
--- a/tests/rustdoc-ui/z-help.stdout
+++ b/tests/rustdoc-ui/z-help.stdout
@@ -45,6 +45,7 @@
     -Z                 extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no)
     -Z                           fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
     -Z                   flatten-format-args=val -- flatten nested format_args!() and literals into a simplified format_args!() call (default: no)
+    -Z                  force-full-debuginfo=val -- force all codegen-units to have full debuginfo even for -C debuginfo=1. see #64405 (default: yes)
     -Z            force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
     -Z                                  fuel=val -- set the optimization fuel quota for a crate
     -Z                     function-sections=val -- whether each function should go in its own section