Skip to content

Commit bc4aad3

Browse files
committed
naked-functions: properly document the -Zfunction-sections windows status
1 parent 25e1647 commit bc4aad3

2 files changed

Lines changed: 54 additions & 20 deletions

File tree

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt, TypeVisitableExt};
88
use rustc_middle::{bug, ty};
99
use rustc_span::sym;
1010
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
11-
use rustc_target::spec::{Arch, BinaryFormat};
11+
use rustc_target::spec::{Arch, BinaryFormat, Env};
1212

1313
use crate::common;
1414
use crate::mir::AsmCodegenMethods;
@@ -234,6 +234,8 @@ fn prefix_and_suffix<'tcx>(
234234
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
235235
} else if function_sections {
236236
writeln!(begin, ".pushsection .text.{asm_name},\"ax\", {progbits}").unwrap();
237+
} else {
238+
writeln!(begin, ".text").unwrap();
237239
}
238240
writeln!(begin, ".balign {align_bytes}").unwrap();
239241
write_linkage(&mut begin).unwrap();
@@ -261,7 +263,9 @@ fn prefix_and_suffix<'tcx>(
261263
}
262264
}
263265
BinaryFormat::MachO => {
264-
// NOTE: LLVM ignores `-Zfunction-sections` on macos.
266+
// NOTE: LLVM ignores `-Zfunction-sections` on macos. Instead the Mach-O symbol
267+
// subsection splitting feature is used, which can be enabled with the
268+
// `.subsections_via_symbols` global directive. LLVM already enables this directive.
265269
if let Some(section) = &link_section {
266270
writeln!(begin, ".pushsection {section},regular,pure_instructions").unwrap();
267271
}
@@ -289,9 +293,27 @@ fn prefix_and_suffix<'tcx>(
289293
writeln!(begin, ".endef").unwrap();
290294

291295
if let Some(section) = &link_section {
292-
writeln!(begin, ".pushsection {section},\"xr\"").unwrap()
293-
} else if function_sections {
294-
writeln!(begin, ".pushsection .text${asm_name},\"xr\"").unwrap()
296+
writeln!(begin, ".section {section},\"xr\"").unwrap()
297+
} else if !function_sections {
298+
// Function sections are enabled by default on MSVC, but disabled by default on GNU.
299+
writeln!(begin, ".text").unwrap();
300+
} else {
301+
// LLVM uses an extension to the section directive to support defining multiple
302+
// sections with the same name and comdat. It adds `unique,<id>` at the end of the
303+
// `.section` directive. We have no way of generating that unique ID here, so don't
304+
// emit it.
305+
//
306+
// See https://llvm.org/docs/Extensions.html#id2.
307+
match &tcx.sess.target.options.env {
308+
Env::Gnu => {
309+
writeln!(begin, ".section .text${asm_name},\"xr\",one_only,{asm_name}")
310+
.unwrap();
311+
}
312+
Env::Msvc => {
313+
writeln!(begin, ".section .text,\"xr\",one_only,{asm_name}").unwrap();
314+
}
315+
other => bug!("invalid coff env {other:?}"),
316+
}
295317
}
296318
write_linkage(&mut begin).unwrap();
297319
writeln!(begin, ".balign {align_bytes}").unwrap();

tests/codegen-llvm/naked-fn/naked-functions.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
// ignore-tidy-linelength
2+
//
13
//@ add-minicore
2-
//@ revisions: linux win_x86_msvc win_x86_gnu win_i686_gnu macos thumb
4+
//@ revisions: linux linux_no_function_sections macos thumb
5+
//@ revisions: win_x86_msvc win_x86_gnu win_i686_gnu win_x86_gnu_function_sections
36
//
47
//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
58
//@[linux] needs-llvm-components: x86
9+
//@[linux_no_function_sections] compile-flags: --target x86_64-unknown-linux-gnu -Zfunction-sections=false
10+
//@[linux_no_function_sections] needs-llvm-components: x86
611
//@[win_x86_gnu] compile-flags: --target x86_64-pc-windows-gnu
712
//@[win_x86_gnu] needs-llvm-components: x86
13+
//@[win_x86_gnu_function_sections] compile-flags: --target x86_64-pc-windows-gnu -Zfunction-sections
14+
//@[win_x86_gnu_function_sections] needs-llvm-components: x86
815
//@[win_x86_msvc] compile-flags: --target x86_64-pc-windows-msvc
916
//@[win_x86_msvc] needs-llvm-components: x86
1017
//@[win_i686_gnu] compile-flags: --target i686-pc-windows-gnu
@@ -21,20 +28,22 @@
2128
extern crate minicore;
2229
use minicore::*;
2330

24-
// linux,win_x86,win_i686: .intel_syntax
31+
// linux,win_x86_gnu,win_i686_gnu: .intel_syntax
2532
//
2633
// linux: .pushsection .text.naked_empty,\22ax\22, @progbits
34+
// linux_no_function_sections: .text
2735
// macos-NOT: .pushsection
2836
//
29-
// win_x86_msvc: .pushsection .text$naked_empty,\22xr\22
30-
// win_x86_gnu-NOT: .pushsection
31-
// win_i686_gnu-NOT: .pushsection
37+
// win_x86_msvc: .section .text,\22xr\22,one_only,naked_empty
38+
// win_x86_gnu_function_sections: .section .text$naked_empty,\22xr\22,one_only,naked_empty
39+
// win_x86_gnu-NOT: .section
40+
// win_i686_gnu-NOT: .section
3241
//
3342
// thumb: .pushsection .text.naked_empty,\22ax\22, %progbits
3443
//
3544
// linux, macos, thumb: .balign 4
3645
//
37-
// linux,thumb: .globl naked_empty
46+
// linux,win_x86_gnu,thumb: .globl naked_empty
3847
// macos: .globl _naked_empty
3948
//
4049
// CHECK-NOT: .private_extern
@@ -63,7 +72,7 @@ use minicore::*;
6372
//
6473
// CHECK-LABEL: naked_empty:
6574
//
66-
// linux,macos,win_x86,win_x86: ret
75+
// linux,macos,win_x86_msvc,win_x86_gnu,win_i686_gnu: ret
6776
// thumb: bx lr
6877
//
6978
// linux,windows,win_x86_msvc,thumb: .popsection
@@ -86,20 +95,22 @@ pub extern "C" fn naked_empty() {
8695
}
8796
}
8897

