]> git.proxmox.com Git - rustc.git/blob - vendor/object/src/read/wasm.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / vendor / object / src / read / wasm.rs
1 //! Support for reading Wasm files.
2 //!
3 //! Provides `WasmFile` and related types which implement the `Object` trait.
4 //!
5 //! Currently implements the minimum required to access DWARF debugging information.
6 use alloc::boxed::Box;
7 use alloc::vec::Vec;
8 use core::marker::PhantomData;
9 use core::{slice, str};
10 use wasmparser as wp;
11
12 use crate::read::{
13 self, Architecture, ComdatKind, CompressedData, Error, FileFlags, Object, ObjectComdat,
14 ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, Relocation, Result,
15 SectionFlags, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolScope,
16 SymbolSection,
17 };
18
19 const SECTION_CUSTOM: usize = 0;
20 const SECTION_TYPE: usize = 1;
21 const SECTION_IMPORT: usize = 2;
22 const SECTION_FUNCTION: usize = 3;
23 const SECTION_TABLE: usize = 4;
24 const SECTION_MEMORY: usize = 5;
25 const SECTION_GLOBAL: usize = 6;
26 const SECTION_EXPORT: usize = 7;
27 const SECTION_START: usize = 8;
28 const SECTION_ELEMENT: usize = 9;
29 const SECTION_CODE: usize = 10;
30 const SECTION_DATA: usize = 11;
31 const SECTION_DATA_COUNT: usize = 12;
32 // Update this constant when adding new section id:
33 const MAX_SECTION_ID: usize = SECTION_DATA_COUNT;
34
35 /// A WebAssembly object file.
36 #[derive(Debug, Default)]
37 pub struct WasmFile<'data> {
38 // All sections, including custom sections.
39 sections: Vec<wp::Section<'data>>,
40 // Indices into `sections` of sections with a non-zero id.
41 id_sections: Box<[Option<usize>; MAX_SECTION_ID + 1]>,
42 // Whether the file has DWARF information.
43 has_debug_symbols: bool,
44 // Symbols collected from imports, exports, code and name sections.
45 symbols: Vec<WasmSymbolInternal<'data>>,
46 // Address of the function body for the entry point.
47 entry: u64,
48 }
49
50 #[derive(Clone)]
51 enum LocalFunctionKind {
52 Unknown,
53 Exported { symbol_ids: Vec<u32> },
54 Local { symbol_id: u32 },
55 }
56
57 impl<T> ReadError<T> for wasmparser::Result<T> {
58 fn read_error(self, error: &'static str) -> Result<T> {
59 self.map_err(|_| Error(error))
60 }
61 }
62
63 impl<'data> WasmFile<'data> {
64 /// Parse the raw wasm data.
65 pub fn parse(data: &'data [u8]) -> Result<Self> {
66 let module = wp::ModuleReader::new(data).read_error("Invalid Wasm header")?;
67
68 let mut file = WasmFile::default();
69
70 let mut main_file_symbol = Some(WasmSymbolInternal {
71 name: "",
72 address: 0,
73 size: 0,
74 kind: SymbolKind::File,
75 section: SymbolSection::None,
76 scope: SymbolScope::Compilation,
77 });
78
79 let mut imported_funcs_count = 0;
80 let mut local_func_kinds = Vec::new();
81 let mut entry_func_id = None;
82
83 for section in module {
84 let section = section.read_error("Invalid Wasm section header")?;
85
86 match section.code {
87 wp::SectionCode::Import => {
88 let mut last_module_name = None;
89
90 for import in section
91 .get_import_section_reader()
92 .read_error("Couldn't read header of the import section")?
93 {
94 let import = import.read_error("Couldn't read an import item")?;
95 let module_name = import.module;
96
97 if last_module_name != Some(module_name) {
98 file.symbols.push(WasmSymbolInternal {
99 name: module_name,
100 address: 0,
101 size: 0,
102 kind: SymbolKind::File,
103 section: SymbolSection::None,
104 scope: SymbolScope::Dynamic,
105 });
106 last_module_name = Some(module_name);
107 }
108
109 let kind = match import.ty {
110 wp::ImportSectionEntryType::Function(_) => {
111 imported_funcs_count += 1;
112 SymbolKind::Text
113 }
114 wp::ImportSectionEntryType::Table(_)
115 | wp::ImportSectionEntryType::Memory(_)
116 | wp::ImportSectionEntryType::Global(_) => SymbolKind::Data,
117 };
118
119 file.symbols.push(WasmSymbolInternal {
120 name: import.field,
121 address: 0,
122 size: 0,
123 kind,
124 section: SymbolSection::Undefined,
125 scope: SymbolScope::Dynamic,
126 });
127 }
128 }
129 wp::SectionCode::Function => {
130 local_func_kinds = vec![
131 LocalFunctionKind::Unknown;
132 section
133 .get_function_section_reader()
134 .read_error("Couldn't read header of the function section")?
135 .get_count() as usize
136 ];
137 }
138 wp::SectionCode::Export => {
139 if let Some(main_file_symbol) = main_file_symbol.take() {
140 file.symbols.push(main_file_symbol);
141 }
142
143 for export in section
144 .get_export_section_reader()
145 .read_error("Couldn't read header of the export section")?
146 {
147 let export = export.read_error("Couldn't read an export item")?;
148
149 let (kind, section_idx) = match export.kind {
150 wp::ExternalKind::Function => {
151 if let Some(local_func_id) =
152 export.index.checked_sub(imported_funcs_count)
153 {
154 let local_func_kind =
155 &mut local_func_kinds[local_func_id as usize];
156 if let LocalFunctionKind::Unknown = local_func_kind {
157 *local_func_kind = LocalFunctionKind::Exported {
158 symbol_ids: Vec::new(),
159 };
160 }
161 let symbol_ids = match local_func_kind {
162 LocalFunctionKind::Exported { symbol_ids } => symbol_ids,
163 _ => unreachable!(),
164 };
165 symbol_ids.push(file.symbols.len() as u32);
166 }
167 (SymbolKind::Text, SECTION_CODE)
168 }
169 wp::ExternalKind::Table
170 | wp::ExternalKind::Memory
171 | wp::ExternalKind::Global => (SymbolKind::Data, SECTION_DATA),
172 };
173
174 file.symbols.push(WasmSymbolInternal {
175 name: export.field,
176 address: 0,
177 size: 0,
178 kind,
179 section: SymbolSection::Section(SectionIndex(section_idx)),
180 scope: SymbolScope::Dynamic,
181 });
182 }
183 }
184 wp::SectionCode::Start => {
185 entry_func_id = Some(
186 section
187 .get_start_section_content()
188 .read_error("Couldn't read contents of the start section")?,
189 );
190 }
191 wp::SectionCode::Code => {
192 if let Some(main_file_symbol) = main_file_symbol.take() {
193 file.symbols.push(main_file_symbol);
194 }
195
196 for (i, (body, local_func_kind)) in section
197 .get_code_section_reader()
198 .read_error("Couldn't read header of the code section")?
199 .into_iter()
200 .zip(&mut local_func_kinds)
201 .enumerate()
202 {
203 let body = body.read_error("Couldn't read a function body")?;
204 let range = body.range();
205
206 let address = range.start as u64 - section.range().start as u64;
207 let size = (range.end - range.start) as u64;
208
209 if entry_func_id == Some(i as u32) {
210 file.entry = address;
211 }
212
213 match local_func_kind {
214 LocalFunctionKind::Unknown => {
215 *local_func_kind = LocalFunctionKind::Local {
216 symbol_id: file.symbols.len() as u32,
217 };
218 file.symbols.push(WasmSymbolInternal {
219 name: "",
220 address,
221 size,
222 kind: SymbolKind::Text,
223 section: SymbolSection::Section(SectionIndex(SECTION_CODE)),
224 scope: SymbolScope::Compilation,
225 });
226 }
227 LocalFunctionKind::Exported { symbol_ids } => {
228 for symbol_id in core::mem::replace(symbol_ids, Vec::new()) {
229 let export_symbol = &mut file.symbols[symbol_id as usize];
230 export_symbol.address = address;
231 export_symbol.size = size;
232 }
233 }
234 _ => unreachable!(),
235 }
236 }
237 }
238 wp::SectionCode::Custom {
239 kind: wp::CustomSectionKind::Name,
240 ..
241 } => {
242 for name in section
243 .get_name_section_reader()
244 .read_error("Couldn't read header of the name section")?
245 {
246 let name =
247 match name.read_error("Couldn't read header of a name subsection")? {
248 wp::Name::Function(name) => name,
249 _ => continue,
250 };
251 let mut name_map = name
252 .get_map()
253 .read_error("Couldn't read header of the function name subsection")?;
254 for _ in 0..name_map.get_count() {
255 let naming = name_map
256 .read()
257 .read_error("Couldn't read a function name")?;
258 if let Some(local_index) =
259 naming.index.checked_sub(imported_funcs_count)
260 {
261 if let LocalFunctionKind::Local { symbol_id } =
262 local_func_kinds[local_index as usize]
263 {
264 file.symbols[symbol_id as usize].name = naming.name;
265 }
266 }
267 }
268 }
269 }
270 wp::SectionCode::Custom { name, .. } if name.starts_with(".debug_") => {
271 file.has_debug_symbols = true;
272 }
273 _ => {}
274 }
275
276 let id = section_code_to_id(section.code);
277 file.id_sections[id] = Some(file.sections.len());
278
279 file.sections.push(section);
280 }
281
282 Ok(file)
283 }
284 }
285
286 impl<'data> read::private::Sealed for WasmFile<'data> {}
287
288 impl<'data, 'file> Object<'data, 'file> for WasmFile<'data>
289 where
290 'data: 'file,
291 {
292 type Segment = WasmSegment<'data, 'file>;
293 type SegmentIterator = WasmSegmentIterator<'data, 'file>;
294 type Section = WasmSection<'data, 'file>;
295 type SectionIterator = WasmSectionIterator<'data, 'file>;
296 type Comdat = WasmComdat<'data, 'file>;
297 type ComdatIterator = WasmComdatIterator<'data, 'file>;
298 type Symbol = WasmSymbol<'data, 'file>;
299 type SymbolIterator = WasmSymbolIterator<'data, 'file>;
300 type SymbolTable = WasmSymbolTable<'data, 'file>;
301
302 #[inline]
303 fn architecture(&self) -> Architecture {
304 Architecture::Wasm32
305 }
306
307 #[inline]
308 fn is_little_endian(&self) -> bool {
309 true
310 }
311
312 #[inline]
313 fn is_64(&self) -> bool {
314 false
315 }
316
317 fn segments(&'file self) -> Self::SegmentIterator {
318 WasmSegmentIterator { file: self }
319 }
320
321 #[inline]
322 fn entry(&'file self) -> u64 {
323 self.entry
324 }
325
326 fn section_by_name(&'file self, section_name: &str) -> Option<WasmSection<'data, 'file>> {
327 self.sections()
328 .find(|section| section.name() == Ok(section_name))
329 }
330
331 fn section_by_index(&'file self, index: SectionIndex) -> Result<WasmSection<'data, 'file>> {
332 // TODO: Missing sections should return an empty section.
333 let id_section = self
334 .id_sections
335 .get(index.0)
336 .and_then(|x| *x)
337 .read_error("Invalid Wasm section index")?;
338 let section = self.sections.get(id_section).unwrap();
339 Ok(WasmSection { section })
340 }
341
342 fn sections(&'file self) -> Self::SectionIterator {
343 WasmSectionIterator {
344 sections: self.sections.iter(),
345 }
346 }
347
348 fn comdats(&'file self) -> Self::ComdatIterator {
349 WasmComdatIterator { file: self }
350 }
351
352 #[inline]
353 fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<WasmSymbol<'data, 'file>> {
354 let symbol = self
355 .symbols
356 .get(index.0)
357 .read_error("Invalid Wasm symbol index")?;
358 Ok(WasmSymbol { index, symbol })
359 }
360
361 fn symbols(&'file self) -> Self::SymbolIterator {
362 WasmSymbolIterator {
363 symbols: self.symbols.iter().enumerate(),
364 }
365 }
366
367 fn symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> {
368 Some(WasmSymbolTable {
369 symbols: &self.symbols,
370 })
371 }
372
373 fn dynamic_symbols(&'file self) -> Self::SymbolIterator {
374 WasmSymbolIterator {
375 symbols: [].iter().enumerate(),
376 }
377 }
378
379 #[inline]
380 fn dynamic_symbol_table(&'file self) -> Option<WasmSymbolTable<'data, 'file>> {
381 None
382 }
383
384 fn has_debug_symbols(&self) -> bool {
385 self.has_debug_symbols
386 }
387
388 #[inline]
389 fn flags(&self) -> FileFlags {
390 FileFlags::None
391 }
392 }
393
394 /// An iterator over the segments of a `WasmFile`.
395 #[derive(Debug)]
396 pub struct WasmSegmentIterator<'data, 'file> {
397 file: &'file WasmFile<'data>,
398 }
399
400 impl<'data, 'file> Iterator for WasmSegmentIterator<'data, 'file> {
401 type Item = WasmSegment<'data, 'file>;
402
403 #[inline]
404 fn next(&mut self) -> Option<Self::Item> {
405 None
406 }
407 }
408
409 /// A segment of a `WasmFile`.
410 #[derive(Debug)]
411 pub struct WasmSegment<'data, 'file> {
412 file: &'file WasmFile<'data>,
413 }
414
415 impl<'data, 'file> read::private::Sealed for WasmSegment<'data, 'file> {}
416
417 impl<'data, 'file> ObjectSegment<'data> for WasmSegment<'data, 'file> {
418 #[inline]
419 fn address(&self) -> u64 {
420 unreachable!()
421 }
422
423 #[inline]
424 fn size(&self) -> u64 {
425 unreachable!()
426 }
427
428 #[inline]
429 fn align(&self) -> u64 {
430 unreachable!()
431 }
432
433 #[inline]
434 fn file_range(&self) -> (u64, u64) {
435 unreachable!()
436 }
437
438 fn data(&self) -> Result<&'data [u8]> {
439 unreachable!()
440 }
441
442 fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> {
443 unreachable!()
444 }
445
446 #[inline]
447 fn name(&self) -> Result<Option<&str>> {
448 unreachable!()
449 }
450 }
451
452 /// An iterator over the sections of a `WasmFile`.
453 #[derive(Debug)]
454 pub struct WasmSectionIterator<'data, 'file> {
455 sections: slice::Iter<'file, wp::Section<'data>>,
456 }
457
458 impl<'data, 'file> Iterator for WasmSectionIterator<'data, 'file> {
459 type Item = WasmSection<'data, 'file>;
460
461 fn next(&mut self) -> Option<Self::Item> {
462 let section = self.sections.next()?;
463 Some(WasmSection { section })
464 }
465 }
466
467 /// A section of a `WasmFile`.
468 #[derive(Debug)]
469 pub struct WasmSection<'data, 'file> {
470 section: &'file wp::Section<'data>,
471 }
472
473 impl<'data, 'file> read::private::Sealed for WasmSection<'data, 'file> {}
474
475 impl<'data, 'file> ObjectSection<'data> for WasmSection<'data, 'file> {
476 type RelocationIterator = WasmRelocationIterator<'data, 'file>;
477
478 #[inline]
479 fn index(&self) -> SectionIndex {
480 // Note that we treat all custom sections as index 0.
481 // This is ok because they are never looked up by index.
482 SectionIndex(section_code_to_id(self.section.code))
483 }
484
485 #[inline]
486 fn address(&self) -> u64 {
487 0
488 }
489
490 #[inline]
491 fn size(&self) -> u64 {
492 let range = self.section.range();
493 (range.end - range.start) as u64
494 }
495
496 #[inline]
497 fn align(&self) -> u64 {
498 1
499 }
500
501 #[inline]
502 fn file_range(&self) -> Option<(u64, u64)> {
503 let range = self.section.range();
504 Some((range.start as _, range.end as _))
505 }
506
507 #[inline]
508 fn data(&self) -> Result<&'data [u8]> {
509 let mut reader = self.section.get_binary_reader();
510 // TODO: raise a feature request upstream to be able
511 // to get remaining slice from a BinaryReader directly.
512 Ok(reader.read_bytes(reader.bytes_remaining()).unwrap())
513 }
514
515 fn data_range(&self, _address: u64, _size: u64) -> Result<Option<&'data [u8]>> {
516 unimplemented!()
517 }
518
519 #[inline]
520 fn compressed_data(&self) -> Result<CompressedData<'data>> {
521 self.data().map(CompressedData::none)
522 }
523
524 #[inline]
525 fn name(&self) -> Result<&str> {
526 Ok(match self.section.code {
527 wp::SectionCode::Custom { name, .. } => name,
528 wp::SectionCode::Type => "<type>",
529 wp::SectionCode::Import => "<import>",
530 wp::SectionCode::Function => "<function>",
531 wp::SectionCode::Table => "<table>",
532 wp::SectionCode::Memory => "<memory>",
533 wp::SectionCode::Global => "<global>",
534 wp::SectionCode::Export => "<export>",
535 wp::SectionCode::Start => "<start>",
536 wp::SectionCode::Element => "<element>",
537 wp::SectionCode::Code => "<code>",
538 wp::SectionCode::Data => "<data>",
539 wp::SectionCode::DataCount => "<data_count>",
540 })
541 }
542
543 #[inline]
544 fn segment_name(&self) -> Result<Option<&str>> {
545 Ok(None)
546 }
547
548 #[inline]
549 fn kind(&self) -> SectionKind {
550 match self.section.code {
551 wp::SectionCode::Custom { kind, .. } => match kind {
552 wp::CustomSectionKind::Reloc | wp::CustomSectionKind::Linking => {
553 SectionKind::Linker
554 }
555 _ => SectionKind::Other,
556 },
557 wp::SectionCode::Type => SectionKind::Metadata,
558 wp::SectionCode::Import => SectionKind::Linker,
559 wp::SectionCode::Function => SectionKind::Metadata,
560 wp::SectionCode::Table => SectionKind::UninitializedData,
561 wp::SectionCode::Memory => SectionKind::UninitializedData,
562 wp::SectionCode::Global => SectionKind::Data,
563 wp::SectionCode::Export => SectionKind::Linker,
564 wp::SectionCode::Start => SectionKind::Linker,
565 wp::SectionCode::Element => SectionKind::Data,
566 wp::SectionCode::Code => SectionKind::Text,
567 wp::SectionCode::Data => SectionKind::Data,
568 wp::SectionCode::DataCount => SectionKind::UninitializedData,
569 }
570 }
571
572 #[inline]
573 fn relocations(&self) -> WasmRelocationIterator<'data, 'file> {
574 WasmRelocationIterator::default()
575 }
576
577 #[inline]
578 fn flags(&self) -> SectionFlags {
579 SectionFlags::None
580 }
581 }
582
583 /// An iterator over the COMDAT section groups of a `WasmFile`.
584 #[derive(Debug)]
585 pub struct WasmComdatIterator<'data, 'file> {
586 file: &'file WasmFile<'data>,
587 }
588
589 impl<'data, 'file> Iterator for WasmComdatIterator<'data, 'file> {
590 type Item = WasmComdat<'data, 'file>;
591
592 #[inline]
593 fn next(&mut self) -> Option<Self::Item> {
594 None
595 }
596 }
597
598 /// A COMDAT section group of a `WasmFile`.
599 #[derive(Debug)]
600 pub struct WasmComdat<'data, 'file> {
601 file: &'file WasmFile<'data>,
602 }
603
604 impl<'data, 'file> read::private::Sealed for WasmComdat<'data, 'file> {}
605
606 impl<'data, 'file> ObjectComdat<'data> for WasmComdat<'data, 'file> {
607 type SectionIterator = WasmComdatSectionIterator<'data, 'file>;
608
609 #[inline]
610 fn kind(&self) -> ComdatKind {
611 unreachable!();
612 }
613
614 #[inline]
615 fn symbol(&self) -> SymbolIndex {
616 unreachable!();
617 }
618
619 #[inline]
620 fn name(&self) -> Result<&str> {
621 unreachable!();
622 }
623
624 #[inline]
625 fn sections(&self) -> Self::SectionIterator {
626 unreachable!();
627 }
628 }
629
630 /// An iterator over the sections in a COMDAT section group of a `WasmFile`.
631 #[derive(Debug)]
632 pub struct WasmComdatSectionIterator<'data, 'file>
633 where
634 'data: 'file,
635 {
636 file: &'file WasmFile<'data>,
637 }
638
639 impl<'data, 'file> Iterator for WasmComdatSectionIterator<'data, 'file> {
640 type Item = SectionIndex;
641
642 fn next(&mut self) -> Option<Self::Item> {
643 None
644 }
645 }
646
647 /// A symbol table of a `WasmFile`.
648 #[derive(Debug)]
649 pub struct WasmSymbolTable<'data, 'file> {
650 symbols: &'file [WasmSymbolInternal<'data>],
651 }
652
653 impl<'data, 'file> read::private::Sealed for WasmSymbolTable<'data, 'file> {}
654
655 impl<'data, 'file> ObjectSymbolTable<'data> for WasmSymbolTable<'data, 'file> {
656 type Symbol = WasmSymbol<'data, 'file>;
657 type SymbolIterator = WasmSymbolIterator<'data, 'file>;
658
659 fn symbols(&self) -> Self::SymbolIterator {
660 WasmSymbolIterator {
661 symbols: self.symbols.iter().enumerate(),
662 }
663 }
664
665 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
666 let symbol = self
667 .symbols
668 .get(index.0)
669 .read_error("Invalid Wasm symbol index")?;
670 Ok(WasmSymbol { index, symbol })
671 }
672 }
673
674 /// An iterator over the symbols of a `WasmFile`.
675 #[derive(Debug)]
676 pub struct WasmSymbolIterator<'data, 'file> {
677 symbols: core::iter::Enumerate<slice::Iter<'file, WasmSymbolInternal<'data>>>,
678 }
679
680 impl<'data, 'file> Iterator for WasmSymbolIterator<'data, 'file> {
681 type Item = WasmSymbol<'data, 'file>;
682
683 fn next(&mut self) -> Option<Self::Item> {
684 let (index, symbol) = self.symbols.next()?;
685 Some(WasmSymbol {
686 index: SymbolIndex(index),
687 symbol,
688 })
689 }
690 }
691
692 /// A symbol of a `WasmFile`.
693 #[derive(Clone, Copy, Debug)]
694 pub struct WasmSymbol<'data, 'file> {
695 index: SymbolIndex,
696 symbol: &'file WasmSymbolInternal<'data>,
697 }
698
699 #[derive(Clone, Debug)]
700 struct WasmSymbolInternal<'data> {
701 name: &'data str,
702 address: u64,
703 size: u64,
704 kind: SymbolKind,
705 section: SymbolSection,
706 scope: SymbolScope,
707 }
708
709 impl<'data, 'file> read::private::Sealed for WasmSymbol<'data, 'file> {}
710
711 impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> {
712 #[inline]
713 fn index(&self) -> SymbolIndex {
714 self.index
715 }
716
717 #[inline]
718 fn name(&self) -> read::Result<&'data str> {
719 Ok(self.symbol.name)
720 }
721
722 #[inline]
723 fn address(&self) -> u64 {
724 self.symbol.address
725 }
726
727 #[inline]
728 fn size(&self) -> u64 {
729 self.symbol.size
730 }
731
732 #[inline]
733 fn kind(&self) -> SymbolKind {
734 self.symbol.kind
735 }
736
737 #[inline]
738 fn section(&self) -> SymbolSection {
739 self.symbol.section
740 }
741
742 #[inline]
743 fn is_undefined(&self) -> bool {
744 self.symbol.section == SymbolSection::Undefined
745 }
746
747 #[inline]
748 fn is_definition(&self) -> bool {
749 self.symbol.kind == SymbolKind::Text && self.symbol.section != SymbolSection::Undefined
750 }
751
752 #[inline]
753 fn is_common(&self) -> bool {
754 self.symbol.section == SymbolSection::Common
755 }
756
757 #[inline]
758 fn is_weak(&self) -> bool {
759 false
760 }
761
762 #[inline]
763 fn scope(&self) -> SymbolScope {
764 self.symbol.scope
765 }
766
767 #[inline]
768 fn is_global(&self) -> bool {
769 self.symbol.scope != SymbolScope::Compilation
770 }
771
772 #[inline]
773 fn is_local(&self) -> bool {
774 self.symbol.scope == SymbolScope::Compilation
775 }
776
777 #[inline]
778 fn flags(&self) -> SymbolFlags<SectionIndex> {
779 SymbolFlags::None
780 }
781 }
782
783 /// An iterator over the relocations in a `WasmSection`.
784 #[derive(Debug, Default)]
785 pub struct WasmRelocationIterator<'data, 'file>(PhantomData<(&'data (), &'file ())>);
786
787 impl<'data, 'file> Iterator for WasmRelocationIterator<'data, 'file> {
788 type Item = (u64, Relocation);
789
790 #[inline]
791 fn next(&mut self) -> Option<Self::Item> {
792 None
793 }
794 }
795
796 fn section_code_to_id(code: wp::SectionCode) -> usize {
797 match code {
798 wp::SectionCode::Custom { .. } => SECTION_CUSTOM,
799 wp::SectionCode::Type => SECTION_TYPE,
800 wp::SectionCode::Import => SECTION_IMPORT,
801 wp::SectionCode::Function => SECTION_FUNCTION,
802 wp::SectionCode::Table => SECTION_TABLE,
803 wp::SectionCode::Memory => SECTION_MEMORY,
804 wp::SectionCode::Global => SECTION_GLOBAL,
805 wp::SectionCode::Export => SECTION_EXPORT,
806 wp::SectionCode::Start => SECTION_START,
807 wp::SectionCode::Element => SECTION_ELEMENT,
808 wp::SectionCode::Code => SECTION_CODE,
809 wp::SectionCode::Data => SECTION_DATA,
810 wp::SectionCode::DataCount => SECTION_DATA_COUNT,
811 }
812 }