6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -490,6 +490,7 @@ dependencies = [
|
||||
name = "cranelift-object"
|
||||
version = "0.65.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-module",
|
||||
"object",
|
||||
@@ -1223,13 +1224,12 @@ checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.18.0"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5666bbb90bc4d1e5bdcb26c0afda1822d25928341e9384ab187a9b37ab69e36"
|
||||
checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"indexmap",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -31,7 +31,7 @@ wasmtime-wast = { path = "crates/wast", version = "0.18.0" }
|
||||
wasmtime-wasi = { path = "crates/wasi", version = "0.18.0" }
|
||||
wasi-common = { path = "crates/wasi-common", version = "0.18.0" }
|
||||
structopt = { version = "0.3.5", features = ["color", "suggestions"] }
|
||||
object = { version = "0.18", default-features = false, features = ["write"] }
|
||||
object = { version = "0.19", default-features = false, features = ["write"] }
|
||||
anyhow = "1.0.19"
|
||||
target-lexicon = { version = "0.10.0", default-features = false }
|
||||
pretty_env_logger = "0.4.0"
|
||||
|
||||
@@ -12,8 +12,9 @@ edition = "2018"
|
||||
[dependencies]
|
||||
cranelift-module = { path = "../module", version = "0.65.0" }
|
||||
cranelift-codegen = { path = "../codegen", version = "0.65.0", default-features = false, features = ["std"] }
|
||||
object = { version = "0.18", default-features = false, features = ["write"] }
|
||||
object = { version = "0.19", default-features = false, features = ["write"] }
|
||||
target-lexicon = "0.10"
|
||||
anyhow = "1.0"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "experimental" }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Defines `ObjectBackend`.
|
||||
|
||||
use anyhow::anyhow;
|
||||
use cranelift_codegen::binemit::{
|
||||
Addend, CodeOffset, NullStackmapSink, Reloc, RelocSink, TrapSink,
|
||||
};
|
||||
@@ -7,8 +8,8 @@ use cranelift_codegen::entity::SecondaryMap;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::{self, binemit, ir};
|
||||
use cranelift_module::{
|
||||
Backend, DataContext, DataDescription, DataId, FuncId, Init, Linkage, ModuleNamespace,
|
||||
ModuleResult,
|
||||
Backend, DataContext, DataDescription, DataId, FuncId, Init, Linkage, ModuleError,
|
||||
ModuleNamespace, ModuleResult,
|
||||
};
|
||||
use object::write::{
|
||||
Object, Relocation, SectionId, StandardSection, Symbol, SymbolId, SymbolSection,
|
||||
@@ -18,11 +19,14 @@ use object::{
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use target_lexicon::{BinaryFormat, PointerWidth};
|
||||
use target_lexicon::PointerWidth;
|
||||
|
||||
/// A builder for `ObjectBackend`.
|
||||
pub struct ObjectBuilder {
|
||||
isa: Box<dyn TargetIsa>,
|
||||
binary_format: object::BinaryFormat,
|
||||
architecture: object::Architecture,
|
||||
endian: object::Endianness,
|
||||
name: Vec<u8>,
|
||||
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||
function_alignment: u64,
|
||||
@@ -40,13 +44,47 @@ impl ObjectBuilder {
|
||||
isa: Box<dyn TargetIsa>,
|
||||
name: V,
|
||||
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
) -> ModuleResult<Self> {
|
||||
let binary_format = match isa.triple().binary_format {
|
||||
target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
|
||||
target_lexicon::BinaryFormat::Coff => object::BinaryFormat::Coff,
|
||||
target_lexicon::BinaryFormat::Macho => object::BinaryFormat::MachO,
|
||||
target_lexicon::BinaryFormat::Wasm => {
|
||||
return Err(ModuleError::Backend(anyhow!(
|
||||
"binary format wasm is unsupported",
|
||||
)))
|
||||
}
|
||||
target_lexicon::BinaryFormat::Unknown => {
|
||||
return Err(ModuleError::Backend(anyhow!("binary format is unknown")))
|
||||
}
|
||||
};
|
||||
let architecture = match isa.triple().architecture {
|
||||
target_lexicon::Architecture::I386
|
||||
| target_lexicon::Architecture::I586
|
||||
| target_lexicon::Architecture::I686 => object::Architecture::I386,
|
||||
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
||||
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
||||
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
||||
architecture => {
|
||||
return Err(ModuleError::Backend(anyhow!(
|
||||
"target architecture {:?} is unsupported",
|
||||
architecture,
|
||||
)))
|
||||
}
|
||||
};
|
||||
let endian = match isa.triple().endianness().unwrap() {
|
||||
target_lexicon::Endianness::Little => object::Endianness::Little,
|
||||
target_lexicon::Endianness::Big => object::Endianness::Big,
|
||||
};
|
||||
Ok(Self {
|
||||
isa,
|
||||
binary_format,
|
||||
architecture,
|
||||
endian,
|
||||
name: name.into(),
|
||||
libcall_names,
|
||||
function_alignment: 1,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the alignment used for functions.
|
||||
@@ -85,8 +123,7 @@ impl Backend for ObjectBackend {
|
||||
|
||||
/// Create a new `ObjectBackend` using the given Cranelift target.
|
||||
fn new(builder: ObjectBuilder) -> Self {
|
||||
let triple = builder.isa.triple();
|
||||
let mut object = Object::new(triple.binary_format, triple.architecture);
|
||||
let mut object = Object::new(builder.binary_format, builder.architecture, builder.endian);
|
||||
object.add_file_symbol(builder.name);
|
||||
Self {
|
||||
isa: builder.isa,
|
||||
@@ -383,7 +420,7 @@ impl Backend for ObjectBackend {
|
||||
}
|
||||
|
||||
// Indicate that this object has a non-executable stack.
|
||||
if self.object.format() == BinaryFormat::Elf {
|
||||
if self.object.format() == object::BinaryFormat::Elf {
|
||||
self.object.add_section(
|
||||
vec![],
|
||||
".note.GNU-stack".as_bytes().to_vec(),
|
||||
@@ -509,12 +546,12 @@ struct RelocRecord {
|
||||
}
|
||||
|
||||
struct ObjectRelocSink {
|
||||
format: BinaryFormat,
|
||||
format: object::BinaryFormat,
|
||||
relocs: Vec<RelocRecord>,
|
||||
}
|
||||
|
||||
impl ObjectRelocSink {
|
||||
fn new(format: BinaryFormat) -> Self {
|
||||
fn new(format: object::BinaryFormat) -> Self {
|
||||
Self {
|
||||
format,
|
||||
relocs: vec![],
|
||||
@@ -552,7 +589,7 @@ impl RelocSink for ObjectRelocSink {
|
||||
Reloc::ElfX86_64TlsGd => {
|
||||
assert_eq!(
|
||||
self.format,
|
||||
BinaryFormat::Elf,
|
||||
object::BinaryFormat::Elf,
|
||||
"ElfX86_64TlsGd is not supported for this file format"
|
||||
);
|
||||
(
|
||||
@@ -564,7 +601,7 @@ impl RelocSink for ObjectRelocSink {
|
||||
Reloc::MachOX86_64Tlv => {
|
||||
assert_eq!(
|
||||
self.format,
|
||||
BinaryFormat::Macho,
|
||||
object::BinaryFormat::MachO,
|
||||
"MachOX86_64Tlv is not supported for this file format"
|
||||
);
|
||||
addend += 4; // X86_64_RELOC_TLV has an implicit addend of -4
|
||||
|
||||
@@ -14,7 +14,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
gimli = "0.21.0"
|
||||
wasmparser = "0.57.0"
|
||||
object = { version = "0.18", default-features = false, features = ["write"] }
|
||||
object = { version = "0.19", default-features = false, features = ["write"] }
|
||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||
target-lexicon = { version = "0.10.0", default-features = false }
|
||||
anyhow = "1.0"
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
#![allow(clippy::cast_ptr_alignment)]
|
||||
|
||||
use anyhow::Error;
|
||||
use anyhow::{bail, Error};
|
||||
use more_asserts::assert_gt;
|
||||
use object::write::{Object, Relocation, StandardSegment};
|
||||
use object::{RelocationEncoding, RelocationKind, SectionKind};
|
||||
use object::{
|
||||
Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use target_lexicon::BinaryFormat;
|
||||
use wasmtime_environ::isa::TargetIsa;
|
||||
|
||||
pub use crate::read_debuginfo::{read_debuginfo, DebugInfoData, WasmFileInfo};
|
||||
@@ -91,7 +92,14 @@ pub fn write_debugsections_image(
|
||||
code_region: (*const u8, usize),
|
||||
funcs: &[*const u8],
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let mut obj = Object::new(BinaryFormat::Elf, isa.triple().architecture);
|
||||
if isa.triple().architecture != target_lexicon::Architecture::X86_64 {
|
||||
bail!(
|
||||
"Unsupported architecture for DWARF image: {}",
|
||||
isa.triple().architecture
|
||||
);
|
||||
}
|
||||
|
||||
let mut obj = Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
|
||||
|
||||
assert!(!code_region.0.is_null() && code_region.1 > 0);
|
||||
assert_gt!(funcs.len(), 0);
|
||||
|
||||
@@ -13,7 +13,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
wasmtime-environ = { path = "../environ", version = "0.18.0" }
|
||||
object = { version = "0.18", default-features = false, features = ["write"] }
|
||||
object = { version = "0.19", default-features = false, features = ["write"] }
|
||||
more-asserts = "0.2.1"
|
||||
|
||||
[badges]
|
||||
|
||||
@@ -24,7 +24,7 @@ wasmtime-runtime = { path = "../runtime", version = "0.18.0" }
|
||||
ittapi-rs = { version = "0.1.5", optional = true }
|
||||
|
||||
[dependencies.object]
|
||||
version = "0.18.0"
|
||||
version = "0.19.0"
|
||||
optional = true
|
||||
default-features = false
|
||||
features = ['read_core', 'elf', 'std']
|
||||
|
||||
39
src/obj.rs
39
src/obj.rs
@@ -13,6 +13,42 @@ use wasmtime_environ::{
|
||||
use wasmtime_jit::native;
|
||||
use wasmtime_obj::emit_module;
|
||||
|
||||
fn to_obj_format(
|
||||
triple: &Triple,
|
||||
) -> Result<(
|
||||
object::BinaryFormat,
|
||||
object::Architecture,
|
||||
object::Endianness,
|
||||
)> {
|
||||
let binary_format = match triple.binary_format {
|
||||
target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
|
||||
target_lexicon::BinaryFormat::Coff => object::BinaryFormat::Coff,
|
||||
target_lexicon::BinaryFormat::Macho => object::BinaryFormat::MachO,
|
||||
target_lexicon::BinaryFormat::Wasm => {
|
||||
bail!("binary format wasm is unsupported");
|
||||
}
|
||||
target_lexicon::BinaryFormat::Unknown => {
|
||||
bail!("binary format is unknown");
|
||||
}
|
||||
};
|
||||
let architecture = match triple.architecture {
|
||||
target_lexicon::Architecture::I386
|
||||
| target_lexicon::Architecture::I586
|
||||
| target_lexicon::Architecture::I686 => object::Architecture::I386,
|
||||
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
|
||||
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
|
||||
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
|
||||
architecture => {
|
||||
bail!("target architecture {:?} is unsupported", architecture,);
|
||||
}
|
||||
};
|
||||
let endian = match triple.endianness().unwrap() {
|
||||
target_lexicon::Endianness::Little => object::Endianness::Little,
|
||||
target_lexicon::Endianness::Big => object::Endianness::Big,
|
||||
};
|
||||
Ok((binary_format, architecture, endian))
|
||||
}
|
||||
|
||||
/// Creates object file from binary wasm data.
|
||||
pub fn compile_to_obj(
|
||||
wasm: &[u8],
|
||||
@@ -50,7 +86,8 @@ pub fn compile_to_obj(
|
||||
|
||||
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
|
||||
|
||||
let mut obj = Object::new(isa.triple().binary_format, isa.triple().architecture);
|
||||
let (obj_format, obj_arch, obj_endian) = to_obj_format(isa.triple())?;
|
||||
let mut obj = Object::new(obj_format, obj_arch, obj_endian);
|
||||
|
||||
// TODO: Expose the tunables as command-line flags.
|
||||
let mut tunables = Tunables::default();
|
||||
|
||||
Reference in New Issue
Block a user