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}
35
36static LIBCALLS_ELF: phf::Map<&'static str, LibCall> = phf::phf_map! {
37 "ceilf" => LibCall::CeilF32,
38 "ceil" => LibCall::CeilF64,
39 "floorf" => LibCall::FloorF32,
40 "floor" => LibCall::FloorF64,
41 "nearbyintf" => LibCall::NearestF32,
42 "nearbyint" => LibCall::NearestF64,
43 "truncf" => LibCall::TruncF32,
44 "trunc" => LibCall::TruncF64,
45 "wasmer_vm_f32_ceil" => LibCall::CeilF32,
46 "wasmer_vm_f64_ceil" => LibCall::CeilF64,
47 "wasmer_vm_f32_floor" => LibCall::FloorF32,
48 "wasmer_vm_f64_floor" => LibCall::FloorF64,
49 "wasmer_vm_f32_nearest" => LibCall::NearestF32,
50 "wasmer_vm_f64_nearest" => LibCall::NearestF64,
51 "wasmer_vm_f32_trunc" => LibCall::TruncF32,
52 "wasmer_vm_f64_trunc" => LibCall::TruncF64,
53 "wasmer_vm_memory32_size" => LibCall::Memory32Size,
54 "wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
55 "wasmer_vm_table_copy" => LibCall::TableCopy,
56 "wasmer_vm_table_init" => LibCall::TableInit,
57 "wasmer_vm_table_fill" => LibCall::TableFill,
58 "wasmer_vm_table_size" => LibCall::TableSize,
59 "wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
60 "wasmer_vm_table_get" => LibCall::TableGet,
61 "wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
62 "wasmer_vm_table_set" => LibCall::TableSet,
63 "wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
64 "wasmer_vm_table_grow" => LibCall::TableGrow,
65 "wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
66 "wasmer_vm_func_ref" => LibCall::FuncRef,
67 "wasmer_vm_elem_drop" => LibCall::ElemDrop,
68 "wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
69 "wasmer_vm_imported_memory32_copy" => LibCall::ImportedMemory32Copy,
70 "wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
71 "wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
72 "wasmer_vm_memory32_init" => LibCall::Memory32Init,
73 "wasmer_vm_data_drop" => LibCall::DataDrop,
74 "wasmer_vm_raise_trap" => LibCall::RaiseTrap,
75 "wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
76 "wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
77 "wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
78 "wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
79 "wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
80 "wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
81 "wasmer_vm_throw" => LibCall::Throw,
82 "wasmer_vm_alloc_exception" => LibCall::AllocException,
83 "wasmer_vm_read_exnref" => LibCall::ReadExnRef,
84 "wasmer_vm_exception_into_exnref" => LibCall::LibunwindExceptionIntoExnRef,
85 "wasmer_eh_personality" => LibCall::EHPersonality,
86 "wasmer_eh_personality2" => LibCall::EHPersonality2,
87 "wasmer_vm_dbg_usize" => LibCall::DebugUsize,
88 "wasmer_vm_dbg_str" => LibCall::DebugStr,
89};
90
91static LIBCALLS_MACHO: phf::Map<&'static str, LibCall> = phf::phf_map! {
92 "_ceilf" => LibCall::CeilF32,
93 "_ceil" => LibCall::CeilF64,
94 "_floorf" => LibCall::FloorF32,
95 "_floor" => LibCall::FloorF64,
96 "_nearbyintf" => LibCall::NearestF32,
97 "_nearbyint" => LibCall::NearestF64,
98 "_truncf" => LibCall::TruncF32,
99 "_trunc" => LibCall::TruncF64,
100 "_wasmer_vm_f32_ceil" => LibCall::CeilF32,
101 "_wasmer_vm_f64_ceil" => LibCall::CeilF64,
102 "_wasmer_vm_f32_floor" => LibCall::FloorF32,
103 "_wasmer_vm_f64_floor" => LibCall::FloorF64,
104 "_wasmer_vm_f32_nearest" => LibCall::NearestF32,
105 "_wasmer_vm_f64_nearest" => LibCall::NearestF64,
106 "_wasmer_vm_f32_trunc" => LibCall::TruncF32,
107 "_wasmer_vm_f64_trunc" => LibCall::TruncF64,
108 "_wasmer_vm_memory32_size" => LibCall::Memory32Size,
109 "_wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
110 "_wasmer_vm_table_copy" => LibCall::TableCopy,
111 "_wasmer_vm_table_init" => LibCall::TableInit,
112 "_wasmer_vm_table_fill" => LibCall::TableFill,
113 "_wasmer_vm_table_size" => LibCall::TableSize,
114 "_wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
115 "_wasmer_vm_table_get" => LibCall::TableGet,
116 "_wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
117 "_wasmer_vm_table_set" => LibCall::TableSet,
118 "_wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
119 "_wasmer_vm_table_grow" => LibCall::TableGrow,
120 "_wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
121 "_wasmer_vm_func_ref" => LibCall::FuncRef,
122 "_wasmer_vm_elem_drop" => LibCall::ElemDrop,
123 "_wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
124 "_wasmer_vm_imported_memory32_copy" => LibCall::ImportedMemory32Copy,
125 "_wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
126 "_wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
127 "_wasmer_vm_memory32_init" => LibCall::Memory32Init,
128 "_wasmer_vm_data_drop" => LibCall::DataDrop,
129 "_wasmer_vm_raise_trap" => LibCall::RaiseTrap,
130 "_wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
131 "_wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
132 "_wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
133 "_wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
134 "_wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
135 "_wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
136
137 "_wasmer_vm_throw" => LibCall::Throw,
138 "_wasmer_vm_alloc_exception" => LibCall::AllocException,
139 "_wasmer_vm_read_exnref" => LibCall::ReadExnRef,
140 "_wasmer_vm_exception_into_exnref" => LibCall::LibunwindExceptionIntoExnRef,
141 "___gxx_personality_v0" => LibCall::EHPersonality,
146 "_wasmer_eh_personality2" => LibCall::EHPersonality2,
147 "_wasmer_vm_dbg_usize" => LibCall::DebugUsize,
148 "_wasmer_vm_dbg_str" => LibCall::DebugStr,
149};
150
151pub fn load_object_file<F>(
152 contents: &[u8],
153 root_section: &str,
154 root_section_reloc_target: RelocationTarget,
155 mut symbol_name_to_relocation_target: F,
156 binary_fmt: BinaryFormat,
157) -> Result<CompiledFunction, CompileError>
158where
159 F: FnMut(&str) -> Result<Option<RelocationTarget>, CompileError>,
160{
161 let obj = object::File::parse(contents).map_err(map_object_err)?;
162
163 let libcalls = match binary_fmt {
164 BinaryFormat::Elf => &LIBCALLS_ELF,
165 BinaryFormat::Macho => &LIBCALLS_MACHO,
166 _ => {
167 return Err(CompileError::UnsupportedTarget(format!(
168 "Unsupported binary format {binary_fmt:?}"
169 )));
170 }
171 };
172
173 let mut visited: HashSet<object::read::SectionIndex> = HashSet::new();
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 visited.insert(root_section_index);
217
218 let mut eh_frame_section_indices = vec![];
220
221 let mut compact_unwind_section_indices = vec![];
223
224 let mut gcc_except_table_section_indices = vec![];
229
230 for section in obj.sections() {
231 let index = section.index();
232 if section.kind() == object::SectionKind::Elf(object::elf::SHT_X86_64_UNWIND)
233 || section.name().unwrap_or_default() == "__eh_frame"
234 {
235 worklist.push(index);
236 eh_frame_section_indices.push(index);
237
238 elf_section_to_target(index);
240 } else if section.name().unwrap_or_default() == "__compact_unwind" {
241 worklist.push(index);
242 compact_unwind_section_indices.push(index);
243
244 elf_section_to_target(index);
245 } else if section.name().unwrap_or_default() == ".gcc_except_table" {
246 worklist.push(index);
247 gcc_except_table_section_indices.push(index);
248
249 elf_section_to_target(index);
250 }
251 }
252
253 while let Some(section_index) = worklist.pop() {
254 let sec = obj
255 .section_by_index(section_index)
256 .map_err(map_object_err)?;
257 let relocs = sec.relocations();
258 for (offset, reloc) in relocs {
259 let mut addend = reloc.addend();
260 let target = match reloc.target() {
261 object::read::RelocationTarget::Symbol(index) => {
262 let symbol = obj.symbol_by_index(index).map_err(map_object_err)?;
263 let symbol_name = symbol.name().map_err(map_object_err)?;
264 if symbol.kind() == object::SymbolKind::Section {
265 match symbol.section() {
266 object::SymbolSection::Section(section_index) => {
267 if section_index == root_section_index {
268 root_section_reloc_target
269 } else {
270 if visited.insert(section_index) {
271 worklist.push(section_index);
272 }
273 elf_section_to_target(section_index)
274 }
275 }
276 _ => {
277 return Err(CompileError::Codegen(format!(
278 "relocation targets unknown section {reloc:?}",
279 )));
280 }
281 }
282 } else if let Some(libcall) = libcalls.get(symbol_name) {
284 RelocationTarget::LibCall(*libcall)
285 } else if let Ok(Some(reloc_target)) =
286 symbol_name_to_relocation_target(symbol_name)
287 {
288 reloc_target
289 } else if let object::SymbolSection::Section(section_index) = symbol.section() {
290 if matches!(
291 reloc.kind(),
292 object::RelocationKind::MachO {
293 value: object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12,
294 relative: false
295 } | object::RelocationKind::MachO {
296 value: object::macho::ARM64_RELOC_POINTER_TO_GOT,
297 relative: true
298 } | object::RelocationKind::MachO {
299 value: object::macho::ARM64_RELOC_GOT_LOAD_PAGE21,
300 relative: true
301 } | object::RelocationKind::MachO {
302 value: object::macho::ARM64_RELOC_PAGE21,
303 relative: true
304 } | object::RelocationKind::MachO {
305 value: object::macho::ARM64_RELOC_PAGEOFF12,
306 relative: false
307 }
308 ) {
309 let symbol_sec = obj
329 .section_by_index(section_index)
330 .map_err(map_object_err)?;
331
332 addend = addend
333 .wrapping_add((symbol.address() - symbol_sec.address()) as i64);
334 } else {
335 addend = addend.wrapping_add(symbol.address() as i64);
337 }
338
339 if section_index == root_section_index {
340 root_section_reloc_target
341 } else {
342 if visited.insert(section_index) {
343 worklist.push(section_index);
344 }
345
346 elf_section_to_target(section_index)
347 }
348 } else {
349 return Err(CompileError::Codegen(format!(
350 "relocation {reloc:?} targets unknown symbol '{symbol:?}'",
351 )));
352 }
353 }
354
355 object::read::RelocationTarget::Section(index) => {
356 if index == root_section_index {
357 root_section_reloc_target
358 } else {
359 if visited.insert(index) {
360 worklist.push(index);
361 }
362 elf_section_to_target(index)
363 }
364 }
365
366 object::read::RelocationTarget::Absolute => {
367 return Err(CompileError::Codegen(format!(
371 "relocation targets absolute address {reloc:?}",
372 )));
373 }
374
375 t => {
382 return Err(CompileError::Codegen(format!(
383 "relocation target is unknown `{t:?}`",
384 )));
385 }
386 };
387 let kind = match (obj.architecture(), reloc.kind(), reloc.size()) {
388 (_, object::RelocationKind::Absolute, 64) => RelocationKind::Abs8,
389 (_, object::RelocationKind::Absolute, 32) => RelocationKind::Abs4,
390 (
391 object::Architecture::X86_64,
392 object::RelocationKind::Elf(object::elf::R_X86_64_PC64),
393 0,
394 ) => RelocationKind::X86PCRel8,
395 (object::Architecture::Aarch64, object::RelocationKind::PltRelative, 26) => {
396 RelocationKind::Arm64Call
397 }
398 (
399 object::Architecture::Aarch64,
400 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G0_NC),
401 0,
402 ) => RelocationKind::Arm64Movw0,
403 (
404 object::Architecture::Aarch64,
405 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G1_NC),
406 0,
407 ) => RelocationKind::Arm64Movw1,
408 (
409 object::Architecture::Aarch64,
410 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G2_NC),
411 0,
412 ) => RelocationKind::Arm64Movw2,
413 (
414 object::Architecture::Aarch64,
415 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G3),
416 0,
417 ) => RelocationKind::Arm64Movw3,
418 (
419 object::Architecture::Riscv64,
420 object::RelocationKind::Elf(object::elf::R_RISCV_CALL_PLT),
421 0,
422 ) => RelocationKind::RiscvCall,
423 (
424 object::Architecture::Riscv64,
425 object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_HI20),
426 0,
427 ) => RelocationKind::RiscvPCRelHi20,
428 (
429 object::Architecture::Riscv64,
430 object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_LO12_I),
431 0,
432 ) => RelocationKind::RiscvPCRelLo12I,
433 (
434 object::Architecture::LoongArch64,
435 object::RelocationKind::Elf(object::elf::R_LARCH_ABS_HI20),
436 0,
437 ) => RelocationKind::LArchAbsHi20,
438 (
439 object::Architecture::LoongArch64,
440 object::RelocationKind::Elf(object::elf::R_LARCH_ABS_LO12),
441 0,
442 ) => RelocationKind::LArchAbsLo12,
443 (
444 object::Architecture::LoongArch64,
445 object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_HI12),
446 0,
447 ) => RelocationKind::LArchAbs64Hi12,
448 (
449 object::Architecture::LoongArch64,
450 object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20),
451 0,
452 ) => RelocationKind::LArchAbs64Lo20,
453 (
454 object::Architecture::LoongArch64,
455 object::RelocationKind::Elf(110),
459 0,
460 ) => RelocationKind::LArchCall36,
461 (
462 object::Architecture::LoongArch64,
463 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA_HI20),
464 0,
465 ) => RelocationKind::LArchPCAlaHi20,
466 (
467 object::Architecture::LoongArch64,
468 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA_LO12),
469 0,
470 ) => RelocationKind::LArchPCAlaLo12,
471 (
472 object::Architecture::LoongArch64,
473 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA64_HI12),
474 0,
475 ) => RelocationKind::LArchPCAla64Hi12,
476 (
477 object::Architecture::LoongArch64,
478 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA64_LO20),
479 0,
480 ) => RelocationKind::LArchPCAla64Lo20,
481 (
482 object::Architecture::Aarch64,
483 object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_LO21),
484 0,
485 ) => RelocationKind::Aarch64AdrPrelLo21,
486 (
487 object::Architecture::Aarch64,
488 object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_PG_HI21),
489 0,
490 ) => RelocationKind::Aarch64AdrPrelPgHi21,
491 (
492 object::Architecture::Aarch64,
493 object::RelocationKind::Elf(object::elf::R_AARCH64_LDST128_ABS_LO12_NC),
494 0,
495 ) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
496 (
497 object::Architecture::Aarch64,
498 object::RelocationKind::Elf(object::elf::R_AARCH64_ADD_ABS_LO12_NC),
499 0,
500 ) => RelocationKind::Aarch64AddAbsLo12Nc,
501 (
502 object::Architecture::Aarch64,
503 object::RelocationKind::Elf(object::elf::R_AARCH64_LDST64_ABS_LO12_NC),
504 0,
505 ) => RelocationKind::Aarch64Ldst64AbsLo12Nc,
506 (object::Architecture::Aarch64, object::RelocationKind::MachO { value, .. }, _) => {
507 match value {
508 object::macho::ARM64_RELOC_UNSIGNED => {
509 RelocationKind::MachoArm64RelocUnsigned
510 }
511 object::macho::ARM64_RELOC_SUBTRACTOR => {
512 RelocationKind::MachoArm64RelocSubtractor
513 }
514 object::macho::ARM64_RELOC_BRANCH26 => {
515 RelocationKind::MachoArm64RelocBranch26
516 }
517 object::macho::ARM64_RELOC_PAGE21 => RelocationKind::MachoArm64RelocPage21,
518 object::macho::ARM64_RELOC_PAGEOFF12 => {
519 RelocationKind::MachoArm64RelocPageoff12
520 }
521 object::macho::ARM64_RELOC_GOT_LOAD_PAGE21 => {
522 RelocationKind::MachoArm64RelocGotLoadPage21
523 }
524 object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12 => {
525 RelocationKind::MachoArm64RelocGotLoadPageoff12
526 }
527 object::macho::ARM64_RELOC_POINTER_TO_GOT => {
528 RelocationKind::MachoArm64RelocPointerToGot
529 }
530 object::macho::ARM64_RELOC_TLVP_LOAD_PAGE21 => {
531 RelocationKind::MachoArm64RelocTlvpLoadPage21
532 }
533 object::macho::ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
534 RelocationKind::MachoArm64RelocTlvpLoadPageoff12
535 }
536 object::macho::ARM64_RELOC_ADDEND => RelocationKind::MachoArm64RelocAddend,
537 _ => {
538 return Err(CompileError::Codegen(format!(
539 "unknown relocation {reloc:?}",
540 )));
541 }
542 }
543 }
544 (object::Architecture::X86_64, object::RelocationKind::MachO { value, .. }, _) => {
545 match value {
546 object::macho::X86_64_RELOC_UNSIGNED => {
547 RelocationKind::MachoX86_64RelocUnsigned
548 }
549 object::macho::X86_64_RELOC_SIGNED => {
550 RelocationKind::MachoX86_64RelocSigned
551 }
552 object::macho::X86_64_RELOC_BRANCH => {
553 RelocationKind::MachoX86_64RelocBranch
554 }
555 object::macho::X86_64_RELOC_GOT_LOAD => {
556 RelocationKind::MachoX86_64RelocGotLoad
557 }
558 object::macho::X86_64_RELOC_GOT => RelocationKind::MachoX86_64RelocGot,
559 object::macho::X86_64_RELOC_SUBTRACTOR => {
560 RelocationKind::MachoX86_64RelocSubtractor
561 }
562 object::macho::X86_64_RELOC_SIGNED_1 => {
563 RelocationKind::MachoX86_64RelocSigned1
564 }
565 object::macho::X86_64_RELOC_SIGNED_2 => {
566 RelocationKind::MachoX86_64RelocSigned2
567 }
568 object::macho::X86_64_RELOC_SIGNED_4 => {
569 RelocationKind::MachoX86_64RelocSigned4
570 }
571 object::macho::X86_64_RELOC_TLV => RelocationKind::MachoX86_64RelocTlv,
572 _ => {
573 return Err(CompileError::Codegen(format!(
574 "unknown relocation {reloc:?}"
575 )));
576 }
577 }
578 }
579 _ => {
580 return Err(CompileError::Codegen(format!(
581 "unknown relocation {reloc:?}",
582 )));
583 }
584 };
585
586 relocations
587 .entry(section_index)
588 .or_default()
589 .push(Relocation {
590 kind,
591 reloc_target: target,
592 offset: offset.try_into().map_err(map_tryfromint_err)?,
593 addend,
594 });
595 }
596 }
597
598 let eh_frame_section_indices = eh_frame_section_indices
599 .iter()
600 .map(|index| {
601 section_to_custom_section.get(index).map_or_else(
602 || {
603 Err(CompileError::Codegen(format!(
604 ".eh_frame section with index={index:?} was never loaded",
605 )))
606 },
607 |idx| Ok(*idx),
608 )
609 })
610 .collect::<Result<Vec<SectionIndex>, _>>()?;
611
612 let compact_unwind_section_indices = compact_unwind_section_indices
613 .iter()
614 .map(|index| {
615 section_to_custom_section.get(index).map_or_else(
616 || {
617 Err(CompileError::Codegen(format!(
618 "_compact_unwind section with index={index:?} was never loaded",
619 )))
620 },
621 |idx| Ok(*idx),
622 )
623 })
624 .collect::<Result<Vec<SectionIndex>, _>>()?;
625
626 let gcc_except_table_section_indices = gcc_except_table_section_indices
627 .iter()
628 .map(|index| {
629 section_to_custom_section.get(index).map_or_else(
630 || {
631 Err(CompileError::Codegen(format!(
632 ".gcc_except_table section with index={index:?} was never loaded",
633 )))
634 },
635 |idx| Ok(*idx),
636 )
637 })
638 .collect::<Result<Vec<SectionIndex>, _>>()?;
639
640 let mut custom_sections = section_to_custom_section
641 .iter()
642 .map(|(elf_section_index, custom_section_index)| {
643 let section = obj.section_by_index(*elf_section_index).unwrap();
644 (
645 custom_section_index,
646 CustomSection {
647 protection: CustomSectionProtection::Read,
648 alignment: Some(section.align()),
649 bytes: SectionBody::new_with_vec(section.data().unwrap().to_vec()),
650 relocations: relocations
651 .remove_entry(elf_section_index)
652 .map_or(vec![], |(_, v)| v),
653 },
654 )
655 })
656 .collect::<Vec<_>>();
657 custom_sections.sort_unstable_by_key(|a| a.0);
658 let custom_sections = custom_sections
659 .into_iter()
660 .map(|(_, v)| v)
661 .collect::<PrimaryMap<SectionIndex, _>>();
662
663 let function_body = FunctionBody {
664 body: obj
665 .section_by_index(root_section_index)
666 .unwrap()
667 .data()
668 .unwrap()
669 .to_vec(),
670 unwind_info: None,
671 };
672
673 let address_map = FunctionAddressMap {
674 instructions: vec![InstructionAddressMap {
675 srcloc: SourceLoc::default(),
676 code_offset: 0,
677 code_len: function_body.body.len(),
678 }],
679 start_srcloc: SourceLoc::default(),
680 end_srcloc: SourceLoc::default(),
681 body_offset: 0,
682 body_len: function_body.body.len(),
683 };
684
685 Ok(CompiledFunction {
686 compiled_function: wasmer_compiler::types::function::CompiledFunction {
687 body: function_body,
688 relocations: relocations
689 .remove_entry(&root_section_index)
690 .map_or(vec![], |(_, v)| v),
691 frame_info: CompiledFunctionFrameInfo {
692 address_map,
693 traps: vec![],
694 },
695 },
696 custom_sections,
697 eh_frame_section_indices,
698 compact_unwind_section_indices,
699 gcc_except_table_section_indices,
700 })
701}