Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/singlepass dylib #2802

Merged
merged 14 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions lib/compiler-llvm/src/object_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,26 +169,6 @@ where
object::RelocationKind::Elf(object::elf::R_X86_64_PC64),
0,
) => RelocationKind::X86PCRel8,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G0_NC),
0,
) => RelocationKind::Arm64Movw0,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G1_NC),
0,
) => RelocationKind::Arm64Movw1,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G2_NC),
0,
) => RelocationKind::Arm64Movw2,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G3),
0,
) => RelocationKind::Arm64Movw3,
(object::Architecture::Aarch64, object::RelocationKind::PltRelative, 26) => {
RelocationKind::Arm64Call
}
Expand Down
9 changes: 5 additions & 4 deletions lib/compiler-singlepass/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2599,17 +2599,18 @@ impl<'a, M: Machine> FuncGen<'a, M> {
function_index - self.module.num_imported_functions,
))
};
self.machine
.move_with_reloc(reloc_target, &mut self.relocations);
let calling_convention = self.calling_convention;

self.emit_call_native(
|this| {
let offset = this
.machine
.mark_instruction_with_trap_code(TrapCode::StackOverflow);
this.machine
.emit_call_register(this.machine.get_grp_for_call());
let mut relocations = this
.machine
.emit_call_with_reloc(calling_convention, reloc_target);
this.machine.mark_instruction_address_end(offset);
this.relocations.append(&mut relocations);
},
params.iter().copied(),
param_types.iter().copied(),
Expand Down
1 change: 1 addition & 0 deletions lib/compiler-singlepass/src/emitter_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,7 @@ impl EmitterARM64 for Assembler {
let reg = reg.into_index() as u32;
dynasm!(self ; adr X(reg), =>label);
}

fn emit_b_label(&mut self, label: Label) {
dynasm!(self ; b =>label);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/compiler-singlepass/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,11 +1038,11 @@ pub trait Machine {
);

/// emit a move function address to GPR ready for call, using appropriate relocation
fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
);
) -> Vec<Relocation>;
/// Add with location directly from the stack
fn emit_binop_add64(
&mut self,
Expand Down
38 changes: 9 additions & 29 deletions lib/compiler-singlepass/src/machine_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3229,43 +3229,23 @@ impl Machine for MachineARM64 {
unimplemented!();
}

fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
_calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
) {
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw0,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movz(Location::GPR(GPR::X27), 0);
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw1,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 16);
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw2,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 32);
) -> Vec<Relocation> {
let mut relocations = vec![];
let next = self.get_label();
let reloc_at = self.assembler.get_offset().0;
self.emit_label(next); // this is to be sure the current imm26 value is 0
self.assembler.emit_call_label(next);
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw3,
kind: RelocationKind::Arm64Call,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 48);
relocations
}

fn emit_binop_add64(&mut self, loc_a: Location, loc_b: Location, ret: Location) {
Expand Down
26 changes: 11 additions & 15 deletions lib/compiler-singlepass/src/machine_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3869,27 +3869,23 @@ impl Machine for MachineX86_64 {
self.release_gpr(compare);
}

fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
_calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
) {
let reloc_at = self.assembler.get_offset().0 + self.assembler.arch_mov64_imm_offset();

) -> Vec<Relocation> {
let mut relocations = vec![];
let next = self.get_label();
let reloc_at = self.assembler.get_offset().0 + 1; // skip E8
self.assembler.emit_call_label(next);
self.emit_label(next);
relocations.push(Relocation {
kind: RelocationKind::Abs8,
kind: RelocationKind::X86CallPCRel4,
reloc_target,
offset: reloc_at as u32,
addend: 0,
addend: -4,
});

// RAX is preserved on entry to `emit_call_native` callback.
// The Imm64 value is relocated by the JIT linker.
self.assembler.emit_mov(
Size::S64,
Location::Imm64(std::u64::MAX),
Location::GPR(GPR::RAX),
);
relocations
}

