1use object::{Object, ObjectSection, ObjectSymbol};
2use target_lexicon::BinaryFormat;
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_vm::libcalls::LibCall;
18
19fn map_tryfromint_err(error: TryFromIntError) -> CompileError {
20 CompileError::Codegen(format!("int doesn't fit: {error}"))
21}
22
23fn map_object_err(error: object::read::Error) -> CompileError {
24 CompileError::Codegen(format!("error parsing object file: {error}"))
25}
26
27#[derive(Debug)]
28pub struct CompiledFunction {
29 pub compiled_function: wasmer_compiler::types::function::CompiledFunction,
30 pub custom_sections: CustomSections,
31 pub eh_frame_section_indices: Vec<SectionIndex>,
32 pub compact_unwind_section_indices: Vec<SectionIndex>,
33 pub gcc_except_table_section_indices: Vec<SectionIndex>,
34 pub data_dw_ref_personality_section_indices: Vec<SectionIndex>,
35}
36
37static LIBCALLS_ELF: phf::Map<&'static str, LibCall> = phf::phf_map! {
38 "ceilf" => LibCall::CeilF32,
39 "ceil" => LibCall::CeilF64,
40 "floorf" => LibCall::FloorF32,
41 "floor" => LibCall::FloorF64,
42 "nearbyintf" => LibCall::NearestF32,
43 "nearbyint" => LibCall::NearestF64,
44 "truncf" => LibCall::TruncF32,
45 "trunc" => LibCall::TruncF64,
46 "wasmer_vm_f32_ceil" => LibCall::CeilF32,
47 "wasmer_vm_f64_ceil" => LibCall::CeilF64,
48 "wasmer_vm_f32_floor" => LibCall::FloorF32,
49 "wasmer_vm_f64_floor" => LibCall::FloorF64,
50 "wasmer_vm_f32_nearest" => LibCall::NearestF32,
51 "wasmer_vm_f64_nearest" => LibCall::NearestF64,
52 "wasmer_vm_f32_trunc" => LibCall::TruncF32,
53 "wasmer_vm_f64_trunc" => LibCall::TruncF64,
54 "wasmer_vm_memory32_size" => LibCall::Memory32Size,
55 "wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
56 "wasmer_vm_table_copy" => LibCall::TableCopy,
57 "wasmer_vm_table_init" => LibCall::TableInit,
58 "wasmer_vm_table_fill" => LibCall::TableFill,
59 "wasmer_vm_table_size" => LibCall::TableSize,
60 "wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
61 "wasmer_vm_table_get" => LibCall::TableGet,
62 "wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
63 "wasmer_vm_table_set" => LibCall::TableSet,
64 "wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
65 "wasmer_vm_table_grow" => LibCall::TableGrow,
66 "wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
67 "wasmer_vm_func_ref" => LibCall::FuncRef,
68 "wasmer_vm_elem_drop" => LibCall::ElemDrop,
69 "wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
70 "wasmer_vm_imported_memory32_copy" => LibCall::ImportedMemory32Copy,
71 "wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
72 "wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
73 "wasmer_vm_memory32_init" => LibCall::Memory32Init,
74 "wasmer_vm_data_drop" => LibCall::DataDrop,
75 "wasmer_vm_raise_trap" => LibCall::RaiseTrap,
76 "wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
77 "wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
78 "wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
79 "wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
80 "wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
81 "wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
82 "wasmer_vm_throw" => LibCall::Throw,
83 "wasmer_vm_alloc_exception" => LibCall::AllocException,
84 "wasmer_vm_read_exnref" => LibCall::ReadExnRef,
85 "wasmer_vm_exception_into_exnref" => LibCall::LibunwindExceptionIntoExnRef,
86 "wasmer_eh_personality" => LibCall::EHPersonality,
87 "wasmer_eh_personality2" => LibCall::EHPersonality2,
88 "wasmer_vm_dbg_usize" => LibCall::DebugUsize,
89 "wasmer_vm_dbg_str" => LibCall::DebugStr,
90};
91
92static LIBCALLS_MACHO: phf::Map<&'static str, LibCall> = phf::phf_map! {
93 "_ceilf" => LibCall::CeilF32,
94 "_ceil" => LibCall::CeilF64,
95 "_floorf" => LibCall::FloorF32,
96 "_floor" => LibCall::FloorF64,
97 "_nearbyintf" => LibCall::NearestF32,
98 "_nearbyint" => LibCall::NearestF64,
99 "_truncf" => LibCall::TruncF32,
100 "_trunc" => LibCall::TruncF64,
101 "_wasmer_vm_f32_ceil" => LibCall::CeilF32,
102 "_wasmer_vm_f64_ceil" => LibCall::CeilF64,
103 "_wasmer_vm_f32_floor" => LibCall::FloorF32,
104 "_wasmer_vm_f64_floor" => LibCall::FloorF64,
105 "_wasmer_vm_f32_nearest" => LibCall::NearestF32,
106 "_wasmer_vm_f64_nearest" => LibCall::NearestF64,
107 "_wasmer_vm_f32_trunc" => LibCall::TruncF32,
108 "_wasmer_vm_f64_trunc" => LibCall::TruncF64,
109 "_wasmer_vm_memory32_size" => LibCall::Memory32Size,
110 "_wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
111 "_wasmer_vm_table_copy" => LibCall::TableCopy,
112 "_wasmer_vm_table_init" => LibCall::TableInit,
113 "_wasmer_vm_table_fill" => LibCall::TableFill,
114 "_wasmer_vm_table_size" => LibCall::TableSize,
115 "_wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
116 "_wasmer_vm_table_get" => LibCall::TableGet,
117 "_wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
118 "_wasmer_vm_table_set" => LibCall::TableSet,
119 "_wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
120 "_wasmer_vm_table_grow" => LibCall::TableGrow,
121 "_wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
122 "_wasmer_vm_func_ref" => LibCall::FuncRef,
123 "_wasmer_vm_elem_drop" => LibCall::ElemDrop,
124 "_wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
125 "_wasmer_vm_imported_memory32_copy" => LibCall::ImportedMemory32Copy,
126 "_wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
127 "_wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
128 "_wasmer_vm_memory32_init" => LibCall::Memory32Init,
129 "_wasmer_vm_data_drop" => LibCall::DataDrop,
130 "_wasmer_vm_raise_trap" => LibCall::RaiseTrap,
131 "_wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
132 "_wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
133 "_wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
134 "_wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
135 "_wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
136 "_wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
137
138 "_wasmer_vm_throw" => LibCall::Throw,
139 "_wasmer_vm_alloc_exception" => LibCall::AllocException,
140 "_wasmer_vm_read_exnref" => LibCall::ReadExnRef,
141 "_wasmer_vm_exception_into_exnref" => LibCall::LibunwindExceptionIntoExnRef,
142 "___gxx_personality_v0" => LibCall::EHPersonality,
147 "_wasmer_eh_personality2" => LibCall::EHPersonality2,
148 "_wasmer_vm_dbg_usize" => LibCall::DebugUsize,
149 "_wasmer_vm_dbg_str" => LibCall::DebugStr,
150};
151
152pub fn load_object_file<F>(
153 contents: &[u8],
154 root_section: &str,
155 root_section_reloc_target: RelocationTarget,
156 mut symbol_name_to_relocation_target: F,
157 binary_fmt: BinaryFormat,
158) -> Result<CompiledFunction, CompileError>
159where
160 F: FnMut(&str) -> Result<Option<RelocationTarget>, CompileError>,
161{
162 let obj = object::File::parse(contents).map_err(map_object_err)?;
163
164 let libcalls = match binary_fmt {
165 BinaryFormat::Elf => &LIBCALLS_ELF,
166 BinaryFormat::Macho => &LIBCALLS_MACHO,
167 _ => {
168 return Err(CompileError::UnsupportedTarget(format!(
169 "Unsupported binary format {binary_fmt:?}"
170 )));
171 }
172 };
173
174 let mut worklist: Vec<object::read::SectionIndex> = Vec::new();
175 let mut section_targets: HashMap<object::read::SectionIndex, RelocationTarget> = HashMap::new();
176
177 let root_section_index = obj
178 .section_by_name(root_section)
179 .ok_or_else(|| CompileError::Codegen(format!("no section named {root_section}")))?
180 .index();
181
182 let mut section_to_custom_section = HashMap::new();
183
184 section_targets.insert(root_section_index, root_section_reloc_target);
185
186 let mut next_custom_section: u32 = 0;
187
188 let mut elf_section_to_target = |elf_section_index: object::read::SectionIndex| {
189 *section_targets.entry(elf_section_index).or_insert_with(|| {
190 let next = SectionIndex::from_u32(next_custom_section);
191 section_to_custom_section.insert(elf_section_index, next);
192 let target = RelocationTarget::CustomSection(next);
193 next_custom_section += 1;
194 target
195 })
196 };
197
198 let mut relocations: HashMap<object::read::SectionIndex, Vec<Relocation>> = HashMap::new();
201
202 worklist.push(root_section_index);
216
217 let mut eh_frame_section_indices = vec![];
219
220 let mut compact_unwind_section_indices = vec![];
222
223 let mut gcc_except_table_section_indices = vec![];
228
229 let mut data_dw_ref_personality_section_indices = vec![];
230
231 for section in obj.sections() {
232 let index = section.index();
233 let Ok(section_name) = section.name() else {
234 continue;
235 };
236
237 match section_name {
238 "__eh_frame" | ".eh_frame" => {
239 worklist.push(index);
240 eh_frame_section_indices.push(index);
241
242 elf_section_to_target(index);
244 }
245 "__compact_unwind" => {
246 worklist.push(index);
247 compact_unwind_section_indices.push(index);
248
249 elf_section_to_target(index);
250 }
251 ".gcc_except_table" => {
252 worklist.push(index);
253 gcc_except_table_section_indices.push(index);
254
255 elf_section_to_target(index);
256 }
257 ".data.DW.ref.wasmer_eh_personality" => {
258 worklist.push(index);
259 data_dw_ref_personality_section_indices.push(index);
260
261 elf_section_to_target(index);
262 }
263 _ => {}
264 }
265 }
266
267 let mut visited: HashSet<_> = HashSet::from_iter(worklist.iter().copied());
268 while let Some(section_index) = worklist.pop() {
269 let sec = obj
270 .section_by_index(section_index)
271 .map_err(map_object_err)?;
272 let relocs = sec.relocations();
273 for (offset, reloc) in relocs {
274 let mut addend = reloc.addend();
275 let target = match reloc.target() {
276 object::read::RelocationTarget::Symbol(index) => {
277 let symbol = obj.symbol_by_index(index).map_err(map_object_err)?;
278 let symbol_name = symbol.name().map_err(map_object_err)?;
279 if symbol.kind() == object::SymbolKind::Section {
280 match symbol.section() {
281 object::SymbolSection::Section(section_index) => {
282 if section_index == root_section_index {
283 root_section_reloc_target
284 } else {
285 if visited.insert(section_index) {
286 worklist.push(section_index);
287 }
288 elf_section_to_target(section_index)
289 }
290 }
291 _ => {
292 return Err(CompileError::Codegen(format!(
293 "relocation targets unknown section {reloc:?}",
294 )));
295 }
296 }
297 } else if let Some(libcall) = libcalls.get(symbol_name) {
299 RelocationTarget::LibCall(*libcall)
300 } else if let Ok(Some(reloc_target)) =
301 symbol_name_to_relocation_target(symbol_name)
302 {
303 reloc_target
304 } else if let object::SymbolSection::Section(section_index) = symbol.section() {
305 if matches!(
306 reloc.flags(),
307 object::RelocationFlags::MachO {
308 r_type: object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12,
309 r_pcrel: false,
310 ..
311 } | object::RelocationFlags::MachO {
312 r_type: object::macho::ARM64_RELOC_POINTER_TO_GOT,
313 r_pcrel: true,
314 ..
315 } | object::RelocationFlags::MachO {
316 r_type: object::macho::ARM64_RELOC_GOT_LOAD_PAGE21,
317 r_pcrel: true,
318 ..
319 } | object::RelocationFlags::MachO {
320 r_type: object::macho::ARM64_RELOC_PAGE21,
321 r_pcrel: true,
322 ..
323 } | object::RelocationFlags::MachO {
324 r_type: object::macho::ARM64_RELOC_PAGEOFF12,
325 r_pcrel: false,
326 ..
327 }
328 ) {
329 let symbol_sec = obj
349 .section_by_index(section_index)
350 .map_err(map_object_err)?;
351
352 addend = addend
353 .wrapping_add((symbol.address() - symbol_sec.address()) as i64);
354 } else {
355 addend = addend.wrapping_add(symbol.address() as i64);
357 }
358
359 if section_index == root_section_index {
360 root_section_reloc_target
361 } else {
362 if visited.insert(section_index) {
363 worklist.push(section_index);
364 }
365
366 elf_section_to_target(section_index)
367 }
368 } else {
369 return Err(CompileError::Codegen(format!(
370 "relocation {reloc:?} targets unknown symbol '{symbol:?}'",
371 )));
372 }
373 }
374
375 object::read::RelocationTarget::Section(index) => {
376 if index == root_section_index {
377 root_section_reloc_target
378 } else {
379 if visited.insert(index) {
380 worklist.push(index);
381 }
382 elf_section_to_target(index)
383 }
384 }
385
386 object::read::RelocationTarget::Absolute => {
387 return Err(CompileError::Codegen(format!(
391 "relocation targets absolute address {reloc:?}",
392 )));
393 }
394
395 t => {
402 return Err(CompileError::Codegen(format!(
403 "relocation target is unknown `{t:?}`",
404 )));
405 }
406 };
407 let kind = match (obj.architecture(), reloc.flags(), reloc.size()) {
408 (
409 _,
410 object::RelocationFlags::Elf {
411 r_type: object::elf::R_X86_64_64,
412 },
413 64,
414 ) => RelocationKind::Abs8,
415 (
416 object::Architecture::X86_64,
417 object::RelocationFlags::Elf {
418 r_type: object::elf::R_X86_64_PC64,
419 },
420 0,
421 ) => RelocationKind::PCRel8,
422 (
423 object::Architecture::Aarch64,
424 object::RelocationFlags::Elf {
425 r_type: object::elf::R_AARCH64_CALL26,
426 },
427 26,
428 ) => RelocationKind::Arm64Call,
429 (
430 object::Architecture::Aarch64,
431 object::RelocationFlags::Elf {
432 r_type: object::elf::R_AARCH64_MOVW_UABS_G0_NC,
433 },
434 0,
435 ) => RelocationKind::Arm64Movw0,
436 (
437 object::Architecture::Aarch64,
438 object::RelocationFlags::Elf {
439 r_type: object::elf::R_AARCH64_MOVW_UABS_G1_NC,
440 },
441 0,
442 ) => RelocationKind::Arm64Movw1,
443 (
444 object::Architecture::Aarch64,
445 object::RelocationFlags::Elf {
446 r_type: object::elf::R_AARCH64_MOVW_UABS_G2_NC,
447 },
448 0,
449 ) => RelocationKind::Arm64Movw2,
450 (
451 object::Architecture::Aarch64,
452 object::RelocationFlags::Elf {
453 r_type: object::elf::R_AARCH64_MOVW_UABS_G3,
454 },
455 0,
456 ) => RelocationKind::Arm64Movw3,
457 (
458 object::Architecture::Riscv64,
459 object::RelocationFlags::Elf {
460 r_type: object::elf::R_RISCV_CALL_PLT,
461 },
462 0,
463 ) => RelocationKind::RiscvCall,
464 (
465 object::Architecture::Riscv64,
466 object::RelocationFlags::Elf {
467 r_type: object::elf::R_RISCV_PCREL_HI20,
468 },
469 0,
470 ) => RelocationKind::RiscvPCRelHi20,
471 (
472 object::Architecture::Riscv64,
473 object::RelocationFlags::Elf {
474 r_type: object::elf::R_RISCV_PCREL_LO12_I,
475 },
476 0,
477 ) => RelocationKind::RiscvPCRelLo12I,
478 (
479 object::Architecture::Riscv64,
480 object::RelocationFlags::Elf {
481 r_type: object::elf::R_RISCV_ADD8,
482 },
483 0,
484 ) => RelocationKind::Add,
485 (
486 object::Architecture::Riscv64,
487 object::RelocationFlags::Elf {
488 r_type: object::elf::R_RISCV_ADD16,
489 },
490 0,
491 ) => RelocationKind::Add2,
492 (
493 object::Architecture::Riscv64,
494 object::RelocationFlags::Elf {
495 r_type: object::elf::R_RISCV_ADD32,
496 },
497 0,
498 ) => RelocationKind::Add4,
499 (
500 object::Architecture::Riscv64,
501 object::RelocationFlags::Elf {
502 r_type: object::elf::R_RISCV_ADD64,
503 },
504 0,
505 ) => RelocationKind::Add8,
506 (
507 object::Architecture::Riscv64,
508 object::RelocationFlags::Elf {
509 r_type: object::elf::R_RISCV_SUB6,
510 },
511 0,
512 ) => RelocationKind::Sub6Bits,
513 (
514 object::Architecture::Riscv64,
515 object::RelocationFlags::Elf {
516 r_type: object::elf::R_RISCV_SUB8,
517 },
518 0,
519 ) => RelocationKind::Sub,
520 (
521 object::Architecture::Riscv64,
522 object::RelocationFlags::Elf {
523 r_type: object::elf::R_RISCV_SUB16,
524 },
525 0,
526 ) => RelocationKind::Sub2,
527 (
528 object::Architecture::Riscv64,
529 object::RelocationFlags::Elf {
530 r_type: object::elf::R_RISCV_SUB32,
531 },
532 0,
533 ) => RelocationKind::Sub4,
534 (
535 object::Architecture::Riscv64,
536 object::RelocationFlags::Elf {
537 r_type: object::elf::R_RISCV_SUB64,
538 },
539 0,
540 ) => RelocationKind::Sub8,
541 (
542 object::Architecture::Riscv64,
543 object::RelocationFlags::Elf {
544 r_type: object::elf::R_RISCV_SET6,
545 },
546 0,
547 ) => RelocationKind::Abs6Bits,
548 (
549 object::Architecture::Riscv64,
550 object::RelocationFlags::Elf {
551 r_type: object::elf::R_RISCV_SET8,
552 },
553 0,
554 ) => RelocationKind::Abs,
555 (
556 object::Architecture::Riscv64,
557 object::RelocationFlags::Elf {
558 r_type: object::elf::R_RISCV_SET16,
559 },
560 0,
561 ) => RelocationKind::Abs2,
562 (
563 object::Architecture::Riscv64,
564 object::RelocationFlags::Elf {
565 r_type: object::elf::R_RISCV_SET32,
566 },
567 0,
568 ) => RelocationKind::Abs4,
569 (
570 object::Architecture::Riscv64,
571 object::RelocationFlags::Elf {
572 r_type: object::elf::R_RISCV_32,
573 },
574 32,
575 ) => RelocationKind::Abs4,
576 (
577 object::Architecture::Riscv64,
578 object::RelocationFlags::Elf {
579 r_type: object::elf::R_RISCV_64,
580 },
581 64,
582 ) => RelocationKind::Abs8,
583 (
584 object::Architecture::Riscv64,
585 object::RelocationFlags::Elf {
586 r_type: object::elf::R_RISCV_32_PCREL,
587 },
588 0,
589 ) => RelocationKind::PCRel4,
590 (
591 object::Architecture::LoongArch64,
592 object::RelocationFlags::Elf {
593 r_type: object::elf::R_LARCH_ABS_HI20,
594 },
595 0,
596 ) => RelocationKind::LArchAbsHi20,
597 (
598 object::Architecture::LoongArch64,
599 object::RelocationFlags::Elf {
600 r_type: object::elf::R_LARCH_ABS_LO12,
601 },
602 0,
603 ) => RelocationKind::LArchAbsLo12,
604 (
605 object::Architecture::LoongArch64,
606 object::RelocationFlags::Elf {
607 r_type: object::elf::R_LARCH_ABS64_HI12,
608 },
609 0,
610 ) => RelocationKind::LArchAbs64Hi12,
611 (
612 object::Architecture::LoongArch64,
613 object::RelocationFlags::Elf {
614 r_type: object::elf::R_LARCH_ABS64_LO20,
615 },
616 0,
617 ) => RelocationKind::LArchAbs64Lo20,
618 (
619 object::Architecture::LoongArch64,
620 object::RelocationFlags::Elf {
621 r_type: object::elf::R_LARCH_CALL36,
622 },
623 0,
624 ) => RelocationKind::LArchCall36,
625 (
626 object::Architecture::LoongArch64,
627 object::RelocationFlags::Elf {
628 r_type: object::elf::R_LARCH_PCALA_HI20,
629 },
630 0,
631 ) => RelocationKind::LArchPCAlaHi20,
632 (
633 object::Architecture::LoongArch64,
634 object::RelocationFlags::Elf {
635 r_type: object::elf::R_LARCH_PCALA_LO12,
636 },
637 0,
638 ) => RelocationKind::LArchPCAlaLo12,
639 (
640 object::Architecture::LoongArch64,
641 object::RelocationFlags::Elf {
642 r_type: object::elf::R_LARCH_PCALA64_HI12,
643 },
644 0,
645 ) => RelocationKind::LArchPCAla64Hi12,
646 (
647 object::Architecture::LoongArch64,
648 object::RelocationFlags::Elf {
649 r_type: object::elf::R_LARCH_PCALA64_LO20,
650 },
651 0,
652 ) => RelocationKind::LArchPCAla64Lo20,
653 (
654 object::Architecture::Aarch64,
655 object::RelocationFlags::Elf {
656 r_type: object::elf::R_AARCH64_ADR_PREL_LO21,
657 },
658 0,
659 ) => RelocationKind::Aarch64AdrPrelLo21,
660 (
661 object::Architecture::LoongArch64,
662 object::RelocationFlags::Elf {
663 r_type: object::elf::R_LARCH_64,
664 },
665 64,
666 ) => RelocationKind::Abs8,
667 (
668 object::Architecture::LoongArch64,
669 object::RelocationFlags::Elf {
670 r_type: object::elf::R_LARCH_32_PCREL,
671 },
672 32,
673 ) => RelocationKind::PCRel4,
674 (
675 object::Architecture::Aarch64,
676 object::RelocationFlags::Elf {
677 r_type: object::elf::R_AARCH64_ADR_PREL_PG_HI21,
678 },
679 0,
680 ) => RelocationKind::Aarch64AdrPrelPgHi21,
681 (
682 object::Architecture::Aarch64,
683 object::RelocationFlags::Elf {
684 r_type: object::elf::R_AARCH64_LDST128_ABS_LO12_NC,
685 },
686 0,
687 ) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
688 (
689 object::Architecture::Aarch64,
690 object::RelocationFlags::Elf {
691 r_type: object::elf::R_AARCH64_ADD_ABS_LO12_NC,
692 },
693 0,
694 ) => RelocationKind::Aarch64AddAbsLo12Nc,
695 (
696 object::Architecture::Aarch64,
697 object::RelocationFlags::Elf {
698 r_type: object::elf::R_AARCH64_LDST64_ABS_LO12_NC,
699 },
700 0,
701 ) => RelocationKind::Aarch64Ldst64AbsLo12Nc,
702 (
703 object::Architecture::Aarch64,
704 object::RelocationFlags::Elf {
705 r_type: object::elf::R_AARCH64_PREL64,
706 },
707 64,
708 ) => RelocationKind::PCRel8,
709 (
710 object::Architecture::Aarch64,
711 object::RelocationFlags::Elf {
712 r_type: object::elf::R_AARCH64_ABS64,
713 },
714 64,
715 ) => RelocationKind::Abs8,
716 (
717 object::Architecture::Aarch64,
718 object::RelocationFlags::MachO { r_type: value, .. },
719 _,
720 ) => match value {
721 object::macho::ARM64_RELOC_UNSIGNED => RelocationKind::MachoArm64RelocUnsigned,
722 object::macho::ARM64_RELOC_SUBTRACTOR => {
723 RelocationKind::MachoArm64RelocSubtractor
724 }
725 object::macho::ARM64_RELOC_BRANCH26 => RelocationKind::MachoArm64RelocBranch26,
726 object::macho::ARM64_RELOC_PAGE21 => RelocationKind::MachoArm64RelocPage21,
727 object::macho::ARM64_RELOC_PAGEOFF12 => {
728 RelocationKind::MachoArm64RelocPageoff12
729 }
730 object::macho::ARM64_RELOC_GOT_LOAD_PAGE21 => {
731 RelocationKind::MachoArm64RelocGotLoadPage21
732 }
733 object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12 => {
734 RelocationKind::MachoArm64RelocGotLoadPageoff12
735 }
736 object::macho::ARM64_RELOC_POINTER_TO_GOT => {
737 RelocationKind::MachoArm64RelocPointerToGot
738 }
739 object::macho::ARM64_RELOC_TLVP_LOAD_PAGE21 => {
740 RelocationKind::MachoArm64RelocTlvpLoadPage21
741 }
742 object::macho::ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
743 RelocationKind::MachoArm64RelocTlvpLoadPageoff12
744 }
745 object::macho::ARM64_RELOC_ADDEND => RelocationKind::MachoArm64RelocAddend,
746 _ => {
747 return Err(CompileError::Codegen(format!(
748 "unknown relocation {reloc:?}",
749 )));
750 }
751 },
752 (
753 object::Architecture::X86_64,
754 object::RelocationFlags::MachO { r_type: value, .. },
755 _,
756 ) => match value {
757 object::macho::X86_64_RELOC_UNSIGNED => {
758 RelocationKind::MachoX86_64RelocUnsigned
759 }
760 object::macho::X86_64_RELOC_SIGNED => RelocationKind::MachoX86_64RelocSigned,
761 object::macho::X86_64_RELOC_BRANCH => RelocationKind::MachoX86_64RelocBranch,
762 object::macho::X86_64_RELOC_GOT_LOAD => RelocationKind::MachoX86_64RelocGotLoad,
763 object::macho::X86_64_RELOC_GOT => RelocationKind::MachoX86_64RelocGot,
764 object::macho::X86_64_RELOC_SUBTRACTOR => {
765 RelocationKind::MachoX86_64RelocSubtractor
766 }
767 object::macho::X86_64_RELOC_SIGNED_1 => RelocationKind::MachoX86_64RelocSigned1,
768 object::macho::X86_64_RELOC_SIGNED_2 => RelocationKind::MachoX86_64RelocSigned2,
769 object::macho::X86_64_RELOC_SIGNED_4 => RelocationKind::MachoX86_64RelocSigned4,
770 object::macho::X86_64_RELOC_TLV => RelocationKind::MachoX86_64RelocTlv,
771 _ => {
772 return Err(CompileError::Codegen(format!(
773 "unknown relocation {reloc:?}"
774 )));
775 }
776 },
777 _ => {
778 return Err(CompileError::Codegen(format!(
779 "unknown relocation {reloc:?}",
780 )));
781 }
782 };
783
784 relocations
785 .entry(section_index)
786 .or_default()
787 .push(Relocation {
788 kind,
789 reloc_target: target,
790 offset: offset.try_into().map_err(map_tryfromint_err)?,
791 addend,
792 });
793 }
794 }
795
796 let eh_frame_section_indices = eh_frame_section_indices
797 .iter()
798 .map(|index| {
799 section_to_custom_section.get(index).map_or_else(
800 || {
801 Err(CompileError::Codegen(format!(
802 ".eh_frame section with index={index:?} was never loaded",
803 )))
804 },
805 |idx| Ok(*idx),
806 )
807 })
808 .collect::<Result<Vec<SectionIndex>, _>>()?;
809
810 let compact_unwind_section_indices = compact_unwind_section_indices
811 .iter()
812 .map(|index| {
813 section_to_custom_section.get(index).map_or_else(
814 || {
815 Err(CompileError::Codegen(format!(
816 "_compact_unwind section with index={index:?} was never loaded",
817 )))
818 },
819 |idx| Ok(*idx),
820 )
821 })
822 .collect::<Result<Vec<SectionIndex>, _>>()?;
823
824 let gcc_except_table_section_indices = gcc_except_table_section_indices
825 .iter()
826 .map(|index| {
827 section_to_custom_section.get(index).map_or_else(
828 || {
829 Err(CompileError::Codegen(format!(
830 ".gcc_except_table section with index={index:?} was never loaded",
831 )))
832 },
833 |idx| Ok(*idx),
834 )
835 })
836 .collect::<Result<Vec<SectionIndex>, _>>()?;
837
838 let data_dw_ref_personality_section_indices = data_dw_ref_personality_section_indices
839 .iter()
840 .map(|index| {
841 section_to_custom_section.get(index).map_or_else(
842 || {
843 Err(CompileError::Codegen(format!(
844 ".data.DW.ref.wasmer_eh_personality section with index={index:?} was never loaded",
845 )))
846 },
847 |idx| Ok(*idx),
848 )
849 })
850 .collect::<Result<Vec<SectionIndex>, _>>()?;
851
852 let mut custom_sections = section_to_custom_section
853 .iter()
854 .map(|(elf_section_index, custom_section_index)| {
855 let section = obj.section_by_index(*elf_section_index).unwrap();
856 (
857 custom_section_index,
858 CustomSection {
859 protection: CustomSectionProtection::Read,
860 alignment: Some(section.align()),
861 bytes: SectionBody::new_with_vec(section.data().unwrap().to_vec()),
862 relocations: relocations
863 .remove_entry(elf_section_index)
864 .map_or(vec![], |(_, v)| v),
865 },
866 )
867 })
868 .collect::<Vec<_>>();
869 custom_sections.sort_unstable_by_key(|a| a.0);
870 let custom_sections = custom_sections
871 .into_iter()
872 .map(|(_, v)| v)
873 .collect::<PrimaryMap<SectionIndex, _>>();
874
875 let function_body = FunctionBody {
876 body: obj
877 .section_by_index(root_section_index)
878 .unwrap()
879 .data()
880 .unwrap()
881 .to_vec(),
882 unwind_info: None,
883 };
884
885 let address_map = FunctionAddressMap {
886 instructions: vec![InstructionAddressMap {
887 srcloc: SourceLoc::default(),
888 code_offset: 0,
889 code_len: function_body.body.len(),
890 }],
891 start_srcloc: SourceLoc::default(),
892 end_srcloc: SourceLoc::default(),
893 body_offset: 0,
894 body_len: function_body.body.len(),
895 };
896
897 Ok(CompiledFunction {
898 compiled_function: wasmer_compiler::types::function::CompiledFunction {
899 body: function_body,
900 relocations: relocations
901 .remove_entry(&root_section_index)
902 .map_or(vec![], |(_, v)| v),
903 frame_info: CompiledFunctionFrameInfo {
904 address_map,
905 traps: vec![],
906 },
907 },
908 custom_sections,
909 eh_frame_section_indices,
910 compact_unwind_section_indices,
911 gcc_except_table_section_indices,
912 data_dw_ref_personality_section_indices,
913 })
914}