Skip to content

Commit

Permalink
Merge pull request #5210 from wasmerio/5196-fix-llvm-relocations-and-…
Browse files Browse the repository at this point in the history
…simd-operations-on-aarch64

Fix(LLVM): Implement the missing relocations on aarch64, fix SIMD operations
  • Loading branch information
xdoardo authored Nov 5, 2024
2 parents 0d4db42 + 5eefba5 commit dbbbe29
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
target: aarch64-apple-darwin
artifact_name: 'wasmer-darwin-arm64'
use_sccache: false
use_llvm: false
use_llvm: true
build_wasm: false
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,7 @@ jobs:
os: macos-14,
target: aarch64-apple-darwin,
exe: '',
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
},
{
build: windows-x64,
Expand Down Expand Up @@ -744,7 +743,6 @@ jobs:
}
]
metadata: [
# We cannot test on macos-arm since we don't have ARM runners
{
build: linux-x64,
os: ubuntu-22.04,
Expand All @@ -758,15 +756,13 @@ jobs:
target: x86_64-apple-darwin,
exe: '',
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-amd64.tar.xz'

},
{
build: macos-arm,
os: macos-14,
target: aarch64-apple-darwin,
exe: '',
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
},
{
build: windows-x64,
Expand Down
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ else
endif

build-docs:
$(CARGO_BINARY) doc $(CARGO_TARGET_FLAG) --release $(compiler_features) --document-private-items --no-deps --workspace --exclude wasmer-c-api --locked
$(CARGO_BINARY) doc $(CARGO_TARGET_FLAG) --release $(compiler_features) --document-private-items --no-deps --workspace --exclude wasmer-c-api --exclude wasmer-swift --locked

# The tokio crate was excluded from the docs build because the code (which is not under our control)
# does not currently compile its docs successfully
Expand Down
4 changes: 2 additions & 2 deletions examples/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ fn main() -> anyhow::Result<()> {
// see how we can do that:
println!("Growing memory...");

// 'wasm-c-api' does not support direct calls to memory.grow()
#[cfg(not(feature = "wasm-c-api"))]
// 'wamr' does not support direct calls to memory.grow()
#[cfg(not(feature = "wamr"))]
{
// Here we are requesting two more pages for our memory.
memory.grow(&mut store, 2)?;
Expand Down
1 change: 0 additions & 1 deletion examples/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ fn main() -> anyhow::Result<()> {

// This test is currently failing with:
// not implemented: Native function definitions can't be directly called from the host yet
#[cfg(FALSE)]
#[test]
fn test_table() -> anyhow::Result<()> {
main()
Expand Down
2 changes: 2 additions & 0 deletions lib/compiler-llvm/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,13 @@ impl LLVM {
// but not in the case of Aarch64, there the ABI is slightly different
#[allow(clippy::match_single_binding)]
match target.triple().architecture {
Architecture::Aarch64(_) => wasmer_types::OperatingSystem::Darwin,
_ => wasmer_types::OperatingSystem::Linux,
}
} else {
target.triple().operating_system
};

let binary_format = if self.is_pic {
target.triple().binary_format
} else {
Expand Down
26 changes: 26 additions & 0 deletions lib/compiler-llvm/src/object_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,32 @@ where
object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20),
0,
) => RelocationKind::LArchAbs64Lo20,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_LO21),
0,
) => RelocationKind::Aarch64AdrPrelLo21,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_PG_HI21),
0,
) => RelocationKind::Aarch64AdrPrelPgHi21,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_LDST128_ABS_LO12_NC),
0,
) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_ADD_ABS_LO12_NC),
0,
) => RelocationKind::Aarch64AddAbsLo12Nc,
(
object::Architecture::Aarch64,
object::RelocationKind::Elf(object::elf::R_AARCH64_LDST64_ABS_LO12_NC),
0,
) => RelocationKind::Aarch64Ldst64AbsLo12Nc,

