Repository: rust-lang/rust
File: compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs (Rust)

Code before:
            section_contents.extend_from_slice(vis_name.as_bytes());
            section_contents.extend_from_slice(&visualizer.src);

            // The final byte `0` tells GDB that the pretty printer has been
            // fully defined and can continue searching for additional
            // pretty printers.
            section_contents.extend_from_slice(b"\0");
        }

        unsafe {
            let section_contents = section_contents.as_slice();
            let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64);

            let section_var = cx
                .define_global(section_var_name, llvm_type)
                .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
            llvm::set_section(section_var, c".debug_gdb_scripts");
            llvm::set_initializer(section_var, cx.const_bytes(section_contents));
            llvm::LLVMSetGlobalConstant(section_var, llvm::True);
            llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global);
            llvm::set_linkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
            // This should make sure that the whole section is not larger than
            // the string it contains. Otherwise we get a warning from GDB.
            llvm::LLVMSetAlignment(section_var, 1);
            // Make sure that the linker doesn't optimize the global away.
            llvm::LLVMRustAppendToUsed(cx.llmod, section_var);
            section_var
        }
    })
}

pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
    let omit_gdb_pretty_printer_section =
        attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section);

    // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
    // ODR violations at link time, this section will not be emitted for rlibs since
    // each rlib could produce a different set of visualizers that would be embedded
    // in the `.debug_gdb_scripts` section. For that reason, we make sure that the
    // section is only emitted for leaf crates.
    let embed_visualizers = cx.tcx.crate_types().iter().any(|&crate_type| match crate_type {
        CrateType::Executable
        | CrateType::Dylib
        | CrateType::Cdylib
        | CrateType::Staticlib
        | CrateType::Sdylib => {
            // These are crate types for which we will embed pretty printers since they
            // are treated as leaf crates.
            true
        }
        CrateType::ProcMacro => {

Review comment (suggestion):
This can probably use `cx.add_used_global(section_var)` instead.

Code after:

        // Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
        // attribute.
        let visualizers = cx
            .tcx
            .debugger_visualizers(LOCAL_CRATE)
            .iter()
            .filter(|visualizer| {
                visualizer.visualizer_type == DebuggerVisualizerType::GdbPrettyPrinter
            })
            .collect::<BTreeSet<_>>();
        let crate_name = cx.tcx.crate_name(LOCAL_CRATE);
        for (index, visualizer) in visualizers.iter().enumerate() {
            // The initial byte `4` instructs GDB that the following pretty printer
            // is defined inline as opposed to in a standalone file.
            section_contents.extend_from_slice(b"\x04");
            let vis_name = format!("pretty-printer-{crate_name}-{index}\n");
            section_contents.extend_from_slice(vis_name.as_bytes());
            section_contents.extend_from_slice(&visualizer.src);

            // The final byte `0` tells GDB that the pretty printer has been
            // fully defined and can continue searching for additional
            // pretty printers.
            section_contents.extend_from_slice(b"\0");
        }

        unsafe {
            let section_contents = section_contents.as_slice();
            let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64);

            let section_var = cx
                .define_global(section_var_name, llvm_type)
                .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name));
            llvm::set_section(section_var, c".debug_gdb_scripts");
            llvm::set_initializer(section_var, cx.const_bytes(section_contents));
            llvm::LLVMSetGlobalConstant(section_var, llvm::True);
            llvm::set_unnamed_address(section_var, llvm::UnnamedAddr::Global);
            llvm::set_linkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
            // This should make sure that the whole section is not larger than
            // the string it contains. Otherwise we get a warning from GDB.
            llvm::LLVMSetAlignment(section_var, 1);
            section_var
        }
    })
}

pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
    cx.sess().opts.debuginfo != DebugInfo::None && cx.sess().target.emit_debug_gdb_scripts
}