Skip to content

Commit 2783559

Browse files
committed
Parse and set Mach-O section type and attributes
1 parent 973ab0a commit 2783559

2 files changed

Lines changed: 83 additions & 29 deletions

File tree

src/constant.rs

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
];

src/debuginfo/unwind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl UnwindContext {
205205

206206
let mut data = DataDescription::new();
207207
data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
208-
data.set_segment_section("", ".gcc_except_table");
208+
data.set_segment_section("", ".gcc_except_table", 0);
209209

210210
for reloc in &gcc_except_table.relocs {
211211
match reloc.name {

0 commit comments

Comments
 (0)