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}
34
35static LIBCALLS_ELF: phf::Map<&'static str, LibCall> = phf::phf_map! {
36 "ceilf" => LibCall::CeilF32,
37 "ceil" => LibCall::CeilF64,
38 "floorf" => LibCall::FloorF32,
39 "floor" => LibCall::FloorF64,
40 "nearbyintf" => LibCall::NearestF32,
41 "nearbyint" => LibCall::NearestF64,
42 "truncf" => LibCall::TruncF32,
43 "trunc" => LibCall::TruncF64,
44 "wasmer_vm_f32_ceil" => LibCall::CeilF32,
45 "wasmer_vm_f64_ceil" => LibCall::CeilF64,
46 "wasmer_vm_f32_floor" => LibCall::FloorF32,
47 "wasmer_vm_f64_floor" => LibCall::FloorF64,
48 "wasmer_vm_f32_nearest" => LibCall::NearestF32,
49 "wasmer_vm_f64_nearest" => LibCall::NearestF64,
50 "wasmer_vm_f32_trunc" => LibCall::TruncF32,
51 "wasmer_vm_f64_trunc" => LibCall::TruncF64,
52 "wasmer_vm_memory32_size" => LibCall::Memory32Size,
53 "wasmer_vm_imported_memory32_size" => LibCall::ImportedMemory32Size,
54 "wasmer_vm_table_copy" => LibCall::TableCopy,
55 "wasmer_vm_table_init" => LibCall::TableInit,
56 "wasmer_vm_table_fill" => LibCall::TableFill,
57 "wasmer_vm_table_size" => LibCall::TableSize,
58 "wasmer_vm_imported_table_size" => LibCall::ImportedTableSize,
59 "wasmer_vm_table_get" => LibCall::TableGet,
60 "wasmer_vm_imported_table_get" => LibCall::ImportedTableGet,
61 "wasmer_vm_table_set" => LibCall::TableSet,
62 "wasmer_vm_imported_table_set" => LibCall::ImportedTableSet,
63 "wasmer_vm_table_grow" => LibCall::TableGrow,
64 "wasmer_vm_imported_table_grow" => LibCall::ImportedTableGrow,
65 "wasmer_vm_func_ref" => LibCall::FuncRef,
66 "wasmer_vm_elem_drop" => LibCall::ElemDrop,
67 "wasmer_vm_memory32_copy" => LibCall::Memory32Copy,
68 "wasmer_vm_imported_memory32_copy" => LibCall::ImportedMemory32Copy,
69 "wasmer_vm_memory32_fill" => LibCall::Memory32Fill,
70 "wasmer_vm_imported_memory32_fill" => LibCall::ImportedMemory32Fill,
71 "wasmer_vm_memory32_init" => LibCall::Memory32Init,
72 "wasmer_vm_data_drop" => LibCall::DataDrop,
73 "wasmer_vm_raise_trap" => LibCall::RaiseTrap,
74 "wasmer_vm_memory32_atomic_wait32" => LibCall::Memory32AtomicWait32,
75 "wasmer_vm_imported_memory32_atomic_wait32" => LibCall::ImportedMemory32AtomicWait32,
76 "wasmer_vm_memory32_atomic_wait64" => LibCall::Memory32AtomicWait64,
77 "wasmer_vm_imported_memory32_atomic_wait64" => LibCall::ImportedMemory32AtomicWait64,
78 "wasmer_vm_memory32_atomic_notify" => LibCall::Memory32AtomicNotify,
79 "wasmer_vm_imported_memory32_atomic_notify" => LibCall::ImportedMemory32AtomicNotify,
80 "wasmer_vm_throw" => LibCall::Throw,
81 "wasmer_vm_rethrow" => LibCall::Rethrow,
82 "wasmer_vm_alloc_exception" => LibCall::AllocException,
83 "wasmer_vm_delete_exception" => LibCall::DeleteException,
84 "wasmer_vm_read_exception" => LibCall::ReadException,
85 "wasmer_vm_dbg_usize" => LibCall::DebugUsize,
86 "wasmer_eh_personality" => LibCall::EHPersonality,
87 "wasmer_eh_personality2" => LibCall::EHPersonality2,
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 "_wasmer_vm_throw" => LibCall::Throw,
137 "_wasmer_vm_rethrow" => LibCall::Rethrow,
138 "_wasmer_vm_alloc_exception" => LibCall::AllocException,
139 "_wasmer_vm_delete_exception" => LibCall::DeleteException,
140 "_wasmer_vm_read_exception" => LibCall::ReadException,
141 "_wasmer_vm_dbg_usize" => LibCall::DebugUsize,
142 "___gxx_personality_v0" => LibCall::EHPersonality,
147 "_wasmer_eh_personality2" => LibCall::EHPersonality2,
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 for section in obj.sections() {
225 let index = section.index();
226 if section.kind() == object::SectionKind::Elf(object::elf::SHT_X86_64_UNWIND)
227 || section.name().unwrap_or_default() == "__eh_frame"
228 {
229 worklist.push(index);
230 eh_frame_section_indices.push(index);
231
232 elf_section_to_target(index);
234 } else if section.name().unwrap_or_default() == "__compact_unwind" {
235 worklist.push(index);
236 compact_unwind_section_indices.push(index);
237
238 elf_section_to_target(index);
239 }
240 }
241
242 while let Some(section_index) = worklist.pop() {
243 let sec = obj
244 .section_by_index(section_index)
245 .map_err(map_object_err)?;
246 let relocs = sec.relocations();
247 for (offset, reloc) in relocs {
248 let mut addend = reloc.addend();
249 let target = match reloc.target() {
250 object::read::RelocationTarget::Symbol(index) => {
251 let symbol = obj.symbol_by_index(index).map_err(map_object_err)?;
252 let symbol_name = symbol.name().map_err(map_object_err)?;
253 if symbol.kind() == object::SymbolKind::Section {
254 match symbol.section() {
255 object::SymbolSection::Section(section_index) => {
256 if section_index == root_section_index {
257 root_section_reloc_target
258 } else {
259 if visited.insert(section_index) {
260 worklist.push(section_index);
261 }
262 elf_section_to_target(section_index)
263 }
264 }
265 _ => {
266 return Err(CompileError::Codegen(format!(
267 "relocation targets unknown section {reloc:?}",
268 )));
269 }
270 }
271 } else if let Some(libcall) = libcalls.get(symbol_name) {
273 RelocationTarget::LibCall(*libcall)
274 } else if let Ok(Some(reloc_target)) =
275 symbol_name_to_relocation_target(symbol_name)
276 {
277 reloc_target
278 } else if let object::SymbolSection::Section(section_index) = symbol.section() {
279 if matches!(
280 reloc.kind(),
281 object::RelocationKind::MachO {
282 value: object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12,
283 relative: false
284 } | object::RelocationKind::MachO {
285 value: object::macho::ARM64_RELOC_POINTER_TO_GOT,
286 relative: true
287 } | object::RelocationKind::MachO {
288 value: object::macho::ARM64_RELOC_GOT_LOAD_PAGE21,
289 relative: true
290 } | object::RelocationKind::MachO {
291 value: object::macho::ARM64_RELOC_PAGE21,
292 relative: true
293 } | object::RelocationKind::MachO {
294 value: object::macho::ARM64_RELOC_PAGEOFF12,
295 relative: false
296 }
297 ) {
298 let symbol_sec = obj
318 .section_by_index(section_index)
319 .map_err(map_object_err)?;
320
321 addend = addend
322 .wrapping_add((symbol.address() - symbol_sec.address()) as i64);
323 } else {
324 addend = addend.wrapping_add(symbol.address() as i64);
326 }
327
328 if section_index == root_section_index {
329 root_section_reloc_target
330 } else {
331 if visited.insert(section_index) {
332 worklist.push(section_index);
333 }
334
335 elf_section_to_target(section_index)
336 }
337 } else {
338 return Err(CompileError::Codegen(format!(
339 "relocation {reloc:?} targets unknown symbol '{symbol:?}'",
340 )));
341 }
342 }
343
344 object::read::RelocationTarget::Section(index) => {
345 if index == root_section_index {
346 root_section_reloc_target
347 } else {
348 if visited.insert(index) {
349 worklist.push(index);
350 }
351 elf_section_to_target(index)
352 }
353 }
354
355 object::read::RelocationTarget::Absolute => {
356 return Err(CompileError::Codegen(format!(
360 "relocation targets absolute address {reloc:?}",
361 )));
362 }
363
364 t => {
371 return Err(CompileError::Codegen(format!(
372 "relocation target is unknown `{t:?}`",
373 )));
374 }
375 };
376 let kind = match (obj.architecture(), reloc.kind(), reloc.size()) {
377 (_, object::RelocationKind::Absolute, 64) => RelocationKind::Abs8,
378 (_, object::RelocationKind::Absolute, 32) => RelocationKind::Abs4,
379 (
380 object::Architecture::X86_64,
381 object::RelocationKind::Elf(object::elf::R_X86_64_PC64),
382 0,
383 ) => RelocationKind::X86PCRel8,
384 (object::Architecture::Aarch64, object::RelocationKind::PltRelative, 26) => {
385 RelocationKind::Arm64Call
386 }
387 (
388 object::Architecture::Aarch64,
389 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G0_NC),
390 0,
391 ) => RelocationKind::Arm64Movw0,
392 (
393 object::Architecture::Aarch64,
394 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G1_NC),
395 0,
396 ) => RelocationKind::Arm64Movw1,
397 (
398 object::Architecture::Aarch64,
399 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G2_NC),
400 0,
401 ) => RelocationKind::Arm64Movw2,
402 (
403 object::Architecture::Aarch64,
404 object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G3),
405 0,
406 ) => RelocationKind::Arm64Movw3,
407 (
408 object::Architecture::Riscv64,
409 object::RelocationKind::Elf(object::elf::R_RISCV_CALL_PLT),
410 0,
411 ) => RelocationKind::RiscvCall,
412 (
413 object::Architecture::Riscv64,
414 object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_HI20),
415 0,
416 ) => RelocationKind::RiscvPCRelHi20,
417 (
418 object::Architecture::Riscv64,
419 object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_LO12_I),
420 0,
421 ) => RelocationKind::RiscvPCRelLo12I,
422 (
423 object::Architecture::LoongArch64,
424 object::RelocationKind::Elf(object::elf::R_LARCH_ABS_HI20),
425 0,
426 ) => RelocationKind::LArchAbsHi20,
427 (
428 object::Architecture::LoongArch64,
429 object::RelocationKind::Elf(object::elf::R_LARCH_ABS_LO12),
430 0,
431 ) => RelocationKind::LArchAbsLo12,
432 (
433 object::Architecture::LoongArch64,
434 object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_HI12),
435 0,
436 ) => RelocationKind::LArchAbs64Hi12,
437 (
438 object::Architecture::LoongArch64,
439 object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20),
440 0,
441 ) => RelocationKind::LArchAbs64Lo20,
442 (
443 object::Architecture::LoongArch64,
444 object::RelocationKind::Elf(110),
448 0,
449 ) => RelocationKind::LArchCall36,
450 (
451 object::Architecture::LoongArch64,
452 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA_HI20),
453 0,
454 ) => RelocationKind::LArchPCAlaHi20,
455 (
456 object::Architecture::LoongArch64,
457 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA_LO12),
458 0,
459 ) => RelocationKind::LArchPCAlaLo12,
460 (
461 object::Architecture::LoongArch64,
462 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA64_HI12),
463 0,
464 ) => RelocationKind::LArchPCAla64Hi12,
465 (
466 object::Architecture::LoongArch64,
467 object::RelocationKind::Elf(object::elf::R_LARCH_PCALA64_LO20),
468 0,
469 ) => RelocationKind::LArchPCAla64Lo20,
470 (
471 object::Architecture::Aarch64,
472 object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_LO21),
473 0,
474 ) => RelocationKind::Aarch64AdrPrelLo21,
475 (
476 object::Architecture::Aarch64,
477 object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_PG_HI21),
478 0,
479 ) => RelocationKind::Aarch64AdrPrelPgHi21,
480 (
481 object::Architecture::Aarch64,
482 object::RelocationKind::Elf(object::elf::R_AARCH64_LDST128_ABS_LO12_NC),
483 0,
484 ) => RelocationKind::Aarch64Ldst128AbsLo12Nc,
485 (
486 object::Architecture::Aarch64,
487 object::RelocationKind::Elf(object::elf::R_AARCH64_ADD_ABS_LO12_NC),
488 0,
489 ) => RelocationKind::Aarch64AddAbsLo12Nc,
490 (
491 object::Architecture::Aarch64,
492 object::RelocationKind::Elf(object::elf::R_AARCH64_LDST64_ABS_LO12_NC),
493 0,
494 ) => RelocationKind::Aarch64Ldst64AbsLo12Nc,
495 (object::Architecture::Aarch64, object::RelocationKind::MachO { value, .. }, _) => {
496 match value {
497 object::macho::ARM64_RELOC_UNSIGNED => {
498 RelocationKind::MachoArm64RelocUnsigned
499 }
500 object::macho::ARM64_RELOC_SUBTRACTOR => {
501 RelocationKind::MachoArm64RelocSubtractor
502 }
503 object::macho::ARM64_RELOC_BRANCH26 => {
504 RelocationKind::MachoArm64RelocBranch26
505 }
506 object::macho::ARM64_RELOC_PAGE21 => RelocationKind::MachoArm64RelocPage21,
507 object::macho::ARM64_RELOC_PAGEOFF12 => {
508 RelocationKind::MachoArm64RelocPageoff12
509 }
510 object::macho::ARM64_RELOC_GOT_LOAD_PAGE21 => {
511 RelocationKind::MachoArm64RelocGotLoadPage21
512 }
513 object::macho::ARM64_RELOC_GOT_LOAD_PAGEOFF12 => {
514 RelocationKind::MachoArm64RelocGotLoadPageoff12
515 }
516 object::macho::ARM64_RELOC_POINTER_TO_GOT => {
517 RelocationKind::MachoArm64RelocPointerToGot
518 }
519 object::macho::ARM64_RELOC_TLVP_LOAD_PAGE21 => {
520 RelocationKind::MachoArm64RelocTlvpLoadPage21
521 }
522 object::macho::ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => {
523 RelocationKind::MachoArm64RelocTlvpLoadPageoff12
524 }
525 object::macho::ARM64_RELOC_ADDEND => RelocationKind::MachoArm64RelocAddend,
526 _ => {
527 return Err(CompileError::Codegen(format!(
528 "unknown relocation {reloc:?}",
529 )));
530 }
531 }
532 }
533 (object::Architecture::X86_64, object::RelocationKind::MachO { value, .. }, _) => {
534 match value {
535 object::macho::X86_64_RELOC_UNSIGNED => {
536 RelocationKind::MachoX86_64RelocUnsigned
537 }
538 object::macho::X86_64_RELOC_SIGNED => {
539 RelocationKind::MachoX86_64RelocSigned
540 }
541 object::macho::X86_64_RELOC_BRANCH => {
542 RelocationKind::MachoX86_64RelocBranch
543 }
544 object::macho::X86_64_RELOC_GOT_LOAD => {
545 RelocationKind::MachoX86_64RelocGotLoad
546 }
547 object::macho::X86_64_RELOC_GOT => RelocationKind::MachoX86_64RelocGot,
548 object::macho::X86_64_RELOC_SUBTRACTOR => {
549 RelocationKind::MachoX86_64RelocSubtractor
550 }
551 object::macho::X86_64_RELOC_SIGNED_1 => {
552 RelocationKind::MachoX86_64RelocSigned1
553 }
554 object::macho::X86_64_RELOC_SIGNED_2 => {
555 RelocationKind::MachoX86_64RelocSigned2
556 }
557 object::macho::X86_64_RELOC_SIGNED_4 => {
558 RelocationKind::MachoX86_64RelocSigned4
559 }
560 object::macho::X86_64_RELOC_TLV => RelocationKind::MachoX86_64RelocTlv,
561 _ => {
562 return Err(CompileError::Codegen(format!(
563 "unknown relocation {reloc:?}"
564 )));
565 }
566 }
567 }
568 _ => {
569 return Err(CompileError::Codegen(format!(
570 "unknown relocation {reloc:?}",
571 )));
572 }
573 };
574
575 relocations
576 .entry(section_index)
577 .or_default()
578 .push(Relocation {
579 kind,
580 reloc_target: target,
581 offset: offset.try_into().map_err(map_tryfromint_err)?,
582 addend,
583 });
584 }
585 }
586
587 let eh_frame_section_indices = eh_frame_section_indices
588 .iter()
589 .map(|index| {
590 section_to_custom_section.get(index).map_or_else(
591 || {
592 Err(CompileError::Codegen(format!(
593 ".eh_frame section with index={index:?} was never loaded",
594 )))
595 },
596 |idx| Ok(*idx),
597 )
598 })
599 .collect::<Result<Vec<SectionIndex>, _>>()?;
600
601 let compact_unwind_section_indices = compact_unwind_section_indices
602 .iter()
603 .map(|index| {
604 section_to_custom_section.get(index).map_or_else(
605 || {
606 Err(CompileError::Codegen(format!(
607 "_compact_unwind section with index={index:?} was never loaded",
608 )))
609 },
610 |idx| Ok(*idx),
611 )
612 })
613 .collect::<Result<Vec<SectionIndex>, _>>()?;
614
615 let mut custom_sections = section_to_custom_section
616 .iter()
617 .map(|(elf_section_index, custom_section_index)| {
618 let section = obj.section_by_index(*elf_section_index).unwrap();
619 (
620 custom_section_index,
621 CustomSection {
622 protection: CustomSectionProtection::Read,
623 alignment: Some(section.align()),
624 bytes: SectionBody::new_with_vec(section.data().unwrap().to_vec()),
625 relocations: relocations
626 .remove_entry(elf_section_index)
627 .map_or(vec![], |(_, v)| v),
628 },
629 )
630 })
631 .collect::<Vec<_>>();
632 custom_sections.sort_unstable_by_key(|a| a.0);
633 let custom_sections = custom_sections
634 .into_iter()
635 .map(|(_, v)| v)
636 .collect::<PrimaryMap<SectionIndex, _>>();
637
638 let function_body = FunctionBody {
639 body: obj
640 .section_by_index(root_section_index)
641 .unwrap()
642 .data()
643 .unwrap()
644 .to_vec(),
645 unwind_info: None,
646 };
647
648 let address_map = FunctionAddressMap {
649 instructions: vec![InstructionAddressMap {
650 srcloc: SourceLoc::default(),
651 code_offset: 0,
652 code_len: function_body.body.len(),
653 }],
654 start_srcloc: SourceLoc::default(),
655 end_srcloc: SourceLoc::default(),
656 body_offset: 0,
657 body_len: function_body.body.len(),
658 };
659
660 Ok(CompiledFunction {
661 compiled_function: wasmer_compiler::types::function::CompiledFunction {
662 body: function_body,
663 relocations: relocations
664 .remove_entry(&root_section_index)
665 .map_or(vec![], |(_, v)| v),
666 frame_info: CompiledFunctionFrameInfo {
667 address_map,
668 traps: vec![],
669 },
670 },
671 custom_sections,
672 eh_frame_section_indices,
673 compact_unwind_section_indices,
674 })
675}