Skip to content

Commit 049897a

Browse files
committed
Allow marking data objects as used for the linker
1 parent 10d3a22 commit 049897a

File tree

4 files changed

+47
-7
lines changed

4 files changed

+47
-7
lines changed

cranelift/jit/src/backend.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ impl Module for JITModule {
611611
data_relocs: _,
612612
custom_segment_section: _,
613613
align,
614+
used: _,
614615
} = data;
615616

616617
// Make sure to allocate at least 1 byte. Allocating 0 bytes is UB. Previously a dummy

cranelift/module/src/data_context.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Defines `DataContext`.
1+
//! Defines `DataDescription`.
22
33
use cranelift_codegen::binemit::{Addend, CodeOffset, Reloc};
44
use cranelift_codegen::entity::PrimaryMap;
@@ -62,9 +62,12 @@ pub struct DataDescription {
6262
pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>,
6363
/// Object file section
6464
pub custom_segment_section: Option<(String, String)>,
65-
/// Alignment in bytes. `None` means that the default alignment of the respective module should
66-
/// be used.
65+
/// Alignment in bytes. `None` means that the default alignment of the
66+
/// respective module should be used.
6767
pub align: Option<u64>,
68+
/// Whether or not to request the linker to preserve this data object even
69+
/// if not referenced.
70+
pub used: bool,
6871
}
6972

7073
impl DataDescription {
@@ -78,6 +81,7 @@ impl DataDescription {
7881
data_relocs: vec![],
7982
custom_segment_section: None,
8083
align: None,
84+
used: false,
8185
}
8286
}
8387

@@ -90,6 +94,7 @@ impl DataDescription {
9094
self.data_relocs.clear();
9195
self.custom_segment_section = None;
9296
self.align = None;
97+
self.used = false;
9398
}
9499

95100
/// Define a zero-initialized object with the given size.
@@ -117,6 +122,12 @@ impl DataDescription {
117122
self.align = Some(align);
118123
}
119124

125+
/// Set whether or not the linker should preserve this data object even if
126+
/// not referenced.
127+
pub fn set_used(&mut self, used: bool) {
128+
self.used = used;
129+
}
130+
120131
/// Declare an external function import.
121132
///
122133
/// Users of the `Module` API generally should call

cranelift/module/src/module.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ pub trait Module {
979979
relocs: &[ModuleReloc],
980980
) -> ModuleResult<()>;
981981

982-
/// Define a data object, producing the data contents from the given `DataContext`.
982+
/// Define a data object, producing the data contents from the given `DataDescription`.
983983
fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>;
984984
}
985985

cranelift/object/src/backend.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use object::write::{
1515
Object, Relocation, SectionId, StandardSection, Symbol, SymbolId, SymbolSection,
1616
};
1717
use object::{
18-
RelocationEncoding, RelocationFlags, RelocationKind, SectionKind, SymbolFlags, SymbolKind,
19-
SymbolScope,
18+
RelocationEncoding, RelocationFlags, RelocationKind, SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope
2019
};
2120
use std::collections::HashMap;
2221
use std::collections::hash_map::Entry;
@@ -394,6 +393,7 @@ impl Module for ObjectModule {
394393
data_relocs: _,
395394
ref custom_segment_section,
396395
align,
396+
used,
397397
} = data;
398398

399399
let pointer_reloc = match self.isa.triple().pointer_width().unwrap() {
@@ -422,7 +422,7 @@ impl Module for ObjectModule {
422422
} else {
423423
StandardSection::ReadOnlyDataWithRel
424424
};
425-
if self.per_data_object_section {
425+
if self.per_data_object_section || used {
426426
// FIXME pass empty symbol name once add_subsection produces `.text` as section name
427427
// instead of `.text.` when passed an empty symbol name. (object#748) Until then
428428
// pass `subsection` to produce `.text.subsection` as section name to reduce
@@ -451,6 +451,34 @@ impl Module for ObjectModule {
451451
)
452452
};
453453

454+
if used {
455+
match self.object.format() {
456+
object::BinaryFormat::Elf => {
457+
let section = self.object.section_mut(section);
458+
match &mut section.flags {
459+
SectionFlags::None => {
460+
section.flags = SectionFlags::Elf {
461+
sh_flags: object::elf::SHF_GNU_RETAIN.into(),
462+
}
463+
}
464+
SectionFlags::Elf { sh_flags } => {
465+
*sh_flags |= u64::from(object::elf::SHF_GNU_RETAIN)
466+
}
467+
_ => unreachable!(),
468+
}
469+
}
470+
object::BinaryFormat::Coff => {},
471+
object::BinaryFormat::MachO => {
472+
let symbol = self.object.symbol_mut(symbol);
473+
assert!(matches!(symbol.flags, SymbolFlags::None));
474+
symbol.flags = SymbolFlags::MachO {
475+
n_desc: object::macho::N_NO_DEAD_STRIP,
476+
}
477+
}
478+
_ => unreachable!(),
479+
}
480+
}
481+
454482
let align = std::cmp::max(align.unwrap_or(1), self.isa.symbol_alignment());
455483
let offset = match *init {
456484
Init::Uninitialized => {

0 commit comments

Comments
 (0)