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