Skip to content

Commit dbbbe29

Browse files
authored
Merge pull request #5210 from wasmerio/5196-fix-llvm-relocations-and-simd-operations-on-aarch64
Fix(LLVM): Implement the missing relocations on aarch64, fix SIMD operations
2 parents 0d4db42 + 5eefba5 commit dbbbe29

File tree

14 files changed

+196
-28
lines changed

14 files changed

+196
-28
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ jobs:
119119
target: aarch64-apple-darwin
120120
artifact_name: 'wasmer-darwin-arm64'
121121
use_sccache: false
122-
use_llvm: false
122+
use_llvm: true
123123
build_wasm: false
124124
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
125125
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'

.github/workflows/test.yaml

+2-6
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,7 @@ jobs:
511511
os: macos-14,
512512
target: aarch64-apple-darwin,
513513
exe: '',
514-
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
515-
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
514+
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
516515
},
517516
{
518517
build: windows-x64,
@@ -744,7 +743,6 @@ jobs:
744743
}
745744
]
746745
metadata: [
747-
# We cannot test on macos-arm since we don't have ARM runners
748746
{
749747
build: linux-x64,
750748
os: ubuntu-22.04,
@@ -758,15 +756,13 @@ jobs:
758756
target: x86_64-apple-darwin,
759757
exe: '',
760758
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-amd64.tar.xz'
761-
762759
},
763760
{
764761
build: macos-arm,
765762
os: macos-14,
766763
target: aarch64-apple-darwin,
767764
exe: '',
768-
# [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly.
769-
# llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
765+
llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz'
770766
},
771767
{
772768
build: windows-x64,

Cargo.lock

+21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ else
437437
endif
438438

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

442442
# The tokio crate was excluded from the docs build because the code (which is not under our control)
443443
# does not currently compile its docs successfully

examples/memory.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ fn main() -> anyhow::Result<()> {
108108
// see how we can do that:
109109
println!("Growing memory...");
110110

111-
// 'wasm-c-api' does not support direct calls to memory.grow()
112-
#[cfg(not(feature = "wasm-c-api"))]
111+
// 'wamr' does not support direct calls to memory.grow()
112+
#[cfg(not(feature = "wamr"))]
113113
{
114114
// Here we are requesting two more pages for our memory.
115115
memory.grow(&mut store, 2)?;

examples/table.rs

-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ fn main() -> anyhow::Result<()> {
154154

155155
// This test is currently failing with:
156156
// not implemented: Native function definitions can't be directly called from the host yet
157-
#[cfg(FALSE)]
158157
#[test]
159158
fn test_table() -> anyhow::Result<()> {
160159
main()

lib/compiler-llvm/src/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,13 @@ impl LLVM {
119119
// but not in the case of Aarch64, there the ABI is slightly different
120120
#[allow(clippy::match_single_binding)]
121121
match target.triple().architecture {
122+
Architecture::Aarch64(_) => wasmer_types::OperatingSystem::Darwin,
122123
_ => wasmer_types::OperatingSystem::Linux,
123124
}
124125
} else {
125126
target.triple().operating_system
126127
};
128+
127129
let binary_format = if self.is_pic {
128130
target.triple().binary_format
129131
} else {

lib/compiler-llvm/src/object_file.rs

+26
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,32 @@ where
251251
object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20),
252252
0,
253253
) => RelocationKind::LArchAbs64Lo20,
254+
(
255+
object::Architecture::Aarch64,
256+
object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_LO21),
257+
0,
258+
) => RelocationKind::Aarch64AdrPrelLo21,
259+
(
260+
object::Architecture::Aarch64,
261+
object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_PG_HI21),
262+
0,
263+
) => RelocationKind::Aarch64AdrPrelPgHi21,
264+
(
265+
object::Architecture::Aarch64,
266+
object::RelocationKind::Elf(object::elf::R_AARCH64_LDST128_ABS_LO12_NC),
267+
0,
268+
) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
269+
(
270+
object::Architecture::Aarch64,
271+
object::RelocationKind::Elf(object::elf::R_AARCH64_ADD_ABS_LO12_NC),
272+
0,
273+
) => RelocationKind::Aarch64AddAbsLo12Nc,
274+
(
275+
object::Architecture::Aarch64,
276+
object::RelocationKind::Elf(object::elf::R_AARCH64_LDST64_ABS_LO12_NC),
277+
0,
278+
) => RelocationKind::Aarch64Ldst64AbsLo12Nc,
279+
254280
_ => {
255281
return Err(CompileError::Codegen(format!(
256282
"unknown relocation {:?}",

lib/compiler-llvm/src/translator/intrinsics.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1104,10 +1104,6 @@ impl<'ctx> Intrinsics<'ctx> {
11041104
intrinsics
11051105
.throw_trap
11061106
.add_attribute(AttributeLoc::Function, noreturn);
1107-
//intrinsics
1108-
// .func_ref
1109-
// .add_attribute(AttributeLoc::Function, intrinsics.readonly);
1110-
11111107
intrinsics
11121108
}
11131109
}

lib/compiler/src/engine/link.rs

+53
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,59 @@ fn apply_relocation(
146146
| read_unaligned(reloc_address as *mut u32);
147147
write_unaligned(reloc_address as *mut u32, reloc_abs);
148148
},
149+
RelocationKind::Aarch64AdrPrelPgHi21 => unsafe {
150+
let (reloc_address, delta) = r.for_address(body, target_func_address as u64);
151+
152+
let delta = delta as isize;
153+
assert!(
154+
((-1 << 32)..(1 << 32)).contains(&delta),
155+
"can't generate page-relative relocation with ±4GB `adrp` instruction"
156+
);
157+
158+
let op = read_unaligned(reloc_address as *mut u32);
159+
let delta = delta >> 12;
160+
let immlo = ((delta as u32) & 0b11) << 29;
161+
let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5;
162+
let mask = !((0x7ffff << 5) | (0b11 << 29));
163+
let op = (op & mask) | immlo | immhi;
164+
165+
write_unaligned(reloc_address as *mut u32, op);
166+
},
167+
RelocationKind::Aarch64AdrPrelLo21 => unsafe {
168+
let (reloc_address, delta) = r.for_address(body, target_func_address as u64);
169+
170+
let delta = delta as isize;
171+
assert!(
172+
((-1 << 20)..(1 << 20)).contains(&delta),
173+
"can't generate an ADR_PREL_LO21 relocation with an immediate larger than 20 bits"
174+
);
175+
176+
let op = read_unaligned(reloc_address as *mut u32);
177+
let immlo = ((delta as u32) & 0b11) << 29;
178+
let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5;
179+
let mask = !((0x7ffff << 5) | (0b11 << 29));
180+
let op = (op & mask) | immlo | immhi;
181+
182+
write_unaligned(reloc_address as *mut u32, op);
183+
},
184+
RelocationKind::Aarch64AddAbsLo12Nc => unsafe {
185+
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
186+
let reloc_delta = (reloc_delta as u32 & 0xfff)
187+
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
188+
write_unaligned(reloc_address as *mut u32, reloc_delta);
189+
},
190+
RelocationKind::Aarch64Ldst128AbsLo12Nc => unsafe {
191+
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
192+
let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 4) << 10
193+
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
194+
write_unaligned(reloc_address as *mut u32, reloc_delta);
195+
},
196+
RelocationKind::Aarch64Ldst64AbsLo12Nc => unsafe {
197+
let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
198+
let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 3) << 10
199+
| (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF);
200+
write_unaligned(reloc_address as *mut u32, reloc_delta);
201+
},
149202
kind => panic!(
150203
"Relocation kind unsupported in the current architecture {}",
151204
kind

lib/types/src/compilation/relocation.rs

+35-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ pub enum RelocationKind {
4646
X86CallPLTRel4,
4747
/// x86 GOT PC-relative 4-byte
4848
X86GOTPCRel4,
49+
50+
/// R_AARCH64_ADR_PREL_LO21
51+
Aarch64AdrPrelLo21,
52+
53+
/// R_AARCH64_ADR_PREL_PG_HI21
54+
Aarch64AdrPrelPgHi21,
55+
56+
/// R_AARCH64_ADD_ABS_LO12_NC
57+
Aarch64AddAbsLo12Nc,
58+
59+
/// R_AARCH64_LDST128_ABS_LO12_NC
60+
Aarch64Ldst128AbsLo12Nc,
61+
62+
/// R_AARCH64_LDST64_ABS_LO12_NC
63+
Aarch64Ldst64AbsLo12Nc,
64+
4965
/// Arm32 call target
5066
Arm32Call,
5167
/// Arm64 call target
@@ -102,6 +118,11 @@ impl fmt::Display for RelocationKind {
102118
Self::LArchAbsLo12 => write!(f, "LArchAbsLo12"),
103119
Self::LArchAbs64Hi12 => write!(f, "LArchAbs64Hi12"),
104120
Self::LArchAbs64Lo20 => write!(f, "LArchAbs64Lo20"),
121+
Self::Aarch64AdrPrelLo21 => write!(f, "Aarch64AdrPrelLo21"),
122+
Self::Aarch64AdrPrelPgHi21 => write!(f, "Aarch64AdrPrelPgHi21"),
123+
Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"),
124+
Self::Aarch64Ldst128AbsLo12Nc => write!(f, "Aarch64Ldst128AbsLo12Nc"),
125+
Self::Aarch64Ldst64AbsLo12Nc => write!(f, "Aarch64Ldst64AbsLo12Nc"),
105126
// Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"),
106127
}
107128
}
@@ -142,7 +163,10 @@ pub trait RelocationLike {
142163
| RelocationKind::Arm64Movw1
143164
| RelocationKind::Arm64Movw2
144165
| RelocationKind::Arm64Movw3
145-
| RelocationKind::RiscvPCRelLo12I => {
166+
| RelocationKind::RiscvPCRelLo12I
167+
| RelocationKind::Aarch64AddAbsLo12Nc
168+
| RelocationKind::Aarch64Ldst128AbsLo12Nc
169+
| RelocationKind::Aarch64Ldst64AbsLo12Nc => {
146170
let reloc_address = start + self.offset() as usize;
147171
let reloc_addend = self.addend() as isize;
148172
let reloc_abs = target_func_address
@@ -178,14 +202,23 @@ pub trait RelocationLike {
178202
}
179203
RelocationKind::Arm64Call
180204
| RelocationKind::RiscvCall
181-
| RelocationKind::RiscvPCRelHi20 => {
205+
| RelocationKind::RiscvPCRelHi20
206+
| RelocationKind::Aarch64AdrPrelLo21 => {
182207
let reloc_address = start + self.offset() as usize;
183208
let reloc_addend = self.addend() as isize;
184209
let reloc_delta_u32 = target_func_address
185210
.wrapping_sub(reloc_address as u64)
186211
.wrapping_add(reloc_addend as u64);
187212
(reloc_address, reloc_delta_u32)
188213
}
214+
RelocationKind::Aarch64AdrPrelPgHi21 => {
215+
let reloc_address = start + self.offset() as usize;
216+
let reloc_addend = self.addend() as isize;
217+
let target_page =
218+
(target_func_address.wrapping_add(reloc_addend as u64) & !(0xFFF)) as usize;
219+
let pc_page = reloc_address & !(0xFFF);
220+
(reloc_address, target_page.wrapping_sub(pc_page) as u64)
221+
}
189222
_ => panic!("Relocation kind unsupported"),
190223
}
191224
}

lib/wasix/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ tokio = { workspace = true, features = [
164164
pretty_assertions.workspace = true
165165
tracing-test = "0.2.4"
166166
wasm-bindgen-test = "0.3.0"
167+
env_logger = { version = "0.11.5", default-features = false}
168+
log = "0.4.22"
167169

168170
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
169171
wasm-bindgen-test = "0.3.0"

0 commit comments

Comments
 (0)