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