_ => {
return Err(CompileError::Codegen(format!(
"unknown relocation {:?}",
Expand Down
4 changes: 0 additions & 4 deletions lib/compiler-llvm/src/translator/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,10 +1104,6 @@ impl<'ctx> Intrinsics<'ctx> {
intrinsics
.throw_trap
.add_attribute(AttributeLoc::Function, noreturn);
//intrinsics
// .func_ref
// .add_attribute(AttributeLoc::Function, intrinsics.readonly);

intrinsics
}
}
Expand Down
53 changes: 53 additions & 0 deletions lib/compiler/src/engine/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,59 @@ fn apply_relocation(
| read_unaligned(reloc_address as *mut u32);
write_unaligned(reloc_address as *mut u32, reloc_abs);
},
RelocationKind::Aarch64AdrPrelPgHi21 => unsafe {
let (reloc_address, delta) = r.for_address(body, target_func_address as u64);

let delta = delta as isize;
assert!(
((-1 << 32)..(1 << 32)).contains(&delta),
"can't generate page-relative relocation with ±4GB `adrp` instruction"
);

let op = read_unaligned(reloc_address as *mut u32);
let delta = delta >> 12;
let immlo = ((delta as u32) & 0b11) << 29;
let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5;
let mask = !((0x7ffff << 5) | (0b11 << 29));
let op = (op & mask) | immlo | immhi;

write_unaligned(reloc_address as *mut u32, op);
},
RelocationKind::Aarch64AdrPrelLo21 => unsafe {
let (reloc_address, delta) = r.for_address(body, target_func_address as u64);

let delta = delta as isize;
assert!(
((-1 << 20)..(1 << 20)).contains(&delta),
"can't generate an ADR_PREL_LO21 relocation with an immediate larger than 20 bits"
);

let op = read_unaligned(reloc_address as *mut u32);
let immlo = ((delta as u32) & 0b11) << 29;
let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5;
let mask = !((0x7ffff << 5) | (0b11 << 29));
let op = (op & mask) | immlo | immhi;

write_unaligned(reloc_address as *mut u32, op);
},
RelocationKind::Aarch64AddAbsLo12Nc => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = (reloc_delta as u32 & 0xfff)
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Aarch64Ldst128AbsLo12Nc => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 4) << 10
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Aarch64Ldst64AbsLo12Nc => unsafe {
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 3) << 10
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
kind => panic!(
"Relocation kind unsupported in the current architecture {}",
kind
Expand Down
37 changes: 35 additions & 2 deletions lib/types/src/compilation/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ pub enum RelocationKind {
X86CallPLTRel4,
/// x86 GOT PC-relative 4-byte
X86GOTPCRel4,

/// R_AARCH64_ADR_PREL_LO21
Aarch64AdrPrelLo21,

/// R_AARCH64_ADR_PREL_PG_HI21
Aarch64AdrPrelPgHi21,

/// R_AARCH64_ADD_ABS_LO12_NC
Aarch64AddAbsLo12Nc,

/// R_AARCH64_LDST128_ABS_LO12_NC
Aarch64Ldst128AbsLo12Nc,

/// R_AARCH64_LDST64_ABS_LO12_NC
Aarch64Ldst64AbsLo12Nc,

/// Arm32 call target
Arm32Call,
/// Arm64 call target
Expand Down Expand Up @@ -102,6 +118,11 @@ impl fmt::Display for RelocationKind {
Self::LArchAbsLo12 => write!(f, "LArchAbsLo12"),
Self::LArchAbs64Hi12 => write!(f, "LArchAbs64Hi12"),
Self::LArchAbs64Lo20 => write!(f, "LArchAbs64Lo20"),
Self::Aarch64AdrPrelLo21 => write!(f, "Aarch64AdrPrelLo21"),
Self::Aarch64AdrPrelPgHi21 => write!(f, "Aarch64AdrPrelPgHi21"),
Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"),
Self::Aarch64Ldst128AbsLo12Nc => write!(f, "Aarch64Ldst128AbsLo12Nc"),
Self::Aarch64Ldst64AbsLo12Nc => write!(f, "Aarch64Ldst64AbsLo12Nc"),
// Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"),
}
}
Expand Down Expand Up @@ -142,7 +163,10 @@ pub trait RelocationLike {
| RelocationKind::Arm64Movw1
| RelocationKind::Arm64Movw2
| RelocationKind::Arm64Movw3
| RelocationKind::RiscvPCRelLo12I => {
| RelocationKind::RiscvPCRelLo12I
| RelocationKind::Aarch64AddAbsLo12Nc
| RelocationKind::Aarch64Ldst128AbsLo12Nc
| RelocationKind::Aarch64Ldst64AbsLo12Nc => {
let reloc_address = start + self.offset() as usize;
let reloc_addend = self.addend() as isize;
let reloc_abs = target_func_address
Expand Down Expand Up @@ -178,14 +202,23 @@ pub trait RelocationLike {
}
RelocationKind::Arm64Call
| RelocationKind::RiscvCall
| RelocationKind::RiscvPCRelHi20 => {
| RelocationKind::RiscvPCRelHi20
| RelocationKind::Aarch64AdrPrelLo21 => {
let reloc_address = start + self.offset() as usize;
let reloc_addend = self.addend() as isize;
let reloc_delta_u32 = target_func_address
.wrapping_sub(reloc_address as u64)
.wrapping_add(reloc_addend as u64);
(reloc_address, reloc_delta_u32)
}
RelocationKind::Aarch64AdrPrelPgHi21 => {
let reloc_address = start + self.offset() as usize;
let reloc_addend = self.addend() as isize;
let target_page =
(target_func_address.wrapping_add(reloc_addend as u64) & !(0xFFF)) as usize;
let pc_page = reloc_address & !(0xFFF);
(reloc_address, target_page.wrapping_sub(pc_page) as u64)
}
_ => panic!("Relocation kind unsupported"),
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/wasix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ tokio = { workspace = true, features = [
pretty_assertions.workspace = true
tracing-test = "0.2.4"
wasm-bindgen-test = "0.3.0"
env_logger = { version = "0.11.5", default-features = false}
log = "0.4.22"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.0"
Expand Down
Loading

0 comments on commit dbbbe29

Please sign in to comment.