1use alloc::fmt;
2use core::convert::TryInto;
3use core::fmt::Debug;
4use core::marker::PhantomData;
5use core::str;
6
7use crate::endian::{BigEndian as BE, U32Bytes};
8use crate::pod::{bytes_of, Pod};
9use crate::read::{
10 self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex,
11 StringTable, SymbolFlags, SymbolIndex, SymbolKind, SymbolScope, SymbolSection,
12};
13use crate::xcoff;
14
15use super::{FileHeader, XcoffFile};
16
17#[derive(Debug)]
23pub struct SymbolTable<'data, Xcoff, R = &'data [u8]>
24where
25 Xcoff: FileHeader,
26 R: ReadRef<'data>,
27{
28 symbols: &'data [xcoff::SymbolBytes],
29 strings: StringTable<'data, R>,
30 header: PhantomData<Xcoff>,
31}
32
33impl<'data, Xcoff, R> Default for SymbolTable<'data, Xcoff, R>
34where
35 Xcoff: FileHeader,
36 R: ReadRef<'data>,
37{
38 fn default() -> Self {
39 Self {
40 symbols: &[],
41 strings: StringTable::default(),
42 header: PhantomData,
43 }
44 }
45}
46
47impl<'data, Xcoff, R> SymbolTable<'data, Xcoff, R>
48where
49 Xcoff: FileHeader,
50 R: ReadRef<'data>,
51{
52 pub fn parse(header: Xcoff, data: R) -> Result<Self> {
54 let mut offset = header.f_symptr().into();
55 let (symbols, strings) = if offset != 0 {
56 let symbols = data
57 .read_slice(&mut offset, header.f_nsyms() as usize)
58 .read_error("Invalid XCOFF symbol table offset or size")?;
59
60 let length = data
63 .read_at::<U32Bytes<_>>(offset)
64 .read_error("Missing XCOFF string table")?
65 .get(BE);
66 let str_end = offset
67 .checked_add(length as u64)
68 .read_error("Invalid XCOFF string table length")?;
69 let strings = StringTable::new(data, offset, str_end);
70
71 (symbols, strings)
72 } else {
73 (&[][..], StringTable::default())
74 };
75
76 Ok(SymbolTable {
77 symbols,
78 strings,
79 header: PhantomData,
80 })
81 }
82
83 #[inline]
85 pub fn strings(&self) -> StringTable<'data, R> {
86 self.strings
87 }
88
89 #[inline]
93 pub fn iter<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> {
94 SymbolIterator {
95 symbols: self,
96 index: 0,
97 }
98 }
99
100 #[inline]
102 pub(super) fn iter_none<'table>(&'table self) -> SymbolIterator<'data, 'table, Xcoff, R> {
103 SymbolIterator {
104 symbols: self,
105 index: self.symbols.len(),
106 }
107 }
108
109 pub fn get<T: Pod>(&self, index: SymbolIndex, offset: usize) -> Result<&'data T> {
111 let entry = index
112 .0
113 .checked_add(offset)
114 .and_then(|x| self.symbols.get(x))
115 .read_error("Invalid XCOFF symbol index")?;
116 let bytes = bytes_of(entry);
117 Bytes(bytes).read().read_error("Invalid XCOFF symbol data")
118 }
119
120 fn symbol_unchecked(&self, index: SymbolIndex) -> Result<&'data Xcoff::Symbol> {
124 self.get::<Xcoff::Symbol>(index, 0)
125 }
126
127 pub fn symbol(&self, index: SymbolIndex) -> Result<&'data Xcoff::Symbol> {
132 let symbol = self.symbol_unchecked(index)?;
133 if symbol.is_null() {
134 return Err(Error("Invalid XCOFF symbol index"));
135 }
136 Ok(symbol)
137 }
138
139 pub fn aux_file(&self, index: SymbolIndex, offset: usize) -> Result<&'data Xcoff::FileAux> {
141 debug_assert!(self.symbol(index)?.has_aux_file());
142 let aux_file = self.get::<Xcoff::FileAux>(index, offset)?;
143 if let Some(aux_type) = aux_file.x_auxtype() {
144 if aux_type != xcoff::AUX_FILE {
145 return Err(Error("Invalid index for file auxiliary symbol."));
146 }
147 }
148 Ok(aux_file)
149 }
150
151 pub fn aux_csect(&self, index: SymbolIndex, offset: usize) -> Result<&'data Xcoff::CsectAux> {
153 debug_assert!(self.symbol(index)?.has_aux_csect());
154 let aux_csect = self.get::<Xcoff::CsectAux>(index, offset)?;
155 if let Some(aux_type) = aux_csect.x_auxtype() {
156 if aux_type != xcoff::AUX_CSECT {
157 return Err(Error("Invalid index/offset for csect auxiliary symbol."));
158 }
159 }
160 Ok(aux_csect)
161 }
162
163 #[inline]
165 pub fn is_empty(&self) -> bool {
166 self.symbols.is_empty()
167 }
168
169 #[inline]
173 pub fn len(&self) -> usize {
174 self.symbols.len()
175 }
176}
177
178#[derive(Debug)]
182pub struct SymbolIterator<'data, 'table, Xcoff, R = &'data [u8]>
183where
184 Xcoff: FileHeader,
185 R: ReadRef<'data>,
186{
187 symbols: &'table SymbolTable<'data, Xcoff, R>,
188 index: usize,
189}
190
191impl<'data, 'table, Xcoff: FileHeader, R: ReadRef<'data>> Iterator
192 for SymbolIterator<'data, 'table, Xcoff, R>
193{
194 type Item = (SymbolIndex, &'data Xcoff::Symbol);
195
196 fn next(&mut self) -> Option<Self::Item> {
197 loop {
198 let index = SymbolIndex(self.index);
199 let symbol = self.symbols.symbol_unchecked(index).ok()?;
200 self.index += 1 + symbol.n_numaux() as usize;
201 if !symbol.is_null() {
202 return Some((index, symbol));
203 }
204 }
205 }
206}
207
208pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> =
210 XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>;
211pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> =
213 XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>;
214
215#[derive(Debug, Clone, Copy)]
217pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]>
218where
219 Xcoff: FileHeader,
220 R: ReadRef<'data>,
221{
222 pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
223 pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>,
224}
225
226impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed
227 for XcoffSymbolTable<'data, 'file, Xcoff, R>
228{
229}
230
231impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data>
232 for XcoffSymbolTable<'data, 'file, Xcoff, R>
233{
234 type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>;
235 type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>;
236
237 fn symbols(&self) -> Self::SymbolIterator {
238 XcoffSymbolIterator {
239 file: self.file,
240 symbols: self.symbols.iter(),
241 }
242 }
243
244 fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<Self::Symbol> {
245 let symbol = self.symbols.symbol(index)?;
246 Ok(XcoffSymbol {
247 file: self.file,
248 symbols: self.symbols,
249 index,
250 symbol,
251 })
252 }
253}
254
255pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> =
257 XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>;
258pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> =
260 XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>;
261
262pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]>
264where
265 Xcoff: FileHeader,
266 R: ReadRef<'data>,
267{
268 pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
269 pub(super) symbols: SymbolIterator<'data, 'file, Xcoff, R>,
270}
271
272impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> fmt::Debug
273 for XcoffSymbolIterator<'data, 'file, Xcoff, R>
274{
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 f.debug_struct("XcoffSymbolIterator").finish()
277 }
278}
279
280impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator
281 for XcoffSymbolIterator<'data, 'file, Xcoff, R>
282{
283 type Item = XcoffSymbol<'data, 'file, Xcoff, R>;
284
285 fn next(&mut self) -> Option<Self::Item> {
286 let (index, symbol) = self.symbols.next()?;
287 Some(XcoffSymbol {
288 file: self.file,
289 symbols: self.symbols.symbols,
290 index,
291 symbol,
292 })
293 }
294}
295
296pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> =
298 XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>;
299pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> =
301 XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>;
302
303#[derive(Debug, Clone, Copy)]
307pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]>
308where
309 Xcoff: FileHeader,
310 R: ReadRef<'data>,
311{
312 pub(super) file: &'file XcoffFile<'data, Xcoff, R>,
313 pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>,
314 pub(super) index: SymbolIndex,
315 pub(super) symbol: &'data Xcoff::Symbol,
316}
317
318impl<'data, 'file, Xcoff, R> XcoffSymbol<'data, 'file, Xcoff, R>
319where
320 Xcoff: FileHeader,
321 R: ReadRef<'data>,
322{
323 pub fn xcoff_file(&self) -> &'file XcoffFile<'data, Xcoff, R> {
325 self.file
326 }
327
328 pub fn xcoff_symbol(&self) -> &'data Xcoff::Symbol {
330 self.symbol
331 }
332}
333
334impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed
335 for XcoffSymbol<'data, 'file, Xcoff, R>
336{
337}
338
339impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
340 for XcoffSymbol<'data, 'file, Xcoff, R>
341{
342 #[inline]
343 fn index(&self) -> SymbolIndex {
344 self.index
345 }
346
347 fn name_bytes(&self) -> Result<&'data [u8]> {
348 if self.symbol.has_aux_file() {
349 self.symbols
351 .aux_file(self.index, 1)?
352 .fname(self.symbols.strings)
353 } else {
354 self.symbol.name(self.symbols.strings)
355 }
356 }
357
358 fn name(&self) -> Result<&'data str> {
359 let name = self.name_bytes()?;
360 str::from_utf8(name)
361 .ok()
362 .read_error("Non UTF-8 XCOFF symbol name")
363 }
364
365 #[inline]
366 fn address(&self) -> u64 {
367 match self.symbol.n_sclass() {
368 xcoff::C_EXT
370 | xcoff::C_WEAKEXT
371 | xcoff::C_HIDEXT
372 | xcoff::C_FCN
373 | xcoff::C_BLOCK
374 | xcoff::C_STAT
375 | xcoff::C_INFO => self.symbol.n_value().into(),
376 _ => 0,
377 }
378 }
379
380 #[inline]
381 fn size(&self) -> u64 {
382 if self.symbol.has_aux_csect() {
383 if let Ok(aux_csect) = self
386 .file
387 .symbols
388 .aux_csect(self.index, self.symbol.n_numaux() as usize)
389 {
390 let sym_type = aux_csect.sym_type();
391 if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
392 return aux_csect.x_scnlen();
393 }
394 }
395 }
396 0
397 }
398
399 fn kind(&self) -> SymbolKind {
400 if self.symbol.has_aux_csect() {
401 if let Ok(aux_csect) = self
402 .file
403 .symbols
404 .aux_csect(self.index, self.symbol.n_numaux() as usize)
405 {
406 let sym_type = aux_csect.sym_type();
407 if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
408 return match aux_csect.x_smclas() {
409 xcoff::XMC_PR | xcoff::XMC_GL => SymbolKind::Text,
410 xcoff::XMC_RO | xcoff::XMC_RW | xcoff::XMC_TD | xcoff::XMC_BS => {
411 SymbolKind::Data
412 }
413 xcoff::XMC_TL | xcoff::XMC_UL => SymbolKind::Tls,
414 xcoff::XMC_DS | xcoff::XMC_TC0 | xcoff::XMC_TC => {
415 SymbolKind::Data
417 }
418 _ => SymbolKind::Unknown,
419 };
420 } else if sym_type == xcoff::XTY_LD {
421 return SymbolKind::Text;
423 } else if sym_type == xcoff::XTY_ER {
424 return SymbolKind::Unknown;
425 }
426 }
427 }
428 match self.symbol.n_sclass() {
429 xcoff::C_FILE => SymbolKind::File,
430 _ => SymbolKind::Unknown,
431 }
432 }
433
434 fn section(&self) -> SymbolSection {
435 match self.symbol.n_scnum() {
436 xcoff::N_ABS => SymbolSection::Absolute,
437 xcoff::N_UNDEF => SymbolSection::Undefined,
438 xcoff::N_DEBUG => SymbolSection::None,
439 index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)),
440 _ => SymbolSection::Unknown,
441 }
442 }
443
444 #[inline]
445 fn is_undefined(&self) -> bool {
446 self.symbol.is_undefined()
447 }
448
449 #[inline]
451 fn is_definition(&self) -> bool {
452 if self.symbol.n_scnum() <= 0 {
453 return false;
454 }
455 if self.symbol.has_aux_csect() {
456 if let Ok(aux_csect) = self
457 .symbols
458 .aux_csect(self.index, self.symbol.n_numaux() as usize)
459 {
460 let sym_type = aux_csect.sym_type();
461 sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_LD || sym_type == xcoff::XTY_CM
462 } else {
463 false
464 }
465 } else {
466 false
467 }
468 }
469
470 #[inline]
471 fn is_common(&self) -> bool {
472 self.symbol.n_sclass() == xcoff::C_EXT && self.symbol.n_scnum() == xcoff::N_UNDEF
473 }
474
475 #[inline]
476 fn is_weak(&self) -> bool {
477 self.symbol.n_sclass() == xcoff::C_WEAKEXT
478 }
479
480 fn scope(&self) -> SymbolScope {
481 if self.symbol.n_scnum() == xcoff::N_UNDEF {
482 SymbolScope::Unknown
483 } else {
484 match self.symbol.n_sclass() {
485 xcoff::C_EXT | xcoff::C_WEAKEXT => {
486 let visibility = self.symbol.n_type() & xcoff::SYM_V_MASK;
487 if visibility == xcoff::SYM_V_HIDDEN {
488 SymbolScope::Linkage
489 } else {
490 SymbolScope::Dynamic
491 }
492 }
493 _ => SymbolScope::Compilation,
494 }
495 }
496 }
497
498 #[inline]
499 fn is_global(&self) -> bool {
500 match self.symbol.n_sclass() {
501 xcoff::C_EXT | xcoff::C_WEAKEXT => true,
502 _ => false,
503 }
504 }
505
506 #[inline]
507 fn is_local(&self) -> bool {
508 !self.is_global()
509 }
510
511 #[inline]
512 fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
513 let mut x_smtyp = 0;
514 let mut x_smclas = 0;
515 let mut containing_csect = None;
516 if self.symbol.has_aux_csect() {
517 if let Ok(aux_csect) = self
518 .file
519 .symbols
520 .aux_csect(self.index, self.symbol.n_numaux() as usize)
521 {
522 x_smtyp = aux_csect.x_smtyp();
523 x_smclas = aux_csect.x_smclas();
524 if aux_csect.sym_type() == xcoff::XTY_LD {
525 containing_csect = Some(SymbolIndex(aux_csect.x_scnlen() as usize))
526 }
527 }
528 }
529 SymbolFlags::Xcoff {
530 n_sclass: self.symbol.n_sclass(),
531 x_smtyp,
532 x_smclas,
533 containing_csect,
534 }
535 }
536}
537
538#[allow(missing_docs)]
540pub trait Symbol: Debug + Pod {
541 type Word: Into<u64>;
542
543 fn n_value(&self) -> Self::Word;
544 fn n_scnum(&self) -> i16;
545 fn n_type(&self) -> u16;
546 fn n_sclass(&self) -> u8;
547 fn n_numaux(&self) -> u8;
548
549 fn name_offset(&self) -> Option<u32>;
550 fn name<'data, R: ReadRef<'data>>(
551 &'data self,
552 strings: StringTable<'data, R>,
553 ) -> Result<&'data [u8]>;
554
555 fn section(&self) -> Option<SectionIndex> {
557 let index = self.n_scnum();
558 if index > 0 {
559 Some(SectionIndex(index as usize))
560 } else {
561 None
562 }
563 }
564
565 #[inline]
567 fn is_null(&self) -> bool {
568 self.n_sclass() == xcoff::C_NULL
569 }
570
571 #[inline]
573 fn is_undefined(&self) -> bool {
574 let n_sclass = self.n_sclass();
575 (n_sclass == xcoff::C_EXT || n_sclass == xcoff::C_WEAKEXT)
576 && self.n_scnum() == xcoff::N_UNDEF
577 }
578
579 fn has_aux_file(&self) -> bool {
581 self.n_numaux() > 0 && self.n_sclass() == xcoff::C_FILE
582 }
583
584 fn has_aux_csect(&self) -> bool {
589 let sclass = self.n_sclass();
590 self.n_numaux() > 0
591 && (sclass == xcoff::C_EXT || sclass == xcoff::C_WEAKEXT || sclass == xcoff::C_HIDEXT)
592 }
593}
594
595impl Symbol for xcoff::Symbol64 {
596 type Word = u64;
597
598 fn n_value(&self) -> Self::Word {
599 self.n_value.get(BE)
600 }
601
602 fn n_scnum(&self) -> i16 {
603 self.n_scnum.get(BE)
604 }
605
606 fn n_type(&self) -> u16 {
607 self.n_type.get(BE)
608 }
609
610 fn n_sclass(&self) -> u8 {
611 self.n_sclass
612 }
613
614 fn n_numaux(&self) -> u8 {
615 self.n_numaux
616 }
617
618 fn name_offset(&self) -> Option<u32> {
619 Some(self.n_offset.get(BE))
620 }
621
622 fn name<'data, R: ReadRef<'data>>(
624 &'data self,
625 strings: StringTable<'data, R>,
626 ) -> Result<&'data [u8]> {
627 strings
628 .get(self.n_offset.get(BE))
629 .read_error("Invalid XCOFF symbol name offset")
630 }
631}
632
633impl Symbol for xcoff::Symbol32 {
634 type Word = u32;
635
636 fn n_value(&self) -> Self::Word {
637 self.n_value.get(BE)
638 }
639
640 fn n_scnum(&self) -> i16 {
641 self.n_scnum.get(BE)
642 }
643
644 fn n_type(&self) -> u16 {
645 self.n_type.get(BE)
646 }
647
648 fn n_sclass(&self) -> u8 {
649 self.n_sclass
650 }
651
652 fn n_numaux(&self) -> u8 {
653 self.n_numaux
654 }
655
656 fn name_offset(&self) -> Option<u32> {
657 if self.n_name[0] == 0 {
658 let offset = u32::from_be_bytes(self.n_name[4..8].try_into().unwrap());
659 Some(offset)
660 } else {
661 None
662 }
663 }
664
665 fn name<'data, R: ReadRef<'data>>(
667 &'data self,
668 strings: StringTable<'data, R>,
669 ) -> Result<&'data [u8]> {
670 if let Some(offset) = self.name_offset() {
671 strings
673 .get(offset)
674 .read_error("Invalid XCOFF symbol name offset")
675 } else {
676 Ok(match memchr::memchr(b'\0', &self.n_name) {
678 Some(end) => &self.n_name[..end],
679 None => &self.n_name,
680 })
681 }
682 }
683}
684
685#[allow(missing_docs)]
687pub trait FileAux: Debug + Pod {
688 fn x_fname(&self) -> &[u8; 8];
689 fn x_ftype(&self) -> u8;
690 fn x_auxtype(&self) -> Option<u8>;
691
692 fn name_offset(&self) -> Option<u32> {
693 let x_fname = self.x_fname();
694 if x_fname[0] == 0 {
695 Some(u32::from_be_bytes(x_fname[4..8].try_into().unwrap()))
696 } else {
697 None
698 }
699 }
700
701 fn fname<'data, R: ReadRef<'data>>(
703 &'data self,
704 strings: StringTable<'data, R>,
705 ) -> Result<&'data [u8]> {
706 if let Some(offset) = self.name_offset() {
707 strings
709 .get(offset)
710 .read_error("Invalid XCOFF symbol name offset")
711 } else {
712 let x_fname = self.x_fname();
714 Ok(match memchr::memchr(b'\0', x_fname) {
715 Some(end) => &x_fname[..end],
716 None => x_fname,
717 })
718 }
719 }
720}
721
722impl FileAux for xcoff::FileAux64 {
723 fn x_fname(&self) -> &[u8; 8] {
724 &self.x_fname
725 }
726
727 fn x_ftype(&self) -> u8 {
728 self.x_ftype
729 }
730
731 fn x_auxtype(&self) -> Option<u8> {
732 Some(self.x_auxtype)
733 }
734}
735
736impl FileAux for xcoff::FileAux32 {
737 fn x_fname(&self) -> &[u8; 8] {
738 &self.x_fname
739 }
740
741 fn x_ftype(&self) -> u8 {
742 self.x_ftype
743 }
744
745 fn x_auxtype(&self) -> Option<u8> {
746 None
747 }
748}
749
750#[allow(missing_docs)]
752pub trait CsectAux: Debug + Pod {
753 fn x_scnlen(&self) -> u64;
754 fn x_parmhash(&self) -> u32;
755 fn x_snhash(&self) -> u16;
756 fn x_smtyp(&self) -> u8;
757 fn x_smclas(&self) -> u8;
758 fn x_stab(&self) -> Option<u32>;
759 fn x_snstab(&self) -> Option<u16>;
760 fn x_auxtype(&self) -> Option<u8>;
761
762 fn alignment(&self) -> u8 {
763 self.x_smtyp() >> 3
764 }
765 fn sym_type(&self) -> u8 {
766 self.x_smtyp() & 0x07
767 }
768}
769
770impl CsectAux for xcoff::CsectAux64 {
771 fn x_scnlen(&self) -> u64 {
772 self.x_scnlen_lo.get(BE) as u64 | ((self.x_scnlen_hi.get(BE) as u64) << 32)
773 }
774
775 fn x_parmhash(&self) -> u32 {
776 self.x_parmhash.get(BE)
777 }
778
779 fn x_snhash(&self) -> u16 {
780 self.x_snhash.get(BE)
781 }
782
783 fn x_smtyp(&self) -> u8 {
784 self.x_smtyp
785 }
786
787 fn x_smclas(&self) -> u8 {
788 self.x_smclas
789 }
790
791 fn x_stab(&self) -> Option<u32> {
792 None
793 }
794
795 fn x_snstab(&self) -> Option<u16> {
796 None
797 }
798
799 fn x_auxtype(&self) -> Option<u8> {
800 Some(self.x_auxtype)
801 }
802}
803
804impl CsectAux for xcoff::CsectAux32 {
805 fn x_scnlen(&self) -> u64 {
806 self.x_scnlen.get(BE) as u64
807 }
808
809 fn x_parmhash(&self) -> u32 {
810 self.x_parmhash.get(BE)
811 }
812
813 fn x_snhash(&self) -> u16 {
814 self.x_snhash.get(BE)
815 }
816
817 fn x_smtyp(&self) -> u8 {
818 self.x_smtyp
819 }
820
821 fn x_smclas(&self) -> u8 {
822 self.x_smclas
823 }
824
825 fn x_stab(&self) -> Option<u32> {
826 Some(self.x_stab.get(BE))
827 }
828
829 fn x_snstab(&self) -> Option<u16> {
830 Some(self.x_snstab.get(BE))
831 }
832
833 fn x_auxtype(&self) -> Option<u8> {
834 None
835 }
836}