From 6b47079884e9f816b1c4b9790718de6db3fe1bc2 Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Sat, 6 Jun 2020 16:08:21 +0200 Subject: [PATCH 1/6] Cranelift: Module data apis should allow specifying the object file section #1640 --- cranelift/module/src/data_context.rs | 8 ++++++ cranelift/object/src/backend.rs | 39 +++++++++++++++++----------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/cranelift/module/src/data_context.rs b/cranelift/module/src/data_context.rs index 94dbeb0b98..a20d734cd2 100644 --- a/cranelift/module/src/data_context.rs +++ b/cranelift/module/src/data_context.rs @@ -46,6 +46,8 @@ pub struct DataDescription { pub function_relocs: Vec<(CodeOffset, ir::FuncRef)>, /// Data addresses to write at specified offsets. pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>, + /// Object file section + pub section: Option<(std::string::String, std::string::String)> } /// This is to data objects what cranelift_codegen::Context is to functions. @@ -63,6 +65,7 @@ impl DataContext { data_decls: PrimaryMap::new(), function_relocs: vec![], data_relocs: vec![], + section: None }, } } @@ -90,6 +93,11 @@ impl DataContext { self.description.init = Init::Bytes { contents }; } + /// Override the segment/section for data, only supported on Object backend + pub fn set_section(&mut self, seg: &str, sec: &str) { + self.description.section = Some((std::string::String::from(seg), std::string::String::from(sec))) + } + /// Declare an external function import. /// /// Users of the `Module` API generally should call diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 664dd34ab2..665e8021e1 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -234,6 +234,7 @@ impl Backend for ObjectBackend { ref data_decls, ref function_relocs, ref data_relocs, + section: ref datasection } = data_ctx.description(); let reloc_size = match self.isa.triple().pointer_width().unwrap() { @@ -264,22 +265,30 @@ impl Backend for ObjectBackend { } let symbol = self.data_objects[data_id].unwrap(); - let section_kind = if let Init::Zeros { .. } = *init { - if tls { - StandardSection::UninitializedTls + let section = + if datasection.is_none() { + let section_kind = if let Init::Zeros { .. } = *init { + if tls { + StandardSection::UninitializedTls + } else { + StandardSection::UninitializedData + } + } else if tls { + StandardSection::Tls + } else if writable { + StandardSection::Data + } else if relocs.is_empty() { + StandardSection::ReadOnlyData + } else { + StandardSection::ReadOnlyDataWithRel + }; + self.object.section_id(section_kind) } else { - StandardSection::UninitializedData - } - } else if tls { - StandardSection::Tls - } else if writable { - StandardSection::Data - } else if relocs.is_empty() { - StandardSection::ReadOnlyData - } else { - StandardSection::ReadOnlyDataWithRel - }; - let section = self.object.section_id(section_kind); + let (seg, sec) = &datasection.as_ref().unwrap(); + self.object.add_section(seg.clone().into_bytes(), sec.clone().into_bytes(), + if writable { SectionKind::Data } else { SectionKind::ReadOnlyData } + ) + }; let align = u64::from(align.unwrap_or(1)); let offset = match *init { From 4ff01aa8989b5ff10766786b03b020b3e0e71799 Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Mon, 8 Jun 2020 07:22:36 +0200 Subject: [PATCH 2/6] Extra assertions and fix for Faerie. --- cranelift/faerie/src/backend.rs | 3 +++ cranelift/object/src/backend.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index 84352b2696..29ae59907f 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -211,8 +211,11 @@ impl Backend for FaerieBackend { ref data_decls, ref function_relocs, ref data_relocs, + section: ref datasection } = data_ctx.description(); + assert!(datasection.is_none(), "Custom sections not supported"); + for &(offset, id) in function_relocs { let to = &namespace.get_function_decl(&function_decls[id]).name; self.artifact diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 665e8021e1..7342839fd5 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -284,6 +284,7 @@ impl Backend for ObjectBackend { }; self.object.section_id(section_kind) } else { + assert!(!tls, "Tls data cannot be in named section"); let (seg, sec) = &datasection.as_ref().unwrap(); self.object.add_section(seg.clone().into_bytes(), sec.clone().into_bytes(), if writable { SectionKind::Data } else { SectionKind::ReadOnlyData } From 04492983d2c6487d7ff5cae95ff1624f3b485c96 Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Mon, 8 Jun 2020 19:19:20 +0200 Subject: [PATCH 3/6] Extra assertions and fix for SimpleJit. --- cranelift/simplejit/src/backend.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index fc22d62f92..f4c6af2da1 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -361,8 +361,11 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { ref data_decls, ref function_relocs, ref data_relocs, + section: ref datasection, } = data.description(); + assert!(datasection.is_none(), "Custom sections not supported"); + let size = init.size(); let storage = if writable { self.memory From 38531b8f426a5eb9c0b96dd2e83fa4e2ca917db5 Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Mon, 8 Jun 2020 19:56:21 +0200 Subject: [PATCH 4/6] Rust fmt fixes --- cranelift/faerie/src/backend.rs | 2 +- cranelift/module/src/data_context.rs | 9 +++-- cranelift/object/src/backend.rs | 51 +++++++++++++++------------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index 29ae59907f..192cf455f2 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -211,7 +211,7 @@ impl Backend for FaerieBackend { ref data_decls, ref function_relocs, ref data_relocs, - section: ref datasection + section: ref datasection, } = data_ctx.description(); assert!(datasection.is_none(), "Custom sections not supported"); diff --git a/cranelift/module/src/data_context.rs b/cranelift/module/src/data_context.rs index a20d734cd2..0b732b41f7 100644 --- a/cranelift/module/src/data_context.rs +++ b/cranelift/module/src/data_context.rs @@ -47,7 +47,7 @@ pub struct DataDescription { /// Data addresses to write at specified offsets. pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>, /// Object file section - pub section: Option<(std::string::String, std::string::String)> + pub section: Option<(std::string::String, std::string::String)>, } /// This is to data objects what cranelift_codegen::Context is to functions. @@ -65,7 +65,7 @@ impl DataContext { data_decls: PrimaryMap::new(), function_relocs: vec![], data_relocs: vec![], - section: None + section: None, }, } } @@ -95,7 +95,10 @@ impl DataContext { /// Override the segment/section for data, only supported on Object backend pub fn set_section(&mut self, seg: &str, sec: &str) { - self.description.section = Some((std::string::String::from(seg), std::string::String::from(sec))) + self.description.section = Some(( + std::string::String::from(seg), + std::string::String::from(sec), + )) } /// Declare an external function import. diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 7342839fd5..1b88023028 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -234,7 +234,7 @@ impl Backend for ObjectBackend { ref data_decls, ref function_relocs, ref data_relocs, - section: ref datasection + section: ref datasection, } = data_ctx.description(); let reloc_size = match self.isa.triple().pointer_width().unwrap() { @@ -265,31 +265,36 @@ impl Backend for ObjectBackend { } let symbol = self.data_objects[data_id].unwrap(); - let section = - if datasection.is_none() { - let section_kind = if let Init::Zeros { .. } = *init { - if tls { - StandardSection::UninitializedTls - } else { - StandardSection::UninitializedData - } - } else if tls { - StandardSection::Tls - } else if writable { - StandardSection::Data - } else if relocs.is_empty() { - StandardSection::ReadOnlyData + let section = if datasection.is_none() { + let section_kind = if let Init::Zeros { .. } = *init { + if tls { + StandardSection::UninitializedTls } else { - StandardSection::ReadOnlyDataWithRel - }; - self.object.section_id(section_kind) + StandardSection::UninitializedData + } + } else if tls { + StandardSection::Tls + } else if writable { + StandardSection::Data + } else if relocs.is_empty() { + StandardSection::ReadOnlyData } else { - assert!(!tls, "Tls data cannot be in named section"); - let (seg, sec) = &datasection.as_ref().unwrap(); - self.object.add_section(seg.clone().into_bytes(), sec.clone().into_bytes(), - if writable { SectionKind::Data } else { SectionKind::ReadOnlyData } - ) + StandardSection::ReadOnlyDataWithRel }; + self.object.section_id(section_kind) + } else { + assert!(!tls, "Tls data cannot be in named section"); + let (seg, sec) = &datasection.as_ref().unwrap(); + self.object.add_section( + seg.clone().into_bytes(), + sec.clone().into_bytes(), + if writable { + SectionKind::Data + } else { + SectionKind::ReadOnlyData + }, + ) + }; let align = u64::from(align.unwrap_or(1)); let offset = match *init { From 0b613caad159dd38d85dc6f1bacb719766c76610 Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Mon, 15 Jun 2020 20:46:04 +0200 Subject: [PATCH 5/6] Address concerns in pullrequests. --- Cargo.lock | 1 + cranelift/faerie/src/backend.rs | 6 ++++-- cranelift/module/src/data_context.rs | 14 ++++++++------ cranelift/object/Cargo.toml | 1 + cranelift/object/src/backend.rs | 10 ++++++---- cranelift/simplejit/src/backend.rs | 4 +--- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d73830f4f..0e769ed75b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,6 +489,7 @@ dependencies = [ name = "cranelift-object" version = "0.64.0" dependencies = [ + "anyhow", "cranelift-codegen", "cranelift-module", "object", diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index 192cf455f2..be2ad792cc 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -211,10 +211,12 @@ impl Backend for FaerieBackend { ref data_decls, ref function_relocs, ref data_relocs, - section: ref datasection, + ref custom_segment_section, } = data_ctx.description(); - assert!(datasection.is_none(), "Custom sections not supported"); + if let Some((segment, section)) = custom_segment_section { + return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!("Custom section not supported by cranelift-faerie: `{}:{}`", segment, section))); + } for &(offset, id) in function_relocs { let to = &namespace.get_function_decl(&function_decls[id]).name; diff --git a/cranelift/module/src/data_context.rs b/cranelift/module/src/data_context.rs index 0b732b41f7..56e8b36024 100644 --- a/cranelift/module/src/data_context.rs +++ b/cranelift/module/src/data_context.rs @@ -3,7 +3,9 @@ use cranelift_codegen::binemit::{Addend, CodeOffset}; use cranelift_codegen::entity::PrimaryMap; use cranelift_codegen::ir; +use std::borrow::ToOwned; use std::boxed::Box; +use std::string::String; use std::vec::Vec; /// This specifies how data is to be initialized. @@ -47,7 +49,7 @@ pub struct DataDescription { /// Data addresses to write at specified offsets. pub data_relocs: Vec<(CodeOffset, ir::GlobalValue, Addend)>, /// Object file section - pub section: Option<(std::string::String, std::string::String)>, + pub custom_segment_section: Option<(String, String)>, } /// This is to data objects what cranelift_codegen::Context is to functions. @@ -65,7 +67,7 @@ impl DataContext { data_decls: PrimaryMap::new(), function_relocs: vec![], data_relocs: vec![], - section: None, + custom_segment_section: None, }, } } @@ -94,10 +96,10 @@ impl DataContext { } /// Override the segment/section for data, only supported on Object backend - pub fn set_section(&mut self, seg: &str, sec: &str) { - self.description.section = Some(( - std::string::String::from(seg), - std::string::String::from(sec), + pub fn set_segment_section(&mut self, seg: &str, sec: &str) { + self.description.custom_segment_section = Some(( + seg.to_owned(), + sec.to_owned(), )) } diff --git a/cranelift/object/Cargo.toml b/cranelift/object/Cargo.toml index 8c4c44fc74..18429a5158 100644 --- a/cranelift/object/Cargo.toml +++ b/cranelift/object/Cargo.toml @@ -14,6 +14,7 @@ cranelift-module = { path = "../module", version = "0.64.0" } cranelift-codegen = { path = "../codegen", version = "0.64.0", default-features = false, features = ["std"] } object = { version = "0.18", default-features = false, features = ["write"] } target-lexicon = "0.10" +anyhow = "1.0" [badges] maintenance = { status = "experimental" } diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 1b88023028..5d0c0d0060 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -234,7 +234,7 @@ impl Backend for ObjectBackend { ref data_decls, ref function_relocs, ref data_relocs, - section: ref datasection, + ref custom_segment_section, } = data_ctx.description(); let reloc_size = match self.isa.triple().pointer_width().unwrap() { @@ -265,7 +265,7 @@ impl Backend for ObjectBackend { } let symbol = self.data_objects[data_id].unwrap(); - let section = if datasection.is_none() { + let section = if custom_segment_section.is_none() { let section_kind = if let Init::Zeros { .. } = *init { if tls { StandardSection::UninitializedTls @@ -283,8 +283,10 @@ impl Backend for ObjectBackend { }; self.object.section_id(section_kind) } else { - assert!(!tls, "Tls data cannot be in named section"); - let (seg, sec) = &datasection.as_ref().unwrap(); + if tls { + return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!("Custom section not supported for TLS"))); + } + let (seg, sec) = &custom_segment_section.as_ref().unwrap(); self.object.add_section( seg.clone().into_bytes(), sec.clone().into_bytes(), diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index f4c6af2da1..d8928f1529 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -361,11 +361,9 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { ref data_decls, ref function_relocs, ref data_relocs, - section: ref datasection, + custom_segment_section: _, } = data.description(); - assert!(datasection.is_none(), "Custom sections not supported"); - let size = init.size(); let storage = if writable { self.memory From b2549d1fde8a708701b2600943ff483e81ea187c Mon Sep 17 00:00:00 2001 From: Carlo Kok Date: Wed, 17 Jun 2020 06:46:58 +0200 Subject: [PATCH 6/6] Rust fmt fixes --- cranelift/faerie/src/backend.rs | 6 +++++- cranelift/module/src/data_context.rs | 5 +---- cranelift/object/src/backend.rs | 4 +++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index be2ad792cc..8fae42a0b4 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -215,7 +215,11 @@ impl Backend for FaerieBackend { } = data_ctx.description(); if let Some((segment, section)) = custom_segment_section { - return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!("Custom section not supported by cranelift-faerie: `{}:{}`", segment, section))); + return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!( + "Custom section not supported by cranelift-faerie: `{}:{}`", + segment, + section + ))); } for &(offset, id) in function_relocs { diff --git a/cranelift/module/src/data_context.rs b/cranelift/module/src/data_context.rs index 56e8b36024..bca8471a77 100644 --- a/cranelift/module/src/data_context.rs +++ b/cranelift/module/src/data_context.rs @@ -97,10 +97,7 @@ impl DataContext { /// Override the segment/section for data, only supported on Object backend pub fn set_segment_section(&mut self, seg: &str, sec: &str) { - self.description.custom_segment_section = Some(( - seg.to_owned(), - sec.to_owned(), - )) + self.description.custom_segment_section = Some((seg.to_owned(), sec.to_owned())) } /// Declare an external function import. diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 5d0c0d0060..4ec6522061 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -284,7 +284,9 @@ impl Backend for ObjectBackend { self.object.section_id(section_kind) } else { if tls { - return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!("Custom section not supported for TLS"))); + return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!( + "Custom section not supported for TLS" + ))); } let (seg, sec) = &custom_segment_section.as_ref().unwrap(); self.object.add_section(