@@ -414,48 +414,60 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
414414 data. set_align ( alloc. align . bytes ( ) ) ;
415415
416416 if let Some ( section_name) = section_name {
417- let ( segment_name, section_name) = if tcx. sess . target . is_like_darwin {
417+ let ( segment_name, section_name, macho_flags ) = if tcx. sess . target . is_like_darwin {
418418 // See https://github.com/llvm/llvm-project/blob/main/llvm/lib/MC/MCSectionMachO.cpp
419419 let mut parts = section_name. as_str ( ) . split ( ',' ) ;
420- let Some ( segment_name) = parts. next ( ) else {
420+
421+ let section_err = |msg| -> ! {
421422 tcx. dcx ( ) . fatal ( format ! (
422- "#[link_section = \" {}\" ] is not valid for macos target: must be segment and section separated by comma" ,
423- section_name
424- ) ) ;
423+ "#[link_section = {section_name:?}] is not valid for Mach-O target: {msg}" ,
424+ ) )
425+ } ;
426+
427+ let Some ( segment_name) = parts. next ( ) else {
428+ section_err ( "must be segment and section separated by comma" ) ;
425429 } ;
430+
426431 let Some ( section_name) = parts. next ( ) else {
427- tcx. dcx ( ) . fatal ( format ! (
428- "#[link_section = \" {}\" ] is not valid for macos target: must be segment and section separated by comma" ,
429- section_name
430- ) ) ;
432+ section_err ( "must be segment and section separated by comma" ) ;
431433 } ;
432434 if section_name. len ( ) > 16 {
433- tcx. dcx ( ) . fatal ( format ! (
434- "#[link_section = \" {}\" ] is not valid for macos target: section name bigger than 16 bytes" ,
435- section_name
436- ) ) ;
435+ section_err ( "section name bigger than 16 bytes" ) ;
437436 }
437+
438438 let section_type = parts. next ( ) . unwrap_or ( "regular" ) ;
439- if section_type != "regular" && section_type != "cstring_literals" {
440- tcx. dcx ( ) . fatal ( format ! (
441- "#[link_section = \" {}\" ] is not supported: unsupported section type {}" ,
442- section_name, section_type,
443- ) ) ;
439+
440+ // The custom Mach-O section flags.
441+ // The flags are the section type packed together with the attributes.
442+ let mut macho_flags = if let Some ( ( _, val) ) =
443+ MACHO_SECTION_TYPES . iter ( ) . find ( |( name, _) | * name == section_type)
444+ {
445+ * val
446+ } else {
447+ section_err ( & format ! ( "unsupported section type {section_type:?}" ) ) ;
448+ } ;
449+
450+ if let Some ( section_attributes) = parts. next ( ) {
451+ for attr in section_attributes. split ( '+' ) {
452+ macho_flags |= if let Some ( ( _, val) ) =
453+ MACHO_SECTION_ATTRIBUTES . iter ( ) . find ( |( name, _) | * name == attr)
454+ {
455+ * val
456+ } else {
457+ section_err ( & format ! ( "unsupported section attribute {attr:?}" ) ) ;
458+ } ;
459+ }
444460 }
445- let _attrs = parts . next ( ) ;
461+
446462 if parts. next ( ) . is_some ( ) {
447- tcx. dcx ( ) . fatal ( format ! (
448- "#[link_section = \" {}\" ] is not valid for macos target: too many components" ,
449- section_name
450- ) ) ;
463+ section_err ( "too many components" ) ;
451464 }
452- // FIXME(bytecodealliance/wasmtime#8901) set S_CSTRING_LITERALS section type when
453- // cstring_literals is specified
454- ( segment_name, section_name)
465+
466+ ( segment_name, section_name, macho_flags)
455467 } else {
456- ( "" , section_name. as_str ( ) )
468+ ( "" , section_name. as_str ( ) , 0 )
457469 } ;
458- data. set_segment_section ( segment_name, section_name) ;
470+ data. set_segment_section ( segment_name, section_name, macho_flags ) ;
459471 }
460472
461473 let bytes = alloc. inspect_with_uninit_and_ptr_outside_interpreter ( 0 ..alloc. len ( ) ) . to_vec ( ) ;
@@ -649,3 +661,45 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
649661 }
650662 }
651663}
664+
665+ // We support the same custom section type / attrs naming as LLVM:
666+ // <https://github.com/llvm/llvm-project/blob/llvmorg-22.1.3/llvm/lib/MC/MCSectionMachO.cpp#L23-L91>
667+ // <https://github.com/llvm/llvm-project/blob/llvmorg-22.1.3/llvm/include/llvm/BinaryFormat/MachO.h#L120-L223>
668+ const MACHO_SECTION_TYPES : & [ ( & str , u32 ) ] = & [
669+ ( "regular" , object:: macho:: S_REGULAR ) ,
670+ ( "zerofill" , object:: macho:: S_ZEROFILL ) ,
671+ ( "cstring_literals" , object:: macho:: S_CSTRING_LITERALS ) ,
672+ ( "4byte_literals" , object:: macho:: S_4BYTE_LITERALS ) ,
673+ ( "8byte_literals" , object:: macho:: S_8BYTE_LITERALS ) ,
674+ ( "literal_pointers" , object:: macho:: S_LITERAL_POINTERS ) ,
675+ ( "non_lazy_symbol_pointers" , object:: macho:: S_NON_LAZY_SYMBOL_POINTERS ) ,
676+ ( "lazy_symbol_pointers" , object:: macho:: S_LAZY_SYMBOL_POINTERS ) ,
677+ ( "symbol_stubs" , object:: macho:: S_SYMBOL_STUBS ) ,
678+ ( "mod_init_funcs" , object:: macho:: S_MOD_INIT_FUNC_POINTERS ) ,
679+ ( "mod_term_funcs" , object:: macho:: S_MOD_TERM_FUNC_POINTERS ) ,
680+ ( "coalesced" , object:: macho:: S_COALESCED ) ,
681+ // S_GB_ZEROFILL (not supported by LLVM)
682+ ( "interposing" , object:: macho:: S_INTERPOSING ) ,
683+ ( "16byte_literals" , object:: macho:: S_16BYTE_LITERALS ) ,
684+ // S_DTRACE_DOF (not supported by LLVM)
685+ // S_LAZY_DYLIB_SYMBOL_POINTERS (not supported by LLVM)
686+ ( "thread_local_regular" , object:: macho:: S_THREAD_LOCAL_REGULAR ) ,
687+ ( "thread_local_zerofill" , object:: macho:: S_THREAD_LOCAL_ZEROFILL ) ,
688+ ( "thread_local_variables" , object:: macho:: S_THREAD_LOCAL_VARIABLES ) ,
689+ ( "thread_local_variable_pointers" , object:: macho:: S_THREAD_LOCAL_VARIABLE_POINTERS ) ,
690+ ( "thread_local_init_function_pointers" , object:: macho:: S_THREAD_LOCAL_INIT_FUNCTION_POINTERS ) ,
691+ // S_INIT_FUNC_OFFSETS (not supported by LLVM)
692+ ] ;
693+ const MACHO_SECTION_ATTRIBUTES : & [ ( & str , u32 ) ] = & [
694+ ( "pure_instructions" , object:: macho:: S_ATTR_PURE_INSTRUCTIONS ) ,
695+ ( "no_toc" , object:: macho:: S_ATTR_NO_TOC ) ,
696+ ( "strip_static_syms" , object:: macho:: S_ATTR_STRIP_STATIC_SYMS ) ,
697+ ( "no_dead_strip" , object:: macho:: S_ATTR_NO_DEAD_STRIP ) ,
698+ ( "live_support" , object:: macho:: S_ATTR_LIVE_SUPPORT ) ,
699+ ( "self_modifying_code" , object:: macho:: S_ATTR_SELF_MODIFYING_CODE ) ,
700+ ( "debug" , object:: macho:: S_ATTR_DEBUG ) ,
701+ // System settable attributes are not supported by LLVM:
702+ // S_ATTR_SOME_INSTRUCTIONS
703+ // S_ATTR_EXT_RELOC
704+ // S_ATTR_LOC_RELOC
705+ ] ;
0 commit comments