1use object::{Object, ObjectSection, ObjectSymbol};
2use target_lexicon::{Architecture, BinaryFormat, Riscv64Architecture, Triple};
3
4use std::collections::{HashMap, HashSet};
5use std::convert::TryInto;
6use std::num::TryFromIntError;
7
8use wasmer_types::{CompileError, SourceLoc, entity::PrimaryMap};
9
10use wasmer_compiler::types::{
11 address_map::{FunctionAddressMap, InstructionAddressMap},
12 function::{CompiledFunctionFrameInfo, CustomSections, FunctionBody},
13 relocation::{Relocation, RelocationKind, RelocationTarget},
14 section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex},
15};
16
17use wasmer_compiler::LIBCALLS_ELF;
18use wasmer_vm::libcalls::LibCall;
19
20fn map_tryfromint_err(error: TryFromIntError) -> CompileError {
21 CompileError::Codegen(format!("int doesn't fit: {error}"))
22}
23
24fn map_object_err(error: object::read::Error) -> CompileError {
25 CompileError::Codegen(format!("error parsing object file: {error}"))
26}
27
28#[derive(Debug)]
29pub struct RkyvCompiledFunction {
30 pub compiled_function: wasmer_compiler::types::function::CompiledFunction,
31 pub custom_sections: CustomSections,
32 pub eh_frame_section_indices: Vec<SectionIndex>,
33 pub compact_unwind_section_indices: Vec<SectionIndex>,
34 pub gcc_except_table_section_indices: Vec<SectionIndex>,
35 pub data_dw_ref_personality_section_indices: Vec<SectionIndex>,
36}
37
38#[derive(Debug)]
39pub enum CompiledFunction {
40 Rkyv(Box<RkyvCompiledFunction>),
41 Elf(Vec<u8>),
42}
43
44impl wasmer_compiler::CompiledFunction for CompiledFunction {}
45
46static SOFTFLOAT_LIBCALLS_ELF: phf::Map<&'static str, LibCall> = phf::phf_map! {
51 "__addsf3" => LibCall::Addsf3,
53 "__adddf3" => LibCall::Adddf3,
54 "__subsf3" => LibCall::Subsf3,
55 "__subdf3" => LibCall::Subdf3,
56 "__mulsf3" => LibCall::Mulsf3,
57 "__muldf3" => LibCall::Muldf3,
58 "__divsf3" => LibCall::Divsf3,
59 "__divdf3" => LibCall::Divdf3,
60 "__negsf2" => LibCall::Negsf2,
61 "__negdf2" => LibCall::Negdf2,
62 "__extendsfdf2" => LibCall::Extendsfdf2,
64 "__truncdfsf2" => LibCall::Truncdfsf2,
65 "__fixsfsi" => LibCall::Fixsfsi,
66 "__fixdfsi" => LibCall::Fixdfsi,
67 "__fixsfdi" => LibCall::Fixsfdi,
68 "__fixdfdi" => LibCall::Fixdfdi,
69 "__fixunssfsi" => LibCall::Fixunssfsi,
70 "__fixunsdfsi" => LibCall::Fixunsdfsi,
71 "__fixunssfdi" => LibCall::Fixunssfdi,
72 "__fixunsdfdi" => LibCall::Fixunsdfdi,
73 "__floatsisf" => LibCall::Floatsisf,
74 "__floatsidf" => LibCall::Floatsidf,
75 "__floatdisf" => LibCall::Floatdisf,
76 "__floatdidf" => LibCall::Floatdidf,
77 "__floatunsisf" => LibCall::Floatunsisf,
78 "__floatunsidf" => LibCall::Floatunsidf,
79 "__floatundisf" => LibCall::Floatundisf,
80 "__floatundidf" => LibCall::Floatundidf,
81 "__unordsf2" => LibCall::Unordsf2,
83 "__unorddf2" => LibCall::Unorddf2,
84 "__eqsf2" => LibCall::Eqsf2,
85 "__eqdf2" => LibCall::Eqdf2,
86 "__nesf2" => LibCall::Nesf2,
87 "__nedf2" => LibCall::Nedf2,
88 "__gesf2" => LibCall::Gesf2,
89 "__gedf2" => LibCall::Gedf2,
90 "__ltsf2" => LibCall::Ltsf2,
91 "__ltdf2" => LibCall::Ltdf2,
92 "__lesf2" => LibCall::Lesf2,
93 "__ledf2" => LibCall::Ledf2,
94 "__gtsf2" => LibCall::Gtsf2,
95 "__gtdf2" => LibCall::Gtdf2,
96};
97
98static LIBCALLS_MACHO: phf::Map<&'static str, LibCall> = phf::phf_map! {
99 "_ceilf" => LibCall::CeilF32,
100 "_ceil" => LibCall::CeilF64,
101 "_floorf" => LibCall::FloorF32,
102 "_floor" => LibCall::FloorF64,
103 "_nearbyintf" => LibCall::NearestF32,
104 "_nearbyint" => LibCall::NearestF64,
105 "_sqrtf" => LibCall::SqrtF32,
106 "_sqrt" => LibCall::SqrtF64,
107 "_truncf" => LibCall::TruncF32,
108 "_trunc" => LibCall::TruncF64,
109 "_wasmer_vm_f32_ceil" => LibCall::CeilF32,
110 "_wasmer_vm_f64_ceil" => LibCall::CeilF64,
111 "_wasmer_vm_f32_floor" => LibCall::FloorF32,
112 "_wasmer_vm_f64_floor" => LibCall::FloorF64,
113 "_wasmer_vm_f32_nearest" => LibCall::NearestF32,
114 "_wasmer_vm_f64_nearest" => LibCall::NearestF64,
115 "_wasmer_vm_f32_sqrt" => LibCall::SqrtF32,
116 "_wasmer_vm_f64_sqrt" => LibCall::SqrtF64,
117 "_wasmer_vm_f32_trunc" => LibCall::TruncF32,
118 "_wasmer_vm_f64_trunc" => LibCall::TruncF64,
119 "_wasmer_vm_memory32_size" => LibCall::Memory32Size,
120 "_wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
121 "_wasmer_vm_table_copy" => LibCall::TableCopy,
122 "_wasmer_vm_table_init" => LibCall::TableInit,
123 "_wasmer_vm_table_fill" => LibCall::TableFill,
124 "_wasmer_vm_table_size" => LibCall::TableSize,
125 "_wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
126 "_wasmer_vm_table_get" => LibCall::TableGet,
127 "_wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
128 "_wasmer_vm_table_set" => LibCall::TableSet,
129 "_wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
130 "_wasmer_vm_table_grow" => LibCall::TableGrow,
131 "_wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
132 "_wasmer_vm_func_ref" => LibCall::FuncRef,
133 "_wasmer_vm_elem_drop" => LibCall::ElemDrop,
134 "_wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
135 "_wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
136 "_wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
137 "_wasmer_vm_memory32_init" => LibCall::Memory32Init,
138 "_wasmer_vm_data_drop" => LibCall::DataDrop,
139 "_wasmer_vm_raise_trap" => LibCall::RaiseTrap,
140 "_wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
141 "_wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
142 "_wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
143 "_wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
144 "_wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
145 "_wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
146
147 "_wasmer_vm_throw" => LibCall::Throw,
148 "_wasmer_vm_alloc_exception" => LibCall::AllocException,
149 "_wasmer_vm_read_exnref" => LibCall::ReadExnRef,
150 "_wasmer_vm_exception_into_exnref" => LibCall::LibunwindExceptionIntoExnRef,
151 "___gxx_personality_v0" => LibCall::EHPersonality,
156 "_wasmer_eh_personality2" => LibCall::EHPersonality2,
157 "_wasmer_vm_dbg_usize" => LibCall::DebugUsize,
158 "_wasmer_vm_dbg_str" => LibCall::DebugStr,
159};
160
161fn is_riscv_softfloat(arch: &Architecture) -> bool {
164 match arch {
165 Architecture::Riscv64(Riscv64Architecture::Riscv64gc | Riscv64Architecture::Riscv64a23) => {
166 false
167 }
168 Architecture::Riscv64(_) => true,
169 _ => false,
170 }
171}
172
173fn lookup_libcall(name: &str, fmt: BinaryFormat, triple: &Triple) -> Option<LibCall> {
174 let base = match fmt {
175 BinaryFormat::Elf => &LIBCALLS_ELF,
176 BinaryFormat::Macho => &LIBCALLS_MACHO,
177 _ => return None,
178 };
179 if let Some(&lc) = base.get(name) {
180 return Some(lc);
181 }
182 if fmt == BinaryFormat::Elf
186 && is_riscv_softfloat(&triple.architecture)
187 && let Some(&lc) = SOFTFLOAT_LIBCALLS_ELF.get(name)
188 {
189 return Some(lc);
190 }
191 None
192}
193
194pub fn load_object_file<F>(
195 contents: &[u8],
196 root_section: &str,
197 root_section_reloc_target: RelocationTarget,
198 mut symbol_name_to_relocation_target: F,
199 binary_fmt: BinaryFormat,
200 triple: &Triple,
201) -> Result<RkyvCompiledFunction, CompileError>
202where
203 F: FnMut(&str) -> Result<Option<RelocationTarget>, CompileError>,
204{
205 let obj = object::File::parse(contents).map_err(map_object_err)?;
206
207 if !matches!(binary_fmt, BinaryFormat::Elf | BinaryFormat::Macho) {
208 return Err(CompileError::UnsupportedTarget(format!(
209 "Unsupported binary format {binary_fmt:?}"
210 )));
211 }
212
213 let mut worklist: Vec<object::read::SectionIndex> = Vec::new();
214 let mut section_targets: HashMap<object::read::SectionIndex, RelocationTarget> = HashMap::new();
215
216 let root_section_index = obj
217 .section_by_name(root_section)
218 .ok_or_else(|| CompileError::Codegen(format!("no section named {root_section}")))?
219 .index();
220
221 let mut section_to_custom_section = HashMap::new();
222
223 section_targets.insert(root_section_index, root_section_reloc_target);
224
225 let mut next_custom_section: u32 = 0;
226
227 let mut elf_section_to_target = |elf_section_index: object::read::SectionIndex| {
228 *section_targets.entry(elf_section_index).or_insert_with(|| {
229 let next = SectionIndex::from_u32(next_custom_section);
230 section_to_custom_section.insert(elf_section_index, next);
231 let target = RelocationTarget::CustomSection(next);
232 next_custom_section += 1;
233 target
234 })
235 };
236
237 let mut relocations: HashMap<object::read::SectionIndex, Vec<Relocation>> = HashMap::new();
240
241 worklist.push(root_section_index);
255
256 let mut eh_frame_section_indices = vec![];
258
259 let mut compact_unwind_section_indices = vec![];
261
262 let mut gcc_except_table_section_indices = vec![];
267
268 let mut data_dw_ref_personality_section_indices = vec![];
269
270 for section in obj.sections() {
271 let index = section.index();
272 let Ok(section_name) = section.name() else {
273 continue;
274 };
275
276 match section_name {
277 "__eh_frame" | ".eh_frame" => {
278 worklist.push(index);
279 eh_frame_section_indices.push(index);
280
281 elf_section_to_target(index);
283 }
284 "__compact_unwind" => {
285 worklist.push(index);
286 compact_unwind_section_indices.push(index);
287
288 elf_section_to_target(index);
289 }
290 ".gcc_except_table" => {
291 worklist.push(index);
292 gcc_except_table_section_indices.push(index);
293
294 elf_section_to_target(index);
295 }
296 ".data.DW.ref.wasmer_eh_personality" => {
297 worklist.push(index);
298 data_dw_ref_personality_section_indices.push(index);
299
300 elf_section_to_target(index);
301 }
302 _ => {}
303 }
304 }
305
306 let mut visited: HashSet<_> = HashSet::from_iter(worklist.iter().copied());
307 while let Some(section_index) = worklist.pop() {
308 let sec = obj
309 .section_by_index(section_index)
310 .map_err(map_object_err)?;
311 let relocs = sec.relocations();
312 for (offset, reloc) in relocs {
313 let mut addend = reloc.addend();
314 let target = match reloc.target() {
315 object::read::RelocationTarget::Symbol(index) => {
316 let symbol = obj.symbol_by_index(index).map_err(map_object_err)?;
317 let symbol_name = symbol.name().map_err(map_object_err)?;
318 if symbol.kind() == object::SymbolKind::Section {
319 match symbol.section() {
320 object::SymbolSection::Section(section_index) => {
321 if section_index == root_section_index {
322 root_section_reloc_target
323 } else {
324 if visited.insert(section_index) {
325 worklist.push(section_index);
326 }
327 elf_section_to_target(section_index)
328 }
329 }
330 _ => {
331 return Err(CompileError::Codegen(format!(
332 "relocation targets unknown section {reloc:?}",
333 )));
334 }
335 }
336 } else if let Some(libcall) = lookup_libcall(symbol_name, binary_fmt, triple) {
338 RelocationTarget::LibCall(libcall)
339 } else if let Ok(Some(reloc_target)) =
340 symbol_name_to_relocation_target(symbol_name)
341 {
342 reloc_target
343 } else if let object::SymbolSection::Section(section_index) = symbol.section() {
344 if matches!(
345 reloc.flags(),
346 object::RelocationFlags::MachO {
347 r_type: object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12,
348 r_pcrel: false,
349 ..
350 } | object::RelocationFlags::MachO {
351 r_type: object::macho::ARM64_RELOC_POINTER_TO_GOT,
352 r_pcrel: true,
353 ..
354 } | object::RelocationFlags::MachO {
355 r_type: object::macho::ARM64_RELOC_GOT_LOAD_PAGE21,
356 r_pcrel: true,
357 ..
358 } | object::RelocationFlags::MachO {
359 r_type: object::macho::ARM64_RELOC_PAGE21,
360 r_pcrel: true,
361 ..
362 } | object::RelocationFlags::MachO {
363 r_type: object::macho::ARM64_RELOC_PAGEOFF12,
364 r_pcrel: false,
365 ..
366 }
367 ) {
368 let symbol_sec = obj
388 .section_by_index(section_index)
389 .map_err(map_object_err)?;
390
391 addend = addend
392 .wrapping_add((symbol.address() - symbol_sec.address()) as i64);
393 } else {
394 addend = addend.wrapping_add(symbol.address() as i64);
396 }
397
398 if section_index == root_section_index {
399 root_section_reloc_target
400 } else {
401 if visited.insert(section_index) {
402 worklist.push(section_index);
403 }
404
405 elf_section_to_target(section_index)
406 }
407 } else {
408 return Err(CompileError::Codegen(format!(
409 "relocation {reloc:?} targets unknown symbol '{symbol:?}'",
410 )));
411 }
412 }
413
414 object::read::RelocationTarget::Section(index) => {
415 if index == root_section_index {
416 root_section_reloc_target
417 } else {
418 if visited.insert(index) {
419 worklist.push(index);
420 }
421 elf_section_to_target(index)
422 }
423 }
424
425 object::read::RelocationTarget::Absolute => {
426 return Err(CompileError::Codegen(format!(
430 "relocation targets absolute address {reloc:?}",
431 )));
432 }
433
434 t => {
441 return Err(CompileError::Codegen(format!(
442 "relocation target is unknown `{t:?}`",
443 )));
444 }
445 };
446 let kind = match (obj.architecture(), reloc.flags(), reloc.size()) {
447 (
448 _,
449 object::RelocationFlags::Elf {
450 r_type: object::elf::R_X86_64_64,
451 },
452 64,
453 ) => RelocationKind::Abs8,
454 (
455 object::Architecture::X86_64,
456 object::RelocationFlags::Elf {
457 r_type: object::elf::R_X86_64_PC64,
458 },
459 0,
460 ) => RelocationKind::PCRel8,
461 (
462 object::Architecture::Aarch64,
463 object::RelocationFlags::Elf {
464 r_type: object::elf::R_AARCH64_CALL26,
465 },
466 26,
467 ) => RelocationKind::Arm64Call,
468 (
469 object::Architecture::Aarch64,
470 object::RelocationFlags::Elf {
471 r_type: object::elf::R_AARCH64_JUMP26,
472 },
473 0,
474 ) => RelocationKind::Arm64Call,
475 (
476 object::Architecture::Aarch64,
477 object::RelocationFlags::Elf {
478 r_type: object::elf::R_AARCH64_MOVW_UABS_G0_NC,
479 },
480 0,
481 ) => RelocationKind::Arm64Movw0,
482 (
483 object::Architecture::Aarch64,
484 object::RelocationFlags::Elf {
485 r_type: object::elf::R_AARCH64_MOVW_UABS_G1_NC,
486 },
487 0,
488 ) => RelocationKind::Arm64Movw1,
489 (
490 object::Architecture::Aarch64,
491 object::RelocationFlags::Elf {
492 r_type: object::elf::R_AARCH64_MOVW_UABS_G2_NC,
493 },
494 0,
495 ) => RelocationKind::Arm64Movw2,
496 (
497 object::Architecture::Aarch64,
498 object::RelocationFlags::Elf {
499 r_type: object::elf::R_AARCH64_MOVW_UABS_G3,
500 },
501 0,
502 ) => RelocationKind::Arm64Movw3,
503 (
504 object::Architecture::Riscv64,
505 object::RelocationFlags::Elf {
506 r_type: object::elf::R_RISCV_CALL_PLT,
507 },
508 0,
509 ) => RelocationKind::RiscvCall,
510 (
511 object::Architecture::Riscv64,
512 object::RelocationFlags::Elf {
513 r_type: object::elf::R_RISCV_PCREL_HI20,
514 },
515 0,
516 ) => RelocationKind::RiscvPCRelHi20,
517 (
518 object::Architecture::Riscv64,
519 object::RelocationFlags::Elf {
520 r_type: object::elf::R_RISCV_PCREL_LO12_I,
521 },
522 0,
523 ) => RelocationKind::RiscvPCRelLo12I,
524 (
525 object::Architecture::Riscv64,
526 object::RelocationFlags::Elf {
527 r_type: object::elf::R_RISCV_ADD8,
528 },
529 0,
530 ) => RelocationKind::Add,
531 (
532 object::Architecture::Riscv64,
533 object::RelocationFlags::Elf {
534 r_type: object::elf::R_RISCV_ADD16,
535 },
536 0,
537 ) => RelocationKind::Add2,
538 (
539 object::Architecture::Riscv64,
540 object::RelocationFlags::Elf {
541 r_type: object::elf::R_RISCV_ADD32,
542 },
543 0,
544 ) => RelocationKind::Add4,
545 (
546 object::Architecture::Riscv64,
547 object::RelocationFlags::Elf {
548 r_type: object::elf::R_RISCV_ADD64,
549 },
550 0,
551 ) => RelocationKind::Add8,
552 (
553 object::Architecture::Riscv64,
554 object::RelocationFlags::Elf {
555 r_type: object::elf::R_RISCV_SUB6,
556 },
557 0,
558 ) => RelocationKind::Sub6Bits,
559 (
560 object::Architecture::Riscv64,
561 object::RelocationFlags::Elf {
562 r_type: object::elf::R_RISCV_SUB8,
563 },
564 0,
565 ) => RelocationKind::Sub,
566 (
567 object::Architecture::Riscv64,
568 object::RelocationFlags::Elf {
569 r_type: object::elf::R_RISCV_SUB16,
570 },
571 0,
572 ) => RelocationKind::Sub2,
573 (
574 object::Architecture::Riscv64,
575 object::RelocationFlags::Elf {
576 r_type: object::elf::R_RISCV_SUB32,
577 },
578 0,
579 ) => RelocationKind::Sub4,
580 (
581 object::Architecture::Riscv64,
582 object::RelocationFlags::Elf {
583 r_type: object::elf::R_RISCV_SUB64,
584 },
585 0,
586 ) => RelocationKind::Sub8,
587 (
588 object::Architecture::Riscv64,
589 object::RelocationFlags::Elf {
590 r_type: object::elf::R_RISCV_SET6,
591 },
592 0,
593 ) => RelocationKind::Abs6Bits,
594 (
595 object::Architecture::Riscv64,
596 object::RelocationFlags::Elf {
597 r_type: object::elf::R_RISCV_SET8,
598 },
599 0,
600 ) => RelocationKind::Abs,
601 (
602 object::Architecture::Riscv64,
603 object::RelocationFlags::Elf {
604 r_type: object::elf::R_RISCV_SET16,
605 },
606 0,
607 ) => RelocationKind::Abs2,
608 (
609 object::Architecture::Riscv64,
610 object::RelocationFlags::Elf {
611 r_type: object::elf::R_RISCV_SET32,
612 },
613 0,
614 ) => RelocationKind::Abs4,
615 (
616 object::Architecture::Riscv64,
617 object::RelocationFlags::Elf {
618 r_type: object::elf::R_RISCV_32,
619 },
620 32,
621 ) => RelocationKind::Abs4,
622 (
623 object::Architecture::Riscv64,
624 object::RelocationFlags::Elf {
625 r_type: object::elf::R_RISCV_64,
626 },
627 64,
628 ) => RelocationKind::Abs8,
629 (
630 object::Architecture::Riscv64,
631 object::RelocationFlags::Elf {
632 r_type: object::elf::R_RISCV_32_PCREL,
633 },
634 0,
635 ) => RelocationKind::PCRel4,
636 (
637 object::Architecture::LoongArch64,
638 object::RelocationFlags::Elf {
639 r_type: object::elf::R_LARCH_ABS_HI20,
640 },
641 0,
642 ) => RelocationKind::LArchAbsHi20,
643 (
644 object::Architecture::LoongArch64,
645 object::RelocationFlags::Elf {
646 r_type: object::elf::R_LARCH_ABS_LO12,
647 },
648 0,
649 ) => RelocationKind::LArchAbsLo12,
650 (
651 object::Architecture::LoongArch64,
652 object::RelocationFlags::Elf {
653 r_type: object::elf::R_LARCH_ABS64_HI12,
654 },
655 0,
656 ) => RelocationKind::LArchAbs64Hi12,
657 (
658 object::Architecture::LoongArch64,
659 object::RelocationFlags::Elf {
660 r_type: object::elf::R_LARCH_ABS64_LO20,
661 },
662 0,
663 ) => RelocationKind::LArchAbs64Lo20,
664 (
665 object::Architecture::LoongArch64,
666 object::RelocationFlags::Elf {
667 r_type: object::elf::R_LARCH_CALL36,
668 },
669 0,
670 ) => RelocationKind::LArchCall36,
671 (
672 object::Architecture::LoongArch64,
673 object::RelocationFlags::Elf {
674 r_type: object::elf::R_LARCH_PCALA_HI20,
675 },
676 0,
677 ) => RelocationKind::LArchPCAlaHi20,
678 (
679 object::Architecture::LoongArch64,
680 object::RelocationFlags::Elf {
681 r_type: object::elf::R_LARCH_PCALA_LO12,
682 },
683 0,
684 ) => RelocationKind::LArchPCAlaLo12,
685 (
686 object::Architecture::LoongArch64,
687 object::RelocationFlags::Elf {
688 r_type: object::elf::R_LARCH_PCALA64_HI12,
689 },
690 0,
691 ) => RelocationKind::LArchPCAla64Hi12,
692 (
693 object::Architecture::LoongArch64,
694 object::RelocationFlags::Elf {
695 r_type: object::elf::R_LARCH_PCALA64_LO20,
696 },
697 0,
698 ) => RelocationKind::LArchPCAla64Lo20,
699 (
700 object::Architecture::Aarch64,
701 object::RelocationFlags::Elf {
702 r_type: object::elf::R_AARCH64_ADR_PREL_LO21,
703 },
704 0,
705 ) => RelocationKind::Aarch64AdrPrelLo21,
706 (
707 object::Architecture::LoongArch64,
708 object::RelocationFlags::Elf {
709 r_type: object::elf::R_LARCH_64,
710 },
711 64,
712 ) => RelocationKind::Abs8,
713 (
714 object::Architecture::LoongArch64,
715 object::RelocationFlags::Elf {
716 r_type: object::elf::R_LARCH_32_PCREL,
717 },
718 32,
719 ) => RelocationKind::PCRel4,
720 (
721 object::Architecture::Aarch64,
722 object::RelocationFlags::Elf {
723 r_type: object::elf::R_AARCH64_ADR_PREL_PG_HI21,
724 },
725 0,
726 ) => RelocationKind::Aarch64AdrPrelPgHi21,
727 (
728 object::Architecture::Aarch64,
729 object::RelocationFlags::Elf {
730 r_type: object::elf::R_AARCH64_LDST128_ABS_LO12_NC,
731 },
732 0,
733 ) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
734 (
735 object::Architecture::Aarch64,
736 object::RelocationFlags::Elf {
737 r_type: object::elf::R_AARCH64_ADD_ABS_LO12_NC,
738 },
739 0,
740 ) => RelocationKind::Aarch64AddAbsLo12Nc,
741 (
742 object::Architecture::Aarch64,
743 object::RelocationFlags::Elf {
744 r_type: object::elf::R_AARCH64_LDST64_ABS_LO12_NC,
745 },
746 0,
747 ) => RelocationKind::Aarch64Ldst64AbsLo12Nc,
748 (
749 object::Architecture::Aarch64,
750 object::RelocationFlags::Elf {
751 r_type: object::elf::R_AARCH64_PREL64,
752 },
753 64,
754 ) => RelocationKind::PCRel8,
755 (
756 object::Architecture::Aarch64,
757 object::RelocationFlags::Elf {
758 r_type: object::elf::R_AARCH64_ABS64,
759 },
760 64,
761 ) => RelocationKind::Abs8,
762 (
763 object::Architecture::Aarch64,
764 object::RelocationFlags::MachO { r_type: value, .. },
765 _,
766 ) => match value {
767 object::macho::ARM64_RELOC_UNSIGNED => RelocationKind::MachoArm64RelocUnsigned,
768 object::macho::ARM64_RELOC_SUBTRACTOR => {
769 RelocationKind::MachoArm64RelocSubtractor
770 }
771 object::macho::ARM64_RELOC_BRANCH26 => RelocationKind::MachoArm64RelocBranch26,
772 object::macho::ARM64_RELOC_PAGE21 => RelocationKind::MachoArm64RelocPage21,
773 object::macho::ARM64_RELOC_PAGEOFF12 => {
774 RelocationKind::MachoArm64RelocPageoff12
775 }
776 object::macho::ARM64_RELOC_GOT_LOAD_PAGE21 => {
777 RelocationKind::MachoArm64RelocGotLoadPage21
778 }
779 object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12 => {
780 RelocationKind::MachoArm64RelocGotLoadPageoff12
781 }
782 object::macho::ARM64_RELOC_POINTER_TO_GOT => {
783 RelocationKind::MachoArm64RelocPointerToGot
784 }
785 object::macho::ARM64_RELOC_TLVP_LOAD_PAGE21 => {
786 RelocationKind::MachoArm64RelocTlvpLoadPage21
787 }
788 object::macho::ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
789 RelocationKind::MachoArm64RelocTlvpLoadPageoff12
790 }
791 object::macho::ARM64_RELOC_ADDEND => RelocationKind::MachoArm64RelocAddend,
792 _ => {
793 return Err(CompileError::Codegen(format!(
794 "unknown relocation {reloc:?}",
795 )));
796 }
797 },
798 (
799 object::Architecture::X86_64,
800 object::RelocationFlags::MachO { r_type: value, .. },
801 _,
802 ) => match value {
803 object::macho::X86_64_RELOC_UNSIGNED => {
804 RelocationKind::MachoX86_64RelocUnsigned
805 }
806 object::macho::X86_64_RELOC_SIGNED => RelocationKind::MachoX86_64RelocSigned,
807 object::macho::X86_64_RELOC_BRANCH => RelocationKind::MachoX86_64RelocBranch,
808 object::macho::X86_64_RELOC_GOT_LOAD => RelocationKind::MachoX86_64RelocGotLoad,
809 object::macho::X86_64_RELOC_GOT => RelocationKind::MachoX86_64RelocGot,
810 object::macho::X86_64_RELOC_SUBTRACTOR => {
811 RelocationKind::MachoX86_64RelocSubtractor
812 }
813 object::macho::X86_64_RELOC_SIGNED_1 => RelocationKind::MachoX86_64RelocSigned1,
814 object::macho::X86_64_RELOC_SIGNED_2 => RelocationKind::MachoX86_64RelocSigned2,
815 object::macho::X86_64_RELOC_SIGNED_4 => RelocationKind::MachoX86_64RelocSigned4,
816 object::macho::X86_64_RELOC_TLV => RelocationKind::MachoX86_64RelocTlv,
817 _ => {
818 return Err(CompileError::Codegen(format!(
819 "unknown relocation {reloc:?}"
820 )));
821 }
822 },
823 _ => {
824 return Err(CompileError::Codegen(format!(
825 "unknown relocation {reloc:?}",
826 )));
827 }
828 };
829
830 relocations
831 .entry(section_index)
832 .or_default()
833 .push(Relocation {
834 kind,
835 reloc_target: target,
836 offset: offset.try_into().map_err(map_tryfromint_err)?,
837 addend,
838 });
839 }
840 }
841
842 let eh_frame_section_indices = eh_frame_section_indices
843 .iter()
844 .map(|index| {
845 section_to_custom_section.get(index).map_or_else(
846 || {
847 Err(CompileError::Codegen(format!(
848 ".eh_frame section with index={index:?} was never loaded",
849 )))
850 },
851 |idx| Ok(*idx),
852 )
853 })
854 .collect::<Result<Vec<SectionIndex>, _>>()?;
855
856 let compact_unwind_section_indices = compact_unwind_section_indices
857 .iter()
858 .map(|index| {
859 section_to_custom_section.get(index).map_or_else(
860 || {
861 Err(CompileError::Codegen(format!(
862 "_compact_unwind section with index={index:?} was never loaded",
863 )))
864 },
865 |idx| Ok(*idx),
866 )
867 })
868 .collect::<Result<Vec<SectionIndex>, _>>()?;
869
870 let gcc_except_table_section_indices = gcc_except_table_section_indices
871 .iter()
872 .map(|index| {
873 section_to_custom_section.get(index).map_or_else(
874 || {
875 Err(CompileError::Codegen(format!(
876 ".gcc_except_table section with index={index:?} was never loaded",
877 )))
878 },
879 |idx| Ok(*idx),
880 )
881 })
882 .collect::<Result<Vec<SectionIndex>, _>>()?;
883
884 let data_dw_ref_personality_section_indices = data_dw_ref_personality_section_indices
885 .iter()
886 .map(|index| {
887 section_to_custom_section.get(index).map_or_else(
888 || {
889 Err(CompileError::Codegen(format!(
890 ".data.DW.ref.wasmer_eh_personality section with index={index:?} was never loaded",
891 )))
892 },
893 |idx| Ok(*idx),
894 )
895 })
896 .collect::<Result<Vec<SectionIndex>, _>>()?;
897
898 let mut custom_sections = section_to_custom_section
899 .iter()
900 .map(|(elf_section_index, custom_section_index)| {
901 let section = obj.section_by_index(*elf_section_index).unwrap();
902 (
903 custom_section_index,
904 CustomSection {
905 protection: CustomSectionProtection::Read,
906 alignment: Some(section.align()),
907 bytes: SectionBody::new_with_vec(section.data().unwrap().to_vec()),
908 relocations: relocations
909 .remove_entry(elf_section_index)
910 .map_or(vec![], |(_, v)| v),
911 },
912 )
913 })
914 .collect::<Vec<_>>();
915 custom_sections.sort_unstable_by_key(|a| a.0);
916 let custom_sections = custom_sections
917 .into_iter()
918 .map(|(_, v)| v)
919 .collect::<PrimaryMap<SectionIndex, _>>();
920
921 let function_body = FunctionBody {
922 body: obj
923 .section_by_index(root_section_index)
924 .unwrap()
925 .data()
926 .unwrap()
927 .to_vec(),
928 unwind_info: None,
929 };
930
931 let address_map = FunctionAddressMap {
932 instructions: vec![InstructionAddressMap {
933 srcloc: SourceLoc::default(),
934 code_offset: 0,
935 code_len: function_body.body.len(),
936 }],
937 start_srcloc: SourceLoc::default(),
938 end_srcloc: SourceLoc::default(),
939 body_offset: 0,
940 body_len: function_body.body.len(),
941 };
942
943 Ok(RkyvCompiledFunction {
944 compiled_function: wasmer_compiler::types::function::CompiledFunction {
945 body: function_body,
946 relocations: relocations
947 .remove_entry(&root_section_index)
948 .map_or(vec![], |(_, v)| v),
949 frame_info: CompiledFunctionFrameInfo {
950 address_map,
951 traps: vec![],
952 },
953 maximum_stack_usage: None,
954 },
955 custom_sections,
956 eh_frame_section_indices,
957 compact_unwind_section_indices,
958 gcc_except_table_section_indices,
959 data_dw_ref_personality_section_indices,
960 })
961}