Skip to content

Commit 64420b6

Browse files
committed
skip predefine_fn for naked functions
1 parent 2e24cdb commit 64420b6

File tree

4 files changed

+41
-32
lines changed

4 files changed

+41
-32
lines changed

compiler/rustc_codegen_llvm/src/mono_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
5858

5959
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
6060
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
61-
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
6261
llvm::set_linkage(lldecl, base::linkage_to_llvm(linkage));
62+
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
6363
base::set_link_section(lldecl, attrs);
6464
if (linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR)
6565
&& self.tcx.sess.target.supports_comdat()

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_attr::InstructionSetAttr;
2-
use rustc_middle::mir::mono::{MonoItem, MonoItemData, Visibility};
2+
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
33
use rustc_middle::mir::{Body, InlineAsmOperand};
44
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf};
55
use rustc_middle::ty::{Instance, TyCtxt};
@@ -153,6 +153,30 @@ fn prefix_and_suffix<'tcx>(
153153
("", "")
154154
};
155155

156+
let emit_fatal = |msg| tcx.dcx().span_fatal(tcx.def_span(instance.def_id()), msg);
157+
158+
// see https://godbolt.org/z/cPK4sxKor.
159+
// None means the default, which corresponds to internal linkage
160+
let linkage = match item_data.linkage {
161+
Linkage::External => Some(".globl"),
162+
Linkage::LinkOnceAny => Some(".weak"),
163+
Linkage::LinkOnceODR => Some(".weak"),
164+
Linkage::WeakAny => Some(".weak"),
165+
Linkage::WeakODR => Some(".weak"),
166+
Linkage::Internal => None,
167+
Linkage::Private => None,
168+
Linkage::Appending => emit_fatal("Only global variables can have appending linkage!"),
169+
Linkage::Common => emit_fatal("Functions may not have common linkage"),
170+
Linkage::AvailableExternally => {
171+
// this would make the function equal an extern definition
172+
emit_fatal("Functions may not have available_externally linkage")
173+
}
174+
Linkage::ExternalWeak => {
175+
// FIXME: actually this causes a SIGILL in LLVM
176+
emit_fatal("Functions may not have external weak linkage")
177+
}
178+
};
179+
156180
let mut begin = String::new();
157181
let mut end = String::new();
158182
match AsmBinaryFormat::from_target(&tcx.sess.target) {
@@ -171,7 +195,9 @@ fn prefix_and_suffix<'tcx>(
171195

172196
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
173197
writeln!(begin, ".balign {align}").unwrap();
174-
writeln!(begin, ".globl {asm_name}").unwrap();
198+
if let Some(linkage) = linkage {
199+
writeln!(begin, "{linkage} {asm_name}").unwrap();
200+
}
175201
if let Visibility::Hidden = item_data.visibility {
176202
writeln!(begin, ".hidden {asm_name}").unwrap();
177203
}
@@ -181,6 +207,8 @@ fn prefix_and_suffix<'tcx>(
181207
}
182208
writeln!(begin, "{asm_name}:").unwrap();
183209

210+
eprintln!("{}", &begin);
211+
184212
writeln!(end).unwrap();
185213
writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap();
186214
writeln!(end, ".popsection").unwrap();
@@ -192,7 +220,9 @@ fn prefix_and_suffix<'tcx>(
192220
let section = link_section.unwrap_or("__TEXT,__text".to_string());
193221
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
194222
writeln!(begin, ".balign {align}").unwrap();
195-
writeln!(begin, ".globl {asm_name}").unwrap();
223+
if let Some(linkage) = linkage {
224+
writeln!(begin, "{linkage} {asm_name}").unwrap();
225+
}
196226
if let Visibility::Hidden = item_data.visibility {
197227
writeln!(begin, ".private_extern {asm_name}").unwrap();
198228
}
@@ -208,7 +238,9 @@ fn prefix_and_suffix<'tcx>(
208238
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
209239
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
210240
writeln!(begin, ".balign {align}").unwrap();
211-
writeln!(begin, ".globl {asm_name}").unwrap();
241+
if let Some(linkage) = linkage {
242+
writeln!(begin, "{linkage} {asm_name}").unwrap();
243+
}
212244
writeln!(begin, ".def {asm_name}").unwrap();
213245
writeln!(begin, ".scl 2").unwrap();
214246
writeln!(begin, ".type 32").unwrap();

compiler/rustc_codegen_ssa/src/mono_item.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,12 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
137137
}
138138
MonoItem::Fn(instance) => {
139139
let attrs = cx.tcx().codegen_fn_attrs(instance.def_id());
140-
let linkage = if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
141-
linkage_info.into_naked_linkage()
140+
141+
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
142+
// do not define this function; it will become a global assembly block
142143
} else {
143-
linkage_info.into_linkage()
144+
cx.predefine_fn(instance, linkage_info.into_linkage(), visibility, symbol_name);
144145
};
145-
146-
cx.predefine_fn(instance, linkage, visibility, symbol_name);
147146
}
148147
MonoItem::GlobalAsm(..) => {}
149148
}

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -299,28 +299,6 @@ impl LinkageInfo {
299299
Self::ImplicitInternal => Linkage::Internal,
300300
}
301301
}
302-
303-
/// Linkage when the MonoItem is a naked function
304-
///
305-
/// Naked functions are generated as a separate declaration (effectively an extern fn) and
306-
/// definition (using global assembly). To link them together, some flavor of external linkage
307-
/// must be used.
308-
///
309-
/// This should be just an implementation detail of the backend, which is why this translation
310-
/// is made at the final moment.
311-
pub const fn into_naked_linkage(self) -> Linkage {
312-
match self {
313-
// promote Weak linkage to ExternalWeak
314-
Self::Explicit(Linkage::WeakAny | Linkage::WeakODR) => Linkage::ExternalWeak,
315-
Self::Explicit(linkage) => linkage,
316-
317-
// the "implicit" means that linkage is picked by the partitioning algorithm.
318-
// picking external should always be valid (given that we are in fact linking
319-
// to the global assembly in the same CGU)
320-
Self::ImplicitExternal => Linkage::External,
321-
Self::ImplicitInternal => Linkage::External,
322-
}
323-
}
324302
}
325303

326304
/// Specifies the linkage type for a `MonoItem`.

0 commit comments

Comments
 (0)