fn emit_binop_add64(&mut self, loc_a: Location, loc_b: Location, ret: Location) {
Expand Down
18 changes: 1 addition & 17 deletions lib/compiler/src/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ pub enum RelocationKind {
Arm32Call,
/// Arm64 call target
Arm64Call,
/// Arm64 movk/z part 0
Arm64Movw0,
/// Arm64 movk/z part 1
Arm64Movw1,
/// Arm64 movk/z part 2
Arm64Movw2,
/// Arm64 movk/z part 3
Arm64Movw3,
// /// RISC-V call target
// RiscvCall,
/// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol.
Expand All @@ -80,10 +72,6 @@ impl fmt::Display for RelocationKind {
Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"),
Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"),
Self::Arm32Call | Self::Arm64Call => write!(f, "Call"),
Self::Arm64Movw0 => write!(f, "Arm64MovwG0"),
Self::Arm64Movw1 => write!(f, "Arm64MovwG1"),
Self::Arm64Movw2 => write!(f, "Arm64MovwG2"),
Self::Arm64Movw3 => write!(f, "Arm64MovwG3"),
Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"),
// Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"),
}
Expand Down Expand Up @@ -133,11 +121,7 @@ impl Relocation {
/// The function returns the relocation address and the delta.
pub fn for_address(&self, start: usize, target_func_address: u64) -> (usize, u64) {
match self.kind {
RelocationKind::Abs8
| RelocationKind::Arm64Movw0
| RelocationKind::Arm64Movw1
| RelocationKind::Arm64Movw2
| RelocationKind::Arm64Movw3 => {
RelocationKind::Abs8 => {
let reloc_address = start + self.offset as usize;
let reloc_addend = self.addend as isize;
let reloc_abs = target_func_address
Expand Down
6 changes: 0 additions & 6 deletions lib/engine-dylib/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,6 @@ impl DylibArtifact {
Triple::host().to_string(),
);

let notext = match (target_triple.operating_system, target_triple.architecture) {
(OperatingSystem::Linux, Architecture::X86_64) => vec!["-Wl,-z,notext"],
_ => vec![],
};

let linker = engine_inner.linker().executable();
let output = Command::new(linker)
.arg(&filepath)
Expand All @@ -414,7 +409,6 @@ impl DylibArtifact {
.args(&target_args)
// .args(&wasmer_symbols)
.arg("-shared")
.args(&notext)
.args(&cross_compiling_args)
.arg("-v")
.output()
Expand Down
26 changes: 1 addition & 25 deletions lib/engine-universal/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,7 @@ fn apply_relocation(
)
}
let reloc_delta = (((reloc_delta / 4) as u32) & 0x3ff_ffff)
| read_unaligned(reloc_address as *mut u32);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Arm64Movw0 => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta =
(((reloc_delta & 0xffff) as u32) << 5) | read_unaligned(reloc_address as *mut u32);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Arm64Movw1 => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = ((((reloc_delta >> 16) & 0xffff) as u32) << 5)
| read_unaligned(reloc_address as *mut u32);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Arm64Movw2 => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = ((((reloc_delta >> 32) & 0xffff) as u32) << 5)
| read_unaligned(reloc_address as *mut u32);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Arm64Movw3 => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = ((((reloc_delta >> 48) & 0xffff) as u32) << 5)
| read_unaligned(reloc_address as *mut u32);
| (read_unaligned(reloc_address as *mut u32) & 0xfc00_0000);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
kind => panic!(
Expand Down
4 changes: 2 additions & 2 deletions lib/object/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ pub fn emit_compilation(
let (_symbol_id, section_offset) = obj.symbol_section_and_offset(symbol_id).unwrap();

for r in relocations {
let relocation_address = section_offset + r.offset as u64;

let (relocation_kind, relocation_encoding, relocation_size) = match r.kind {
Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32),
Reloc::Abs8 => (RelocationKind::Absolute, RelocationEncoding::Generic, 64),
Expand Down Expand Up @@ -317,8 +319,6 @@ pub fn emit_compilation(
}
};

let relocation_address = section_offset + r.offset as u64;

match r.reloc_target {
RelocationTarget::LocalFunc(index) => {
let (_, target_symbol) = function_symbol_ids.get(index).unwrap();
Expand Down
1 change: 0 additions & 1 deletion tests/ignores.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
singlepass spec::multi_value # Singlepass has not implemented multivalue (functions that returns "structs"/"tuples")
singlepass spec::simd # Singlepass doesn't support yet SIMD (no one asked for this feature)

singlepass+dylib * # It needs to add support for PIC in Singlepass. Not implemented at the moment
windows+dylib * # This might be trivial to fix?
musl+dylib * # Dynamic loading not supported in Musl

Expand Down