89-
// linux,win_x86,win_i686: .intel_syntax
98+
// linux,win_x86_gnu,win_i686_gnu,win_x86_msvc: .intel_syntax
9099
//
91100
// linux: .pushsection .text.naked_with_args_and_return,\22ax\22, @progbits
101+
// linux_no_function_sections: .text
92102
// macos-NOT: .pushsection
93103
//
94-
// win_x86_msvc: .pushsection .text$naked_with_args_and_return,\22xr\22
95-
// win_x86_gnu-NOT: .pushsection
96-
// win_i686_gnu-NOT: .pushsection
104+
// win_x86_msvc: .section .text,\22xr\22,one_only,naked_with_args_and_return
105+
// win_x86_gnu_function_sections: .section .text$naked_with_args_and_return,\22xr\22,one_only,naked_with_args_and_return
106+
// win_x86_gnu-NOT: .section
107+
// win_i686_gnu-NOT: .section
97108
//
98109
// thumb: .pushsection .text.naked_with_args_and_return,\22ax\22, %progbits
99110
//
100111
// linux, macos, thumb: .balign 4
101112
//
102-
// linux,thumb: .globl naked_with_args_and_return
113+
// linux,win_x86_gnu,win_x86_msvc,win_i686_gnu,thumb: .globl naked_with_args_and_return
103114
// macos: .globl _naked_with_args_and_return
104115
//
105116
// CHECK-NOT: .private_extern
@@ -132,7 +143,7 @@ pub extern "C" fn naked_empty() {
132143
// macos: add x0, x0, x1
133144
// thumb: adds r0, r0, r1
134145
//
135-
// linux,macos,win_x86,win_i686: ret
146+
// linux,macos,win_x86_msvc,win_x86_gnu,win_i686_gnu: ret
136147
// thumb: bx lr
137148
//
138149
// linux,windows,win_x86_msvc,thumb: .popsection
@@ -158,9 +169,10 @@ pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
158169
}
159170
}
160171

161-
// linux: .pushsection .text.some_different_name,\22ax\22, @progbits
172+
// linux,linux_no_function_sections: .pushsection .text.some_different_name,\22ax\22, @progbits
162173
// macos: .pushsection .text.some_different_name,regular,pure_instructions
163-
// win_x86_msvc,win_x86_gnu,win_i686_gnu: .pushsection .text.some_different_name,\22xr\22
174+
// win_x86_msvc,win_x86_gnu,win_i686_gnu: .section .text.some_different_name,\22xr\22
175+
// win_x86_gnu_function_sections: .section .text.some_different_name,\22xr\22
164176
// thumb: .pushsection .text.some_different_name,\22ax\22, %progbits
165177
// CHECK-LABEL: test_link_section:
166178
#[no_mangle]

0 commit comments

Comments
 (0)