From 8a566d81046fcca0e696e213dd568952774b0bf2 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Thu, 29 Sep 2022 12:46:15 +0800 Subject: [PATCH 01/12] Initial support for reading XCOFF. --- src/common.rs | 11 + src/read/any.rs | 90 ++++++++ src/read/mod.rs | 25 ++- src/read/xcoff/comdat.rs | 130 +++++++++++ src/read/xcoff/file.rs | 390 ++++++++++++++++++++++++++++++++ src/read/xcoff/mod.rs | 21 ++ src/read/xcoff/relocation.rs | 63 ++++++ src/read/xcoff/section.rs | 381 +++++++++++++++++++++++++++++++ src/read/xcoff/segment.rs | 115 ++++++++++ src/read/xcoff/symbol.rs | 421 +++++++++++++++++++++++++++++++++++ src/xcoff.rs | 46 +++- 11 files changed, 1687 insertions(+), 6 deletions(-) create mode 100644 src/read/xcoff/comdat.rs create mode 100644 src/read/xcoff/file.rs create mode 100644 src/read/xcoff/mod.rs create mode 100644 src/read/xcoff/relocation.rs create mode 100644 src/read/xcoff/section.rs create mode 100644 src/read/xcoff/segment.rs create mode 100644 src/read/xcoff/symbol.rs diff --git a/src/common.rs b/src/common.rs index 77065ae2..722bb90d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -88,6 +88,7 @@ pub enum BinaryFormat { MachO, Pe, Wasm, + Xcoff, } /// The kind of a section. @@ -375,6 +376,11 @@ pub enum FileFlags { /// `Characteristics` field in the COFF file header. characteristics: u16, }, + /// XCOFF file flags. + Xcoff { + /// `f_flags` field in the XCOFF file header. + f_flags: u16, + }, } /// Segment flags that are specific to each file format. @@ -425,6 +431,11 @@ pub enum SectionFlags { /// `Characteristics` field in the section header. characteristics: u32, }, + /// XCOFF section flags. + Xcoff { + /// `s_flags` field in the section header. + s_flags: u32, + }, } /// Symbol flags that are specific to each file format. diff --git a/src/read/any.rs b/src/read/any.rs index 02e76dcd..c390b21b 100644 --- a/src/read/any.rs +++ b/src/read/any.rs @@ -12,6 +12,8 @@ use crate::read::macho; use crate::read::pe; #[cfg(feature = "wasm")] use crate::read::wasm; +#[cfg(feature = "xcoff")] +use crate::read::xcoff; use crate::read::{ self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap, @@ -44,6 +46,10 @@ macro_rules! with_inner { $enum::Pe64(ref $var) => $body, #[cfg(feature = "wasm")] $enum::Wasm(ref $var) => $body, + #[cfg(feature = "xcoff")] + $enum::Xcoff32(ref $var) => $body, + #[cfg(feature = "xcoff")] + $enum::Xcoff64(ref $var) => $body, } }; } @@ -67,6 +73,10 @@ macro_rules! with_inner_mut { $enum::Pe64(ref mut $var) => $body, #[cfg(feature = "wasm")] $enum::Wasm(ref mut $var) => $body, + #[cfg(feature = "xcoff")] + $enum::Xcoff32(ref mut $var) => $body, + #[cfg(feature = "xcoff")] + $enum::Xcoff64(ref mut $var) => $body, } }; } @@ -91,6 +101,10 @@ macro_rules! map_inner { $from::Pe64(ref $var) => $to::Pe64($body), #[cfg(feature = "wasm")] $from::Wasm(ref $var) => $to::Wasm($body), + #[cfg(feature = "xcoff")] + $from::Xcoff32(ref $var) => $to::Xcoff32($body), + #[cfg(feature = "xcoff")] + $from::Xcoff64(ref $var) => $to::Xcoff64($body), } }; } @@ -115,6 +129,10 @@ macro_rules! map_inner_option { $from::Pe64(ref $var) => $body.map($to::Pe64), #[cfg(feature = "wasm")] $from::Wasm(ref $var) => $body.map($to::Wasm), + #[cfg(feature = "xcoff")] + $from::Xcoff32(ref $var) => $body.map($to::Xcoff32), + #[cfg(feature = "xcoff")] + $from::Xcoff64(ref $var) => $body.map($to::Xcoff64), } }; } @@ -138,6 +156,10 @@ macro_rules! map_inner_option_mut { $from::Pe64(ref mut $var) => $body.map($to::Pe64), #[cfg(feature = "wasm")] $from::Wasm(ref mut $var) => $body.map($to::Wasm), + #[cfg(feature = "xcoff")] + $from::Xcoff32(ref mut $var) => $body.map($to::Xcoff32), + #[cfg(feature = "xcoff")] + $from::Xcoff64(ref mut $var) => $body.map($to::Xcoff64), } }; } @@ -162,6 +184,10 @@ macro_rules! next_inner { $from::Pe64(ref mut iter) => iter.next().map($to::Pe64), #[cfg(feature = "wasm")] $from::Wasm(ref mut iter) => iter.next().map($to::Wasm), + #[cfg(feature = "xcoff")] + $from::Xcoff32(ref mut iter) => iter.next().map($to::Xcoff32), + #[cfg(feature = "xcoff")] + $from::Xcoff64(ref mut iter) => iter.next().map($to::Xcoff64), } }; } @@ -192,6 +218,10 @@ enum FileInternal<'data, R: ReadRef<'data>> { Pe64(pe::PeFile64<'data, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmFile<'data, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffFile32<'data, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffFile64<'data, R>), } impl<'data, R: ReadRef<'data>> File<'data, R> { @@ -214,6 +244,10 @@ impl<'data, R: ReadRef<'data>> File<'data, R> { FileKind::Pe64 => FileInternal::Pe64(pe::PeFile64::parse(data)?), #[cfg(feature = "coff")] FileKind::Coff => FileInternal::Coff(coff::CoffFile::parse(data)?), + #[cfg(feature = "xcoff")] + FileKind::Xcoff32 => FileInternal::Xcoff32(xcoff::XcoffFile32::parse(data)?), + #[cfg(feature = "xcoff")] + FileKind::Xcoff64 => FileInternal::Xcoff64(xcoff::XcoffFile64::parse(data)?), #[allow(unreachable_patterns)] _ => return Err(Error("Unsupported file format")), }; @@ -250,6 +284,8 @@ impl<'data, R: ReadRef<'data>> File<'data, R> { FileInternal::Pe32(_) | FileInternal::Pe64(_) => BinaryFormat::Pe, #[cfg(feature = "wasm")] FileInternal::Wasm(_) => BinaryFormat::Wasm, + #[cfg(feature = "xcoff")] + FileInternal::Xcoff32(_) | FileInternal::Xcoff64(_) => BinaryFormat::Xcoff, } } } @@ -468,6 +504,10 @@ where Pe64(pe::PeSegmentIterator64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmSegmentIterator<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffSegmentIterator32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffSegmentIterator64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, R> { @@ -508,6 +548,10 @@ where Pe64(pe::PeSegment64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmSegment<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffSegment32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffSegment64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Segment<'data, 'file, R> { @@ -600,6 +644,10 @@ where Pe64(pe::PeSectionIterator64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmSectionIterator<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffSectionIterator32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffSectionIterator64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, R> { @@ -639,6 +687,10 @@ where Pe64(pe::PeSection64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmSection<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffSection32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffSection64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Section<'data, 'file, R> { @@ -771,6 +823,10 @@ where Pe64(pe::PeComdatIterator64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmComdatIterator<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffComdatIterator32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffComdatIterator64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, R> { @@ -810,6 +866,10 @@ where Pe64(pe::PeComdat64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmComdat<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffComdat32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffComdat64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Comdat<'data, 'file, R> { @@ -885,6 +945,10 @@ where Pe64(pe::PeComdatSectionIterator64<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmComdatSectionIterator<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffComdatSectionIterator32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffComdatSectionIterator64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, 'file, R> { @@ -947,6 +1011,10 @@ where Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData)), #[cfg(feature = "wasm")] Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData)), + #[cfg(feature = "xcoff")] + Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData)), + #[cfg(feature = "xcoff")] + Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData)), } impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {} @@ -1027,6 +1095,20 @@ where Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData)), #[cfg(feature = "wasm")] Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData)), + #[cfg(feature = "xcoff")] + Xcoff32( + ( + xcoff::XcoffSymbolIterator32<'data, 'file, R>, + PhantomData, + ), + ), + #[cfg(feature = "xcoff")] + Xcoff64( + ( + xcoff::XcoffSymbolIterator64<'data, 'file, R>, + PhantomData, + ), + ), } impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> { @@ -1090,6 +1172,10 @@ where Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData)), #[cfg(feature = "wasm")] Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData)), + #[cfg(feature = "xcoff")] + Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData)), + #[cfg(feature = "xcoff")] + Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData)), } impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> { @@ -1240,6 +1326,10 @@ where Pe64(pe::PeRelocationIterator<'data, 'file, R>), #[cfg(feature = "wasm")] Wasm(wasm::WasmRelocationIterator<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff32(xcoff::XcoffRelocationIterator32<'data, 'file, R>), + #[cfg(feature = "xcoff")] + Xcoff64(xcoff::XcoffRelocationIterator64<'data, 'file, R>), } impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionRelocationIterator<'data, 'file, R> { diff --git a/src/read/mod.rs b/src/read/mod.rs index 41d34411..91a5c05a 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -22,7 +22,8 @@ pub use util::*; feature = "elf", feature = "macho", feature = "pe", - feature = "wasm" + feature = "wasm", + feature = "xcoff" ))] mod any; #[cfg(any( @@ -30,7 +31,8 @@ mod any; feature = "elf", feature = "macho", feature = "pe", - feature = "wasm" + feature = "wasm", + feature = "xcoff" ))] pub use any::*; @@ -49,12 +51,15 @@ pub mod macho; #[cfg(feature = "pe")] pub mod pe; -mod traits; -pub use traits::*; - #[cfg(feature = "wasm")] pub mod wasm; +#[cfg(feature = "xcoff")] +pub mod xcoff; + +mod traits; +pub use traits::*; + mod private { pub trait Sealed {} } @@ -176,6 +181,12 @@ pub enum FileKind { /// A Wasm file. #[cfg(feature = "wasm")] Wasm, + /// A 32-bit XCOFF file. + #[cfg(feature = "xcoff")] + Xcoff32, + /// A 64-bit XCOFF file. + #[cfg(feature = "xcoff")] + Xcoff64, } impl FileKind { @@ -236,6 +247,10 @@ impl FileKind { | [0x4c, 0x01, ..] // COFF x86-64 | [0x64, 0x86, ..] => FileKind::Coff, + #[cfg(feature = "xcoff")] + [0x01, 0xDF, ..] => FileKind::Xcoff32, + #[cfg(feature = "xcoff")] + [0x01, 0xF7, ..] => FileKind::Xcoff64, _ => return Err(Error("Unknown file magic")), }; Ok(kind) diff --git a/src/read/xcoff/comdat.rs b/src/read/xcoff/comdat.rs new file mode 100644 index 00000000..4c640d42 --- /dev/null +++ b/src/read/xcoff/comdat.rs @@ -0,0 +1,130 @@ +//! XCOFF doesn't support the COMDAT section. + +use core::fmt::Debug; + +use crate::xcoff; + +use crate::read::{self, ComdatKind, ObjectComdat, ReadRef, Result, SectionIndex, SymbolIndex}; + +use super::{FileHeader, XcoffFile}; + +/// An iterator over the COMDAT section groups of a `XcoffFile32`. +pub type XcoffComdatIterator32<'data, 'file, R = &'data [u8]> = + XcoffComdatIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the COMDAT section groups of a `XcoffFile64`. +pub type XcoffComdatIterator64<'data, 'file, R = &'data [u8]> = + XcoffComdatIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the COMDAT section groups of a `XcoffFile`. +#[derive(Debug)] +pub struct XcoffComdatIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type Item = XcoffComdat<'data, 'file, Xcoff, R>; + + #[inline] + fn next(&mut self) -> Option { + None + } +} + +/// A COMDAT section group of a `XcoffFile32`. +pub type XcoffComdat32<'data, 'file, R = &'data [u8]> = + XcoffComdat<'data, 'file, xcoff::FileHeader32, R>; + +/// A COMDAT section group of a `XcoffFile64`. +pub type XcoffComdat64<'data, 'file, R = &'data [u8]> = + XcoffComdat<'data, 'file, xcoff::FileHeader64, R>; + +/// A COMDAT section group of a `XcoffFile`. +#[derive(Debug)] +pub struct XcoffComdat<'data, 'file, Xcoff, R = &'data [u8]> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffComdat<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ +} + +impl<'data, 'file, Xcoff, R> ObjectComdat<'data> for XcoffComdat<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type SectionIterator = XcoffComdatSectionIterator<'data, 'file, Xcoff, R>; + + #[inline] + fn kind(&self) -> ComdatKind { + unreachable!(); + } + + #[inline] + fn symbol(&self) -> SymbolIndex { + unreachable!(); + } + + #[inline] + fn name_bytes(&self) -> Result<&[u8]> { + unreachable!(); + } + + #[inline] + fn name(&self) -> Result<&str> { + unreachable!(); + } + + #[inline] + fn sections(&self) -> Self::SectionIterator { + unreachable!(); + } +} + +/// An iterator over the sections in a COMDAT section group of a `XcoffFile32`. +pub type XcoffComdatSectionIterator32<'data, 'file, R = &'data [u8]> = + XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the sections in a COMDAT section group of a `XcoffFile64`. +pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> = + XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the sections in a COMDAT section group of a `XcoffFile`. +#[derive(Debug)] +pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatSectionIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type Item = SectionIndex; + + fn next(&mut self) -> Option { + None + } +} diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs new file mode 100644 index 00000000..32564d1b --- /dev/null +++ b/src/read/xcoff/file.rs @@ -0,0 +1,390 @@ +use core::fmt::Debug; + +use alloc::vec::Vec; + +use crate::read::{self, Error, NoDynamicRelocationIterator, Object, ReadError, ReadRef, Result}; + +use crate::{ + xcoff, Architecture, BigEndian as BE, ObjectKind, ObjectSection, Pod, SectionIndex, SymbolIndex, FileFlags, +}; + +use super::{ + Rel, SectionHeader, SectionTable, Symbol, SymbolTable, XcoffComdat, XcoffComdatIterator, + XcoffSection, XcoffSectionIterator, XcoffSegment, XcoffSegmentIterator, XcoffSymbol, + XcoffSymbolIterator, XcoffSymbolTable, +}; + +/// A 32-bit XCOFF object file. +pub type XcoffFile32<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader32, R>; +/// A 64-bit XCOFF object file. +pub type XcoffFile64<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader64, R>; + +/// A partially parsed XCOFF file. +/// +/// Most of the functionality of this type is provided by the `Object` trait implementation. +#[derive(Debug)] +pub struct XcoffFile<'data, Xcoff, R = &'data [u8]> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(super) data: R, + pub(super) header: &'data Xcoff, + pub(super) sections: SectionTable<'data, Xcoff>, + pub(super) symbols: SymbolTable<'data, Xcoff, R>, +} + +impl<'data, Xcoff, R> XcoffFile<'data, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + /// Parse the raw XCOFF file data. + pub fn parse(data: R) -> Result { + let mut offset = 0; + let header = Xcoff::parse(data, &mut offset)?; + let sections = header.sections(data, &mut offset)?; + let symbols = header.symbols(data)?; + Ok(XcoffFile { + data, + header, + sections, + symbols, + }) + } + + /// Returns the raw data. + pub fn data(&self) -> R { + self.data + } + + /// Returns the raw XCOFF file header. + pub fn raw_header(&self) -> &'data Xcoff { + self.header + } +} + +impl<'data, Xcoff, R> read::private::Sealed for XcoffFile<'data, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ +} + +impl<'data, 'file, Xcoff, R> Object<'data, 'file> for XcoffFile<'data, Xcoff, R> +where + 'data: 'file, + Xcoff: FileHeader, + R: 'file + ReadRef<'data>, +{ + type Segment = XcoffSegment<'data, 'file, Xcoff, R>; + type SegmentIterator = XcoffSegmentIterator<'data, 'file, Xcoff, R>; + type Section = XcoffSection<'data, 'file, Xcoff, R>; + type SectionIterator = XcoffSectionIterator<'data, 'file, Xcoff, R>; + type Comdat = XcoffComdat<'data, 'file, Xcoff, R>; + type ComdatIterator = XcoffComdatIterator<'data, 'file, Xcoff, R>; + type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>; + type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>; + type SymbolTable = XcoffSymbolTable<'data, 'file, Xcoff, R>; + type DynamicRelocationIterator = NoDynamicRelocationIterator; + + fn architecture(&self) -> crate::Architecture { + if self.is_64() { + Architecture::PowerPc64 + } else { + Architecture::PowerPc + } + } + + fn is_little_endian(&self) -> bool { + false + } + + fn is_64(&self) -> bool { + self.header.is_type_64() + } + + fn kind(&self) -> ObjectKind { + ObjectKind::Relocatable + } + + fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> { + unreachable!() + } + + fn section_by_name_bytes( + &'file self, + section_name: &[u8], + ) -> Option> { + self.sections() + .find(|section| section.name_bytes() == Ok(section_name)) + } + + fn section_by_index( + &'file self, + index: SectionIndex, + ) -> read::Result> { + let section = self.sections.section(index)?; + Ok(XcoffSection { + file: self, + section, + index, + }) + } + + fn sections(&'file self) -> XcoffSectionIterator<'data, 'file, Xcoff, R> { + XcoffSectionIterator { + file: self, + iter: self.sections.iter().enumerate(), + } + } + + fn comdats(&'file self) -> XcoffComdatIterator<'data, 'file, Xcoff, R> { + unreachable!(); + } + + fn symbol_table(&'file self) -> Option> { + if self.symbols.is_empty() { + return None; + } + Some(XcoffSymbolTable { + symbols: &self.symbols, + file: self, + }) + } + + fn symbol_by_index( + &'file self, + index: SymbolIndex, + ) -> read::Result> { + let symbol = self.symbols.symbol(index.0)?; + Ok(XcoffSymbol { + symbols: &self.symbols, + index, + symbol, + file: self, + }) + } + + fn symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> { + XcoffSymbolIterator { + symbols: &self.symbols, + index: 0, + file: self, + } + } + + fn dynamic_symbol_table(&'file self) -> Option> { + None + } + + fn dynamic_symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> { + XcoffSymbolIterator { + file: self, + symbols: &self.symbols, + // Hack: don't return any. + index: self.symbols.len(), + } + } + + fn dynamic_relocations(&'file self) -> Option { + None + } + + fn imports(&self) -> Result>> { + // TODO: not needed yet. + Ok(Vec::new()) + } + + fn exports(&self) -> Result>> { + // TODO: not needed yet. + Ok(Vec::new()) + } + + fn has_debug_symbols(&self) -> bool { + self.section_by_name(".debug").is_some() || self.section_by_name(".dw").is_some() + } + + fn relative_address_base(&'file self) -> u64 { + 0 + } + + fn entry(&'file self) -> u64 { + // TODO: get from the auxiliary file header. + 0 + } + + fn flags(&self) -> FileFlags { + FileFlags::Xcoff { + f_flags: self.header.f_flags() + } + } +} + +/// A trait for generic access to `FileHeader32` and `FileHeader64`. +#[allow(missing_docs)] +pub trait FileHeader: Debug + Pod { + type Word: Into; + type AuxHeader: AuxHeader; + type SectionHeader: SectionHeader; + type Symbol: Symbol; + type Rel: Rel; + + /// Return true if this type is a 64-bit header. + fn is_type_64(&self) -> bool; + + fn f_magic(&self) -> u16; + fn f_nscns(&self) -> u16; + fn f_timdat(&self) -> u32; + fn f_symptr(&self) -> Self::Word; + fn f_nsyms(&self) -> u32; + fn f_opthdr(&self) -> u16; + fn f_flags(&self) -> u16; + + // Provided methods. + + /// Read the file header. + /// + /// Also checks that the magic field in the file header is a supported format. + fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> read::Result<&'data Self> { + let header = data + .read::(offset) + .read_error("Invalid XCOFF header size or alignment")?; + if !header.is_supported() { + return Err(Error("Unsupported XCOFF header")); + } + Ok(header) + } + + /// TODO: currently only 64-bit is supported. + fn is_supported(&self) -> bool { + self.is_type_64() + } + + /// Return the slice of auxiliary header. + /// + /// `data` must be the entire file data. + /// `offset` must be after the file header. + fn aux_headers<'data, R: ReadRef<'data>>( + &self, + data: R, + offset: &mut u64, + ) -> read::Result<&'data [Self::AuxHeader]> { + let total_len = self.f_opthdr() as usize; + let single_len = std::mem::size_of::(); + if total_len % single_len != 0 { + return Err(Error("Invalid aux header length")); + } + data.read_slice(offset, total_len / single_len) + .read_error("Invalid XCOFF aux header offset/size/alignment") + } + + /// Read the section table. + #[inline] + fn sections<'data, R: ReadRef<'data>>( + &self, + data: R, + offset: &mut u64, + ) -> Result> { + SectionTable::parse(*self, data, offset) + } + + /// Return the symbol table. + #[inline] + fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> Result> { + SymbolTable::parse(*self, data) + } +} + +impl FileHeader for xcoff::FileHeader32 { + type Word = u32; + type AuxHeader = xcoff::AuxHeader32; + type SectionHeader = xcoff::SectionHeader32; + type Symbol = xcoff::Symbol32; + type Rel = xcoff::Rel32; + + fn is_type_64(&self) -> bool { + false + } + + fn f_magic(&self) -> u16 { + self.f_magic.get(BE) + } + + fn f_nscns(&self) -> u16 { + self.f_nscns.get(BE) + } + + fn f_timdat(&self) -> u32 { + self.f_timdat.get(BE) + } + + fn f_symptr(&self) -> Self::Word { + self.f_symptr.get(BE) + } + + fn f_nsyms(&self) -> u32 { + self.f_nsyms.get(BE) + } + + fn f_opthdr(&self) -> u16 { + self.f_opthdr.get(BE) + } + + fn f_flags(&self) -> u16 { + self.f_flags.get(BE) + } +} + +impl FileHeader for xcoff::FileHeader64 { + type Word = u64; + type AuxHeader = xcoff::AuxHeader64; + type SectionHeader = xcoff::SectionHeader64; + type Symbol = xcoff::Symbol64; + type Rel = xcoff::Rel64; + + fn is_type_64(&self) -> bool { + true + } + + fn f_magic(&self) -> u16 { + self.f_magic.get(BE) + } + + fn f_nscns(&self) -> u16 { + self.f_nscns.get(BE) + } + + fn f_timdat(&self) -> u32 { + self.f_timdat.get(BE) + } + + fn f_symptr(&self) -> Self::Word { + self.f_symptr.get(BE) + } + + fn f_nsyms(&self) -> u32 { + self.f_nsyms.get(BE) + } + + fn f_opthdr(&self) -> u16 { + self.f_opthdr.get(BE) + } + + fn f_flags(&self) -> u16 { + self.f_flags.get(BE) + } +} + +#[allow(missing_docs)] +pub trait AuxHeader: Debug + Pod { + type Word: Into; +} + +impl AuxHeader for xcoff::AuxHeader32 { + type Word = u32; +} + +impl AuxHeader for xcoff::AuxHeader64 { + type Word = u64; +} diff --git a/src/read/xcoff/mod.rs b/src/read/xcoff/mod.rs new file mode 100644 index 00000000..136e3107 --- /dev/null +++ b/src/read/xcoff/mod.rs @@ -0,0 +1,21 @@ +//! Support for reading AIX XCOFF files. +//! +//! Provides `XcoffFile` and related types which implement the `Object` trait. + +mod file; +pub use file::*; + +mod section; +pub use section::*; + +mod symbol; +pub use symbol::*; + +mod relocation; +pub use relocation::*; + +mod comdat; +pub use comdat::*; + +mod segment; +pub use segment::*; diff --git a/src/read/xcoff/relocation.rs b/src/read/xcoff/relocation.rs new file mode 100644 index 00000000..42b74335 --- /dev/null +++ b/src/read/xcoff/relocation.rs @@ -0,0 +1,63 @@ +use alloc::fmt; +use core::fmt::Debug; + +use crate::pod::Pod; +use crate::{xcoff, Relocation}; + +use crate::read::ReadRef; + +use super::{FileHeader, XcoffFile}; + +/// An iterator over the relocations in a `XcoffSection32`. +pub type XcoffRelocationIterator32<'data, 'file, R = &'data [u8]> = + XcoffRelocationIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the relocations in a `XcoffSection64`. +pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> = + XcoffRelocationIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the relocations in a `XcoffSection`. +pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + pub(super) file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> Iterator for XcoffRelocationIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type Item = (u64, Relocation); + + fn next(&mut self) -> Option { + None + } +} + +impl<'data, 'file, Xcoff, R> fmt::Debug for XcoffRelocationIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("XcoffRelocationIterator").finish() + } +} + +/// A trait for generic access to `Rel32` and `Rel64`. +#[allow(missing_docs)] +pub trait Rel: Debug + Pod { + type Word: Into; +} + +impl Rel for xcoff::Rel32 { + type Word = u32; +} + +impl Rel for xcoff::Rel64 { + type Word = u64; +} diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs new file mode 100644 index 00000000..d824d6ad --- /dev/null +++ b/src/read/xcoff/section.rs @@ -0,0 +1,381 @@ +use core::fmt::Debug; +use core::{iter, result, slice, str}; + +use crate::{CompressedFileRange, xcoff, BigEndian as BE, Pod, SectionFlags, SectionKind, CompressedData}; + +use crate::read::{self, ObjectSection, ReadError, ReadRef, Result, SectionIndex}; + +use super::{FileHeader, XcoffFile, XcoffRelocationIterator}; + +/// An iterator over the sections of an `XcoffFile32`. +pub type XcoffSectionIterator32<'data, 'file, R = &'data [u8]> = + XcoffSectionIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the sections of an `XcoffFile64`. +pub type XcoffSectionIterator64<'data, 'file, R = &'data [u8]> = + XcoffSectionIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the sections of an `XcoffFile`. +#[derive(Debug)] +pub struct XcoffSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(super) file: &'file XcoffFile<'data, Xcoff, R>, + pub(super) iter: iter::Enumerate>, +} + +impl<'data, 'file, Xcoff, R> Iterator for XcoffSectionIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type Item = XcoffSection<'data, 'file, Xcoff, R>; + + fn next(&mut self) -> Option { + self.iter.next().map(|(index, section)| XcoffSection { + index: SectionIndex(index), + file: self.file, + section, + }) + } +} + +/// A section of an `XcoffFile32`. +pub type XcoffSection32<'data, 'file, R = &'data [u8]> = + XcoffSection<'data, 'file, xcoff::FileHeader32, R>; +/// A section of an `XcoffFile64`. +pub type XcoffSection64<'data, 'file, R = &'data [u8]> = + XcoffSection<'data, 'file, xcoff::FileHeader64, R>; + +/// A section of an `XcoffFile`. +#[derive(Debug)] +pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(super) file: &'file XcoffFile<'data, Xcoff, R>, + pub(super) section: &'data Xcoff::SectionHeader, + pub(super) index: SectionIndex, +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> XcoffSection<'data, 'file, Xcoff, R> { + fn bytes(&self) -> Result<&'data [u8]> { + self.section + .xcoff_data(self.file.data) + .read_error("Invalid XCOFF section offset or size") + } + + fn section_flags(&self) -> u32 { + self.section.s_flags().into() + } + + pub(super) fn is_section_text(&self) -> bool { + self.section_flags() & (xcoff::STYP_TEXT as u32) != 0 + } + + pub(super) fn is_section_data(&self) -> bool { + let flags = self.section_flags(); + flags & (xcoff::STYP_DATA as u32) != 0 || flags & (xcoff::STYP_TDATA as u32) != 0 + } + + pub(super) fn is_section_bss(&self) -> bool { + let flags = self.section_flags(); + flags & (xcoff::STYP_BSS as u32) != 0 || flags & (xcoff::STYP_TBSS as u32) != 0 + } +} + +impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSection<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ +} + +impl<'data, 'file, Xcoff, R> ObjectSection<'data> for XcoffSection<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type RelocationIterator = XcoffRelocationIterator<'data, 'file, Xcoff, R>; + + fn index(&self) -> SectionIndex { + self.index + } + + fn address(&self) -> u64 { + self.section.s_paddr().into() + } + + fn size(&self) -> u64 { + self.section.s_size().into() + } + + fn align(&self) -> u64 { + // TODO: return the alignment for different sections. + 4 + } + + fn file_range(&self) -> Option<(u64, u64)> { + self.section.file_range() + } + + fn data(&self) -> Result<&'data [u8]> { + self.bytes() + } + + fn data_range(&self, address: u64, size: u64) -> Result> { + Ok(read::util::data_range( + self.bytes()?, + self.address(), + address, + size, + )) + } + + fn compressed_file_range(&self) -> Result { + Ok(CompressedFileRange::none(self.file_range())) + } + + fn compressed_data(&self) -> Result> { + self.data().map(CompressedData::none) + } + + fn name_bytes(&self) -> read::Result<&[u8]> { + Ok(self.section.name()) + } + + fn name(&self) -> read::Result<&str> { + let name = self.name_bytes()?; + str::from_utf8(name) + .ok() + .read_error("Non UTF-8 XCOFF section name") + } + + fn segment_name_bytes(&self) -> Result> { + Ok(None) + } + + fn segment_name(&self) -> Result> { + Ok(None) + } + + fn kind(&self) -> SectionKind { + // TODO: return the section kind. + SectionKind::Text + } + + fn relocations(&self) -> Self::RelocationIterator { + // TODO: relocations are not fully supported. + unreachable!() + } + + fn flags(&self) -> SectionFlags { + SectionFlags::Xcoff { + s_flags: self.section.s_flags().into(), + } + } + + fn uncompressed_data(&self) -> Result> { + self.compressed_data()?.decompress() + } +} + +/// The table of section headers in an XCOFF file. +#[derive(Debug, Clone, Copy)] +pub struct SectionTable<'data, Xcoff: FileHeader> { + sections: &'data [Xcoff::SectionHeader], +} + +impl<'data, Xcoff> Default for SectionTable<'data, Xcoff> +where + Xcoff: FileHeader, +{ + fn default() -> Self { + Self { sections: &[] } + } +} + +impl<'data, Xcoff> SectionTable<'data, Xcoff> +where + Xcoff: FileHeader, +{ + /// Parse the section table. + /// + /// `data` must be the entire file data. + /// `offset` must be after the optional file header. + pub fn parse>(header: Xcoff, data: R, offset: &mut u64) -> Result { + let section_num = header.f_nscns(); + if section_num == 0 { + return Ok(SectionTable::default()); + } + let sections = data + .read_slice(offset, section_num as usize) + .read_error("Invalid XCOFF section headers")?; + Ok(SectionTable { sections }) + } + + /// Iterate over the section headers. + #[inline] + pub fn iter(&self) -> slice::Iter<'data, Xcoff::SectionHeader> { + self.sections.iter() + } + + /// Return true if the section table is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.sections.is_empty() + } + + /// The number of section headers. + #[inline] + pub fn len(&self) -> usize { + self.sections.len() + } + + /// Return the section header at the given index. + pub fn section(&self, index: SectionIndex) -> read::Result<&'data Xcoff::SectionHeader> { + self.sections + .get(index.0) + .read_error("Invalid XCOFF section index") + } +} + +/// A trait for generic access to `SectionHeader32` and `SectionHeader64`. +#[allow(missing_docs)] +pub trait SectionHeader: Debug + Pod { + type Word: Into; + type HalfWord: Into; + type Xcoff: FileHeader; + + fn s_name(&self) -> &[u8; 8]; + fn s_paddr(&self) -> Self::Word; + fn s_vaddr(&self) -> Self::Word; + fn s_size(&self) -> Self::Word; + fn s_scnptr(&self) -> Self::Word; + fn s_relptr(&self) -> Self::Word; + fn s_lnnoptr(&self) -> Self::Word; + fn s_nreloc(&self) -> Self::HalfWord; + fn s_nlnno(&self) -> Self::HalfWord; + fn s_flags(&self) -> Self::HalfWord; + + /// Return the section name. + fn name(&self) -> &[u8] { + let sectname = &self.s_name()[..]; + match memchr::memchr(b'\0', sectname) { + Some(end) => §name[..end], + None => sectname, + } + } + + /// Return the offset and size of the section in the file. + fn file_range(&self) -> Option<(u64, u64)> { + Some((self.s_scnptr().into(), self.s_size().into())) + } + + /// Return the section data. + /// + /// Returns `Ok(&[])` if the section has no data. + /// Returns `Err` for invalid values. + fn xcoff_data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> { + if let Some((offset, size)) = self.file_range() { + data.read_bytes_at(offset.into(), size.into()) + } else { + Ok(&[]) + } + } +} + +impl SectionHeader for xcoff::SectionHeader32 { + type Word = u32; + type HalfWord = u16; + type Xcoff = xcoff::FileHeader32; + + fn s_name(&self) -> &[u8; 8] { + &self.s_name + } + + fn s_paddr(&self) -> Self::Word { + self.s_paddr.get(BE) + } + + fn s_vaddr(&self) -> Self::Word { + self.s_vaddr.get(BE) + } + + fn s_size(&self) -> Self::Word { + self.s_size.get(BE) + } + + fn s_scnptr(&self) -> Self::Word { + self.s_scnptr.get(BE) + } + + fn s_relptr(&self) -> Self::Word { + self.s_relptr.get(BE) + } + + fn s_lnnoptr(&self) -> Self::Word { + self.s_lnnoptr.get(BE) + } + + fn s_nreloc(&self) -> Self::HalfWord { + self.s_nreloc.get(BE) + } + + fn s_nlnno(&self) -> Self::HalfWord { + self.s_nlnno.get(BE) + } + + fn s_flags(&self) -> Self::HalfWord { + self.s_flags.get(BE) + } +} + +impl SectionHeader for xcoff::SectionHeader64 { + type Word = u64; + type HalfWord = u32; + type Xcoff = xcoff::FileHeader64; + + fn s_name(&self) -> &[u8; 8] { + &self.s_name + } + + fn s_paddr(&self) -> Self::Word { + self.s_paddr.get(BE) + } + + fn s_vaddr(&self) -> Self::Word { + self.s_vaddr.get(BE) + } + + fn s_size(&self) -> Self::Word { + self.s_size.get(BE) + } + + fn s_scnptr(&self) -> Self::Word { + self.s_scnptr.get(BE) + } + + fn s_relptr(&self) -> Self::Word { + self.s_relptr.get(BE) + } + + fn s_lnnoptr(&self) -> Self::Word { + self.s_lnnoptr.get(BE) + } + + fn s_nreloc(&self) -> Self::HalfWord { + self.s_nreloc.get(BE) + } + + fn s_nlnno(&self) -> Self::HalfWord { + self.s_nlnno.get(BE) + } + + fn s_flags(&self) -> Self::HalfWord { + self.s_flags.get(BE) + } +} diff --git a/src/read/xcoff/segment.rs b/src/read/xcoff/segment.rs new file mode 100644 index 00000000..49969438 --- /dev/null +++ b/src/read/xcoff/segment.rs @@ -0,0 +1,115 @@ +//! TODO: Support the segment for XCOFF when auxiliary file header and loader section is ready. + +use core::fmt::Debug; +use core::str; + +use crate::read::{self, ObjectSegment, ReadRef, Result}; +use crate::xcoff; + +use super::{FileHeader, XcoffFile}; + +/// An iterator over the segments of an `XcoffFile32`. +pub type XcoffSegmentIterator32<'data, 'file, R = &'data [u8]> = + XcoffSegmentIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the segments of an `XcoffFile64`. +pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> = + XcoffSegmentIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the segments of an `XcoffFile`. +#[derive(Debug)] +pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + pub(super) file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> Iterator for XcoffSegmentIterator<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + type Item = XcoffSegment<'data, 'file, Xcoff, R>; + + fn next(&mut self) -> Option { + None + } +} + +/// A segment of an `XcoffFile32`. +pub type XcoffSegment32<'data, 'file, R = &'data [u8]> = + XcoffSegment<'data, 'file, xcoff::FileHeader32, R>; +/// A segment of an `XcoffFile64`. +pub type XcoffSegment64<'data, 'file, R = &'data [u8]> = + XcoffSegment<'data, 'file, xcoff::FileHeader64, R>; + +/// A loadable section of an `XcoffFile`. +#[derive(Debug)] +pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + #[allow(unused)] + pub(super) file: &'file XcoffFile<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff, R> XcoffSegment<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ +} + +impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSegment<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ +} + +impl<'data, 'file, Xcoff, R> ObjectSegment<'data> for XcoffSegment<'data, 'file, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + fn address(&self) -> u64 { + unreachable!(); + } + + fn size(&self) -> u64 { + unreachable!(); + } + + fn align(&self) -> u64 { + unreachable!(); + } + + fn file_range(&self) -> (u64, u64) { + unreachable!(); + } + + fn data(&self) -> Result<&'data [u8]> { + unreachable!(); + } + + fn data_range(&self, _address: u64, _size: u64) -> Result> { + unreachable!(); + } + + fn name_bytes(&self) -> Result> { + unreachable!(); + } + + fn name(&self) -> Result> { + unreachable!(); + } + + fn flags(&self) -> crate::SegmentFlags { + unreachable!(); + } +} diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs new file mode 100644 index 00000000..07811b44 --- /dev/null +++ b/src/read/xcoff/symbol.rs @@ -0,0 +1,421 @@ +use alloc::fmt; +use core::fmt::Debug; +use core::str; + +use crate::endian::{BigEndian as BE, U32Bytes}; +use crate::pod::Pod; +use crate::read::util::StringTable; +use crate::{xcoff, Object}; + +use crate::read::{ + self, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex, SymbolFlags, + SymbolIndex, SymbolKind, SymbolScope, SymbolSection, +}; + +use super::{FileHeader, XcoffFile}; + +/// A table of symbol entries in an XCOFF file. +/// +/// Also includes the string table used for the symbol names. +#[derive(Debug)] +pub struct SymbolTable<'data, Xcoff, R = &'data [u8]> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + symbols: &'data [Xcoff::Symbol], + strings: StringTable<'data, R>, +} + +impl<'data, Xcoff, R> Default for SymbolTable<'data, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + fn default() -> Self { + Self { + symbols: &[], + strings: StringTable::default(), + } + } +} + +impl<'data, Xcoff, R> SymbolTable<'data, Xcoff, R> +where + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + /// Parse the symbol table. + pub fn parse(header: Xcoff, data: R) -> Result { + let mut offset = header.f_symptr().into(); + let (symbols, strings) = if offset != 0 { + let symbols = data + .read_slice(&mut offset, header.f_nsyms() as usize) + .read_error("Invalid XCOFF symbol table offset or size")?; + + // Parse the string table. + // Note: don't update data when reading length; the length includes itself. + let length = data + .read_at::>(offset) + .read_error("Missing XCOFF string table")? + .get(BE); + let str_end = offset + .checked_add(length as u64) + .read_error("Invalid XCOFF string table length")?; + let strings = StringTable::new(data, offset, str_end); + + (symbols, strings) + } else { + (&[][..], StringTable::default()) + }; + + Ok(SymbolTable { symbols, strings }) + } + + /// Return the symbol at the given index. + pub fn symbol(&self, index: usize) -> read::Result<&'data Xcoff::Symbol> { + self.symbols + .get(index) + .read_error("Invalid ELF symbol index") + } + + /// Return true if the symbol table is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.symbols.is_empty() + } + + /// The number of symbol table entries. + /// + /// This includes auxiliary symbol table entries. + #[inline] + pub fn len(&self) -> usize { + self.symbols.len() + } +} + +/// A symbol table of an `XcoffFile32`. +pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> = + XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>; +/// A symbol table of an `XcoffFile64`. +pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> = + XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>; + +/// A symbol table of an `XcoffFile`. +#[derive(Debug, Clone, Copy)] +pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, + pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed + for XcoffSymbolTable<'data, 'file, Xcoff, R> +{ +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data> + for XcoffSymbolTable<'data, 'file, Xcoff, R> +{ + type Symbol = XcoffSymbol<'data, 'file, Xcoff, R>; + type SymbolIterator = XcoffSymbolIterator<'data, 'file, Xcoff, R>; + + fn symbols(&self) -> Self::SymbolIterator { + XcoffSymbolIterator { + file: self.file, + symbols: self.symbols, + index: 0, + } + } + + fn symbol_by_index(&self, index: SymbolIndex) -> read::Result { + let symbol = self.symbols.symbol(index.0)?; + Ok(XcoffSymbol { + file: self.file, + symbols: self.symbols, + index, + symbol, + }) + } +} + +/// An iterator over the symbols of an `XcoffFile32`. +pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> = + XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>; +/// An iterator over the symbols of an `XcoffFile64`. +pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> = + XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>; + +/// An iterator over the symbols of an `XcoffFile`. +pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, + pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, + pub(super) index: usize, +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> fmt::Debug + for XcoffSymbolIterator<'data, 'file, Xcoff, R> +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("XcoffSymbolIterator").finish() + } +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator + for XcoffSymbolIterator<'data, 'file, Xcoff, R> +{ + type Item = XcoffSymbol<'data, 'file, Xcoff, R>; + + fn next(&mut self) -> Option { + let index = self.index; + let symbol = self.symbols.symbols.get(index)?; + self.index += 1; + Some(XcoffSymbol { + file: self.file, + symbols: self.symbols, + index: SymbolIndex(index), + symbol, + }) + } +} + +/// A symbol of an `XcoffFile32`. +pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> = + XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>; +/// A symbol of an `XcoffFile64`. +pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> = + XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>; + +/// A symbol of an `XcoffFile`. +#[derive(Debug, Clone, Copy)] +pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]> +where + 'data: 'file, + Xcoff: FileHeader, + R: ReadRef<'data>, +{ + pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, + pub(super) symbols: &'file SymbolTable<'data, Xcoff, R>, + pub(super) index: SymbolIndex, + pub(super) symbol: &'data Xcoff::Symbol, +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> read::private::Sealed + for XcoffSymbol<'data, 'file, Xcoff, R> +{ +} + +impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> + for XcoffSymbol<'data, 'file, Xcoff, R> +{ + #[inline] + fn index(&self) -> SymbolIndex { + self.index + } + + fn name_bytes(&self) -> Result<&'data [u8]> { + self.symbol.name(self.symbols.strings) + } + + fn name(&self) -> Result<&'data str> { + let name = self.name_bytes()?; + str::from_utf8(name) + .ok() + .read_error("Non UTF-8 ELF symbol name") + } + + #[inline] + fn address(&self) -> u64 { + return self.symbol.n_value().into(); + } + + #[inline] + fn size(&self) -> u64 { + // TODO: get the symbol size when the csect auxiliary symbol is supported. + // Most symbols don't have sizes. + 0 + } + + fn kind(&self) -> SymbolKind { + let section = self + .file + .section_by_index(SectionIndex(self.symbol.n_scnum() as usize)) + .unwrap(); + let derived_kind = if section.is_section_text() { + SymbolKind::Text + } else if section.is_section_data() || section.is_section_bss() { + SymbolKind::Data + } else { + SymbolKind::Unknown + }; + + match self.symbol.n_sclass() { + xcoff::C_FILE => SymbolKind::File, + xcoff::C_NULL => SymbolKind::Null, + xcoff::C_GTLS | xcoff::C_STTLS => SymbolKind::Tls, + xcoff::C_DWARF => SymbolKind::Section, + _ => derived_kind, + } + } + + fn section(&self) -> SymbolSection { + // Section number in XCOFF is 1-based index. + // We treat SectionIndex internally 0-based index. + let index = self.symbol.n_scnum() - 1; + SymbolSection::Section(SectionIndex(index as usize)) + } + + #[inline] + fn is_undefined(&self) -> bool { + self.symbol.is_undefined() + } + + #[inline] + fn is_definition(&self) -> bool { + self.symbol.is_definition() + } + + #[inline] + fn is_common(&self) -> bool { + self.symbol.n_sclass() == xcoff::C_EXT && self.symbol.n_scnum() == xcoff::N_UNDEF + } + + #[inline] + fn is_weak(&self) -> bool { + self.symbol.n_sclass() == xcoff::C_WEAKEXT + } + + fn scope(&self) -> SymbolScope { + if self.symbol.n_scnum() == xcoff::N_UNDEF { + SymbolScope::Unknown + } else { + match self.symbol.n_sclass() { + xcoff::C_EXT | xcoff::C_WEAKEXT => { + // TODO: determine if symbol is exported + SymbolScope::Linkage + } + _ => SymbolScope::Compilation, + } + } + } + + #[inline] + fn is_global(&self) -> bool { + match self.symbol.n_sclass() { + xcoff::C_EXT | xcoff::C_WEAKEXT => true, + _ => false, + } + } + + #[inline] + fn is_local(&self) -> bool { + !self.is_global() + } + + #[inline] + fn flags(&self) -> SymbolFlags { + SymbolFlags::None + } +} + +/// A trait for generic access to `Symbol32` and `Symbol64`. +#[allow(missing_docs)] +pub trait Symbol: Debug + Pod { + type Word: Into; + + fn n_value(&self) -> Self::Word; + fn n_offset(&self) -> u32; + fn n_scnum(&self) -> i16; + fn n_type(&self) -> u16; + fn n_sclass(&self) -> u8; + fn n_numaux(&self) -> u8; + + /// Parse the symbol name from the string table. + fn name<'data, R: ReadRef<'data>>( + &self, + strings: StringTable<'data, R>, + ) -> read::Result<&'data [u8]> { + strings + .get(self.n_offset()) + .read_error("Invalid XCOFF symbol name offset") + } + + /// Return true if the symbol is undefined. + #[inline] + fn is_undefined(&self) -> bool { + let n_sclass = self.n_sclass(); + (n_sclass == xcoff::C_EXT || n_sclass == xcoff::C_WEAKEXT) + && self.n_scnum() == xcoff::N_UNDEF + } + + /// Return true if the symbol is a definition of a function or data object. + /// TODO: get the x_smtyp value when csect auxiliary symbol is supported. + fn is_definition(&self) -> bool { + self.n_scnum() != xcoff::N_UNDEF + } +} + +impl Symbol for xcoff::Symbol64 { + type Word = u64; + + fn n_value(&self) -> Self::Word { + self.n_value.get(BE) + } + + fn n_offset(&self) -> u32 { + self.n_offset.get(BE) + } + + fn n_scnum(&self) -> i16 { + self.n_scnum.get(BE) + } + + fn n_type(&self) -> u16 { + self.n_type.get(BE) + } + + fn n_sclass(&self) -> u8 { + self.n_sclass + } + + fn n_numaux(&self) -> u8 { + self.n_numaux + } +} + +impl Symbol for xcoff::Symbol32 { + type Word = u32; + + fn n_value(&self) -> Self::Word { + self.n_value.get(BE) + } + + fn n_offset(&self) -> u32 { + 0 + } + + fn n_scnum(&self) -> i16 { + self.n_scnum.get(BE) + } + + fn n_type(&self) -> u16 { + self.n_type.get(BE) + } + + fn n_sclass(&self) -> u8 { + self.n_sclass + } + + fn n_numaux(&self) -> u8 { + self.n_numaux + } +} diff --git a/src/xcoff.rs b/src/xcoff.rs index 3f055691..e7cdf26f 100644 --- a/src/xcoff.rs +++ b/src/xcoff.rs @@ -336,7 +336,7 @@ pub struct Symbol32 { /// Symbol value; storage class-dependent. pub n_value: U32, /// Section number of symbol. - pub n_scnum: U16, + pub n_scnum: I16, /// Basic and derived type specification. pub n_type: U16, /// Storage class of symbol. @@ -498,6 +498,48 @@ pub const C_EFCN: u8 = 255; /// Reserved. pub const C_TCSYM: u8 = 134; +/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols. +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct CsectAux32 { + /// Section length. + pub x_scnlen: U32, + /// Offset of parameter type-check hash in .typchk section. + pub x_parmhash: U32, + /// .typchk section number. + pub x_snhash: U16, + /// Symbol alignment and type. + pub x_smtyp: u8, + /// Storage mapping class. + pub x_smclas: u8, + /// Reserved. + pub x_stab: U32, + /// x_snstab. + pub x_snstab: U16 +} + +/// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols. +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct CsectAux64 { + /// Low 4 bytes of section length. + pub x_scnlen_lo: U32, + /// Offset of parameter type-check hash in .typchk section. + pub x_parmhash: U32, + /// .typchk section number. + pub x_snhash: U16, + /// Symbol alignment and type. + pub x_smtyp: u8, + /// Storage mapping class. + pub x_smclas: u8, + /// High 4 bytes of section length. + pub x_scnlen_hi: U32, + /// Reserved. + pub pad: u8, + /// Contains _AUX_CSECT; indicates type of auxiliary entry. + pub x_auxtype: u8 +} + /// Relocation table entry #[derive(Debug, Clone, Copy)] #[repr(C)] @@ -584,6 +626,8 @@ unsafe_impl_pod!( SectionHeader64, Symbol32, Symbol64, + CsectAux32, + CsectAux64, Rel32, Rel64, ); From 6afb48bda9599ae579cad389630f449355dd910a Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Thu, 29 Sep 2022 17:03:44 +0800 Subject: [PATCH 02/12] Format code and address comments. --- src/common.rs | 4 ++++ src/read/xcoff/file.rs | 13 ++++++----- src/read/xcoff/section.rs | 47 ++++++++++++++++++++------------------- src/read/xcoff/symbol.rs | 16 ++++++------- src/xcoff.rs | 4 ++-- 5 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/common.rs b/src/common.rs index 722bb90d..bd586fc1 100644 --- a/src/common.rs +++ b/src/common.rs @@ -171,6 +171,10 @@ pub enum SectionKind { /// /// Example ELF sections: `.symtab`, `.strtab`, `.group` Metadata, + /// Information for the system loader. + /// + /// Example XCOFF sections: `.loader` + Loader, /// Some other ELF section type. /// /// This is the `sh_type` field in the section header. diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index 32564d1b..4770c249 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -1,11 +1,13 @@ use core::fmt::Debug; +use core::mem; use alloc::vec::Vec; use crate::read::{self, Error, NoDynamicRelocationIterator, Object, ReadError, ReadRef, Result}; use crate::{ - xcoff, Architecture, BigEndian as BE, ObjectKind, ObjectSection, Pod, SectionIndex, SymbolIndex, FileFlags, + xcoff, Architecture, BigEndian as BE, FileFlags, ObjectKind, ObjectSection, Pod, SectionIndex, + SymbolIndex, }; use super::{ @@ -109,7 +111,7 @@ where } fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> { - unreachable!() + unimplemented!() } fn section_by_name_bytes( @@ -210,13 +212,12 @@ where } fn entry(&'file self) -> u64 { - // TODO: get from the auxiliary file header. - 0 + unimplemented!() } fn flags(&self) -> FileFlags { FileFlags::Xcoff { - f_flags: self.header.f_flags() + f_flags: self.header.f_flags(), } } } @@ -271,7 +272,7 @@ pub trait FileHeader: Debug + Pod { offset: &mut u64, ) -> read::Result<&'data [Self::AuxHeader]> { let total_len = self.f_opthdr() as usize; - let single_len = std::mem::size_of::(); + let single_len = mem::size_of::(); if total_len % single_len != 0 { return Err(Error("Invalid aux header length")); } diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index d824d6ad..9cff1aac 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -1,7 +1,9 @@ use core::fmt::Debug; use core::{iter, result, slice, str}; -use crate::{CompressedFileRange, xcoff, BigEndian as BE, Pod, SectionFlags, SectionKind, CompressedData}; +use crate::{ + xcoff, BigEndian as BE, CompressedData, CompressedFileRange, Pod, SectionFlags, SectionKind, +}; use crate::read::{self, ObjectSection, ReadError, ReadRef, Result, SectionIndex}; @@ -67,24 +69,6 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> XcoffSection<'data, 'fi .xcoff_data(self.file.data) .read_error("Invalid XCOFF section offset or size") } - - fn section_flags(&self) -> u32 { - self.section.s_flags().into() - } - - pub(super) fn is_section_text(&self) -> bool { - self.section_flags() & (xcoff::STYP_TEXT as u32) != 0 - } - - pub(super) fn is_section_data(&self) -> bool { - let flags = self.section_flags(); - flags & (xcoff::STYP_DATA as u32) != 0 || flags & (xcoff::STYP_TDATA as u32) != 0 - } - - pub(super) fn is_section_bss(&self) -> bool { - let flags = self.section_flags(); - flags & (xcoff::STYP_BSS as u32) != 0 || flags & (xcoff::STYP_TBSS as u32) != 0 - } } impl<'data, 'file, Xcoff, R> read::private::Sealed for XcoffSection<'data, 'file, Xcoff, R> @@ -163,13 +147,30 @@ where } fn kind(&self) -> SectionKind { - // TODO: return the section kind. - SectionKind::Text + let section_type = self.section.s_flags().into() as u16; + if section_type & xcoff::STYP_TEXT != 0 { + SectionKind::Text + } else if section_type & xcoff::STYP_DATA != 0 { + SectionKind::Data + } else if section_type & xcoff::STYP_TDATA != 0 { + SectionKind::Tls + } else if section_type & xcoff::STYP_BSS != 0 { + SectionKind::UninitializedData + } else if section_type & xcoff::STYP_TBSS != 0 { + SectionKind::UninitializedTls + } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 { + SectionKind::Debug + } else if section_type & xcoff::STYP_LOADER != 0 { + SectionKind::Loader + } else if section_type & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT) != 0 { + SectionKind::Other + } else { + SectionKind::Unknown + } } fn relocations(&self) -> Self::RelocationIterator { - // TODO: relocations are not fully supported. - unreachable!() + unimplemented!() } fn flags(&self) -> SectionFlags { diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 07811b44..b81dd61c 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -5,7 +5,7 @@ use core::str; use crate::endian::{BigEndian as BE, U32Bytes}; use crate::pod::Pod; use crate::read::util::StringTable; -use crate::{xcoff, Object}; +use crate::{xcoff, Object, ObjectSection, SectionKind}; use crate::read::{ self, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex, SymbolFlags, @@ -76,7 +76,7 @@ where pub fn symbol(&self, index: usize) -> read::Result<&'data Xcoff::Symbol> { self.symbols .get(index) - .read_error("Invalid ELF symbol index") + .read_error("Invalid XCOFF symbol index") } /// Return true if the symbol table is empty. @@ -230,7 +230,7 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> let name = self.name_bytes()?; str::from_utf8(name) .ok() - .read_error("Non UTF-8 ELF symbol name") + .read_error("Non UTF-8 XCOFF symbol name") } #[inline] @@ -250,12 +250,10 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> .file .section_by_index(SectionIndex(self.symbol.n_scnum() as usize)) .unwrap(); - let derived_kind = if section.is_section_text() { - SymbolKind::Text - } else if section.is_section_data() || section.is_section_bss() { - SymbolKind::Data - } else { - SymbolKind::Unknown + let derived_kind = match section.kind() { + SectionKind::Data | SectionKind::Tls | SectionKind::UninitializedData | SectionKind::UninitializedTls => SymbolKind::Data, + SectionKind::Text => SymbolKind::Text, + _ => SymbolKind::Unknown }; match self.symbol.n_sclass() { diff --git a/src/xcoff.rs b/src/xcoff.rs index e7cdf26f..b6527773 100644 --- a/src/xcoff.rs +++ b/src/xcoff.rs @@ -515,7 +515,7 @@ pub struct CsectAux32 { /// Reserved. pub x_stab: U32, /// x_snstab. - pub x_snstab: U16 + pub x_snstab: U16, } /// Csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT symbols. @@ -537,7 +537,7 @@ pub struct CsectAux64 { /// Reserved. pub pad: u8, /// Contains _AUX_CSECT; indicates type of auxiliary entry. - pub x_auxtype: u8 + pub x_auxtype: u8, } /// Relocation table entry From 44bcdd12f047d8436612c725d84b7411b66d86a3 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Wed, 12 Oct 2022 00:34:19 +0800 Subject: [PATCH 03/12] 1. Add the test for the objdump example output. 2. Fix some unimplemented issues. --- .../testfiles/xcoff/base.xcoff.objdump | 31 ++++++++++++++ src/common.rs | 4 -- src/read/xcoff/comdat.rs | 2 +- src/read/xcoff/file.rs | 6 +-- src/read/xcoff/section.rs | 6 +-- src/read/xcoff/symbol.rs | 40 ++++++++++++------- 6 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 crates/examples/testfiles/xcoff/base.xcoff.objdump diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump new file mode 100644 index 00000000..72562c35 --- /dev/null +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -0,0 +1,31 @@ +Format: Xcoff Big-endian 64-bit +Kind: Relocatable +Architecture: PowerPc64 +Flags: Xcoff { f_flags: 0 } +Relative Address Base: 0 +Entry Address: 0 +0: Section { name: ".text", address: 0, size: 68, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } +1: Section { name: ".data", address: 68, size: 20, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } + +Symbols +0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +1: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +2: Symbol { name: "", address: a, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +4: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +6: Symbol { name: "IBM Open XL C/C++ for AIX 17.1.1 (5725-C72, 5765-J18), LLVM version 16.0.0git", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +7: Symbol { name: ".text", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +8: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +10: Symbol { name: "", address: 700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +12: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +13: Symbol { name: "main", address: 68, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +14: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +16: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +18: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } + +Dynamic symbols \ No newline at end of file diff --git a/src/common.rs b/src/common.rs index bd586fc1..722bb90d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -171,10 +171,6 @@ pub enum SectionKind { /// /// Example ELF sections: `.symtab`, `.strtab`, `.group` Metadata, - /// Information for the system loader. - /// - /// Example XCOFF sections: `.loader` - Loader, /// Some other ELF section type. /// /// This is the `sh_type` field in the section header. diff --git a/src/read/xcoff/comdat.rs b/src/read/xcoff/comdat.rs index 4c640d42..eeed2f54 100644 --- a/src/read/xcoff/comdat.rs +++ b/src/read/xcoff/comdat.rs @@ -23,7 +23,7 @@ where R: ReadRef<'data>, { #[allow(unused)] - file: &'file XcoffFile<'data, Xcoff, R>, + pub(crate) file: &'file XcoffFile<'data, Xcoff, R>, } impl<'data, 'file, Xcoff, R> Iterator for XcoffComdatIterator<'data, 'file, Xcoff, R> diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index 4770c249..c33797de 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -111,7 +111,7 @@ where } fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> { - unimplemented!() + XcoffSegmentIterator { file: self } } fn section_by_name_bytes( @@ -142,7 +142,7 @@ where } fn comdats(&'file self) -> XcoffComdatIterator<'data, 'file, Xcoff, R> { - unreachable!(); + XcoffComdatIterator { file: self } } fn symbol_table(&'file self) -> Option> { @@ -212,7 +212,7 @@ where } fn entry(&'file self) -> u64 { - unimplemented!() + 0 } fn flags(&self) -> FileFlags { diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index 9cff1aac..a95ac5a8 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -160,8 +160,6 @@ where SectionKind::UninitializedTls } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 { SectionKind::Debug - } else if section_type & xcoff::STYP_LOADER != 0 { - SectionKind::Loader } else if section_type & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT) != 0 { SectionKind::Other } else { @@ -170,7 +168,9 @@ where } fn relocations(&self) -> Self::RelocationIterator { - unimplemented!() + XcoffRelocationIterator { + file: self.file, + } } fn flags(&self) -> SectionFlags { diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index b81dd61c..bd9ff53b 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -246,30 +246,40 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } fn kind(&self) -> SymbolKind { - let section = self - .file - .section_by_index(SectionIndex(self.symbol.n_scnum() as usize)) - .unwrap(); - let derived_kind = match section.kind() { - SectionKind::Data | SectionKind::Tls | SectionKind::UninitializedData | SectionKind::UninitializedTls => SymbolKind::Data, - SectionKind::Text => SymbolKind::Text, - _ => SymbolKind::Unknown - }; - match self.symbol.n_sclass() { xcoff::C_FILE => SymbolKind::File, xcoff::C_NULL => SymbolKind::Null, xcoff::C_GTLS | xcoff::C_STTLS => SymbolKind::Tls, xcoff::C_DWARF => SymbolKind::Section, - _ => derived_kind, + _ => { + if self.symbol.n_scnum() > 0 { + let section = self + .file + .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize)) + .unwrap(); + match section.kind() { + SectionKind::Data + | SectionKind::Tls + | SectionKind::UninitializedData + | SectionKind::UninitializedTls => SymbolKind::Data, + SectionKind::Text => SymbolKind::Text, + _ => SymbolKind::Unknown, + } + } else { + SymbolKind::Unknown + } + } } } fn section(&self) -> SymbolSection { - // Section number in XCOFF is 1-based index. - // We treat SectionIndex internally 0-based index. - let index = self.symbol.n_scnum() - 1; - SymbolSection::Section(SectionIndex(index as usize)) + match self.symbol.n_scnum() { + xcoff::N_ABS => SymbolSection::Absolute, + xcoff::N_UNDEF => SymbolSection::Undefined, + xcoff::N_DEBUG => SymbolSection::None, + index if index > 0 => SymbolSection::Section(SectionIndex(index as usize)), + _ => SymbolSection::Unknown, + } } #[inline] From 89a9711ec3a53faa4ee883568c0681da98e2b4bf Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Wed, 12 Oct 2022 00:53:10 +0800 Subject: [PATCH 04/12] add a new line for base.xcoff.objdump --- crates/examples/testfiles/xcoff/base.xcoff.objdump | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index 72562c35..83e9166d 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -28,4 +28,4 @@ Symbols 17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } 18: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -Dynamic symbols \ No newline at end of file +Dynamic symbols From 797f3f0583cb98c5715b1cb3d87246e5feb3759d Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Thu, 13 Oct 2022 00:21:11 +0800 Subject: [PATCH 05/12] Update the tests and fmt the code. --- .../examples/testfiles/xcoff/base.o.objdump | 31 +++ .../testfiles/xcoff/base.xcoff.objdump | 183 +++++++++++++++--- src/common.rs | 2 +- src/read/xcoff/section.rs | 4 +- 4 files changed, 194 insertions(+), 26 deletions(-) create mode 100644 crates/examples/testfiles/xcoff/base.o.objdump diff --git a/crates/examples/testfiles/xcoff/base.o.objdump b/crates/examples/testfiles/xcoff/base.o.objdump new file mode 100644 index 00000000..83e9166d --- /dev/null +++ b/crates/examples/testfiles/xcoff/base.o.objdump @@ -0,0 +1,31 @@ +Format: Xcoff Big-endian 64-bit +Kind: Relocatable +Architecture: PowerPc64 +Flags: Xcoff { f_flags: 0 } +Relative Address Base: 0 +Entry Address: 0 +0: Section { name: ".text", address: 0, size: 68, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } +1: Section { name: ".data", address: 68, size: 20, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } + +Symbols +0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +1: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +2: Symbol { name: "", address: a, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +4: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +6: Symbol { name: "IBM Open XL C/C++ for AIX 17.1.1 (5725-C72, 5765-J18), LLVM version 16.0.0git", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +7: Symbol { name: ".text", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +8: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +10: Symbol { name: "", address: 700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +12: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +13: Symbol { name: "main", address: 68, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +14: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +16: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +18: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } + +Dynamic symbols diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index 83e9166d..17811b20 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -1,31 +1,170 @@ Format: Xcoff Big-endian 64-bit Kind: Relocatable Architecture: PowerPc64 -Flags: Xcoff { f_flags: 0 } +Flags: Xcoff { f_flags: 1002 } Relative Address Base: 0 Entry Address: 0 -0: Section { name: ".text", address: 0, size: 68, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } -1: Section { name: ".data", address: 68, size: 20, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } +0: Section { name: "\u{1}\u{b}", address: 1000001f8, size: 1100008b8, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } +1: Section { name: "", address: 110000848, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } +2: Section { name: "", address: 1f8, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } +3: Section { name: "", address: 6cd, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } Symbols -0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -1: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -2: Symbol { name: "", address: a, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -4: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -6: Symbol { name: "IBM Open XL C/C++ for AIX 17.1.1 (5725-C72, 5765-J18), LLVM version 16.0.0git", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -7: Symbol { name: ".text", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -8: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -10: Symbol { name: "", address: 700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -12: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -13: Symbol { name: "main", address: 68, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -14: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -16: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -18: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +1: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +3: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +5: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +7: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +9: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +11: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +13: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +15: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +17: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +19: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +21: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +22: Symbol { name: "__crt0v", address: 110000900, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +23: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +24: Symbol { name: "crt0_data", address: 110000908, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +25: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +26: Symbol { name: "__run_final_dtors", address: 110000910, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +27: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +28: Symbol { name: "_$STATIC", address: 110000918, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +29: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +31: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +32: Symbol { name: "atexit", address: 110000928, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +33: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +34: Symbol { name: "_cdtors", address: 110000930, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +35: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +37: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +38: Symbol { name: "exit", address: 110000940, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +39: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +40: Symbol { name: "__n_pthreads", address: 110000948, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +41: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +42: Symbol { name: "__mod_init", address: 110000950, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +43: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +45: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +46: Symbol { name: "errno", address: 110000960, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +47: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +49: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +50: Symbol { name: "printf", address: 110000970, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +51: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +52: Symbol { name: "", address: 35, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +53: Symbol { name: "crt0_64.s", address: 48, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +55: Symbol { name: "", address: ad00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +57: Symbol { name: "nit_routine", address: 3600000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +58: Symbol { name: "__start", address: 110000848, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +59: Symbol { name: "", address: 1000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +60: Symbol { name: "crt0_data", address: 1100006d0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +61: Symbol { name: "", address: 6800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +62: Symbol { name: "p_xargc", address: 1100008c0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +63: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +64: Symbol { name: "p_xargv", address: 1100008f0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +65: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +67: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +68: Symbol { name: "p_xrc", address: 1100008fc, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +69: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +71: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +72: Symbol { name: ".file", address: 60, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +73: Symbol { name: "", address: 11c, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +74: Symbol { name: "", address: 15b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +75: Symbol { name: "", address: 175, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +76: Symbol { name: "", address: 1000002c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +77: Symbol { name: "", address: 16000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +79: Symbol { name: "nit_routine", address: 4c00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +81: Symbol { name: "nit_routine", address: 4c00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +82: Symbol { name: "_$STATIC", address: 110000738, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +83: Symbol { name: "", address: 5900000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +84: Symbol { name: "__threads_init", address: 110000858, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +85: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +87: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +89: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +91: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +93: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +95: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +96: Symbol { name: ".file", address: 7a, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +97: Symbol { name: "", address: 226, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +98: Symbol { name: "", address: 261, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +99: Symbol { name: "", address: 27b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +100: Symbol { name: "", address: 100000420, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +101: Symbol { name: "", address: 17800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +103: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +105: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +107: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +109: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +110: Symbol { name: "_$STATIC", address: 1100007a0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +111: Symbol { name: "", address: 9500000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } +113: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +115: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +117: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +118: Symbol { name: "_cdtors", address: 110000838, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: true, flags: None } +119: Symbol { name: "", address: 1000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } +121: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +122: Symbol { name: ".file", address: 83, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +123: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +124: Symbol { name: "", address: 319, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +125: Symbol { name: ".text", address: 100000640, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +126: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +127: Symbol { name: ".main", address: 100000640, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +128: Symbol { name: "nit_routine", address: 7d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +130: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +131: Symbol { name: "glink64.s", address: 88, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +133: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +135: Symbol { name: "utine", address: 8400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +136: Symbol { name: "glink64.s", address: 8d, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +138: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +140: Symbol { name: "utine", address: 8900000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +141: Symbol { name: "glink64.s", address: 92, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +143: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +145: Symbol { name: "utine", address: 8e00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +146: Symbol { name: "glink64.s", address: 97, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +148: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +150: Symbol { name: "utine", address: 9300000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +151: Symbol { name: "glink64.s", address: ffffffffffffffff, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } +153: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } +155: Symbol { name: "utine", address: 9800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } Dynamic symbols diff --git a/src/common.rs b/src/common.rs index 722bb90d..d39271d4 100644 --- a/src/common.rs +++ b/src/common.rs @@ -435,7 +435,7 @@ pub enum SectionFlags { Xcoff { /// `s_flags` field in the section header. s_flags: u32, - }, + }, } /// Symbol flags that are specific to each file format. diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index a95ac5a8..2c4d886c 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -168,9 +168,7 @@ where } fn relocations(&self) -> Self::RelocationIterator { - XcoffRelocationIterator { - file: self.file, - } + XcoffRelocationIterator { file: self.file } } fn flags(&self) -> SectionFlags { From 1f6d87ddf08001797522a2efdf036fa135da3315 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Thu, 13 Oct 2022 10:52:05 +0800 Subject: [PATCH 06/12] add a command to build with only the xcoff format feature in CI. --- .github/workflows/rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f8f44055..0e02c551 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -42,6 +42,7 @@ jobs: - run: cargo build --no-default-features --features read_core,write_core,macho - run: cargo build --no-default-features --features read_core,pe - run: cargo build --no-default-features --features read_core,wasm + - run: cargo build --no-default-features --features read_core,xcoff - run: cargo build --no-default-features --features doc cross: From f82ada591dfda28bf0256e12825cdd10f673cfcc Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Mon, 17 Oct 2022 13:24:06 +0800 Subject: [PATCH 07/12] Update. Add TODO comments. --- .../testfiles/xcoff/base.xcoff.objdump | 22 ++++++------- src/read/xcoff/file.rs | 33 ++++++++++++++----- src/read/xcoff/section.rs | 13 ++++++-- src/read/xcoff/symbol.rs | 22 +++++++++---- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index 17811b20..dfd7eb8b 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -1,5 +1,5 @@ Format: Xcoff Big-endian 64-bit -Kind: Relocatable +Kind: Executable Architecture: PowerPc64 Flags: Xcoff { f_flags: 1002 } Relative Address Base: 0 @@ -62,8 +62,8 @@ Symbols 49: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 50: Symbol { name: "printf", address: 110000970, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } 51: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -52: Symbol { name: "", address: 35, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -53: Symbol { name: "crt0_64.s", address: 48, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 55: Symbol { name: "", address: ad00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } @@ -82,7 +82,7 @@ Symbols 69: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } 71: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -72: Symbol { name: ".file", address: 60, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 73: Symbol { name: "", address: 11c, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 74: Symbol { name: "", address: 15b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 75: Symbol { name: "", address: 175, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } @@ -106,7 +106,7 @@ Symbols 93: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } 95: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -96: Symbol { name: ".file", address: 7a, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 97: Symbol { name: "", address: 226, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 98: Symbol { name: "", address: 261, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 99: Symbol { name: "", address: 27b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } @@ -132,7 +132,7 @@ Symbols 119: Symbol { name: "", address: 1000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } 121: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -122: Symbol { name: ".file", address: 83, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 123: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 124: Symbol { name: "", address: 319, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 125: Symbol { name: ".text", address: 100000640, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } @@ -141,27 +141,27 @@ Symbols 128: Symbol { name: "nit_routine", address: 7d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 130: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -131: Symbol { name: "glink64.s", address: 88, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 133: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } 135: Symbol { name: "utine", address: 8400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -136: Symbol { name: "glink64.s", address: 8d, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 138: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } 140: Symbol { name: "utine", address: 8900000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -141: Symbol { name: "glink64.s", address: 92, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 143: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } 145: Symbol { name: "utine", address: 8e00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -146: Symbol { name: "glink64.s", address: 97, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 148: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } 150: Symbol { name: "utine", address: 9300000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -151: Symbol { name: "glink64.s", address: ffffffffffffffff, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } 153: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index c33797de..5d7d1af9 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -107,7 +107,16 @@ where } fn kind(&self) -> ObjectKind { - ObjectKind::Relocatable + let flags = self.header.f_flags(); + if flags & xcoff::F_EXEC != 0 { + ObjectKind::Executable + } else if flags & xcoff::F_SHROBJ != 0 { + ObjectKind::Dynamic + } else if flags & xcoff::F_RELFLG == 0 { + ObjectKind::Relocatable + } else { + ObjectKind::Unknown + } } fn segments(&'file self) -> XcoffSegmentIterator<'data, 'file, Xcoff, R> { @@ -181,6 +190,7 @@ where } fn dynamic_symbols(&'file self) -> XcoffSymbolIterator<'data, 'file, Xcoff, R> { + // TODO: return the symbols in the STYP_LOADER section. XcoffSymbolIterator { file: self, symbols: &self.symbols, @@ -190,21 +200,22 @@ where } fn dynamic_relocations(&'file self) -> Option { + // TODO: return the relocations in the STYP_LOADER section. None } fn imports(&self) -> Result>> { - // TODO: not needed yet. + // TODO: return the imports in the STYP_LOADER section. Ok(Vec::new()) } fn exports(&self) -> Result>> { - // TODO: not needed yet. + // TODO: return the exports in the STYP_LOADER section. Ok(Vec::new()) } fn has_debug_symbols(&self) -> bool { - self.section_by_name(".debug").is_some() || self.section_by_name(".dw").is_some() + self.section_by_name(".debug").is_some() || self.section_by_name(".dwinfo").is_some() } fn relative_address_base(&'file self) -> u64 { @@ -212,6 +223,7 @@ where } fn entry(&'file self) -> u64 { + // TODO: return the o_entry in the auxiliary header. 0 } @@ -271,12 +283,15 @@ pub trait FileHeader: Debug + Pod { data: R, offset: &mut u64, ) -> read::Result<&'data [Self::AuxHeader]> { - let total_len = self.f_opthdr() as usize; - let single_len = mem::size_of::(); - if total_len % single_len != 0 { + let ahsize = self.f_opthdr() as usize; + if ahsize == 0 { + // No program headers is ok. + return Ok(&[]); + } + if ahsize > mem::size_of::() { return Err(Error("Invalid aux header length")); } - data.read_slice(offset, total_len / single_len) + data.read_slice(offset, ahsize) .read_error("Invalid XCOFF aux header offset/size/alignment") } @@ -287,7 +302,7 @@ pub trait FileHeader: Debug + Pod { data: R, offset: &mut u64, ) -> Result> { - SectionTable::parse(*self, data, offset) + SectionTable::parse(self, data, offset) } /// Return the symbol table. diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index 2c4d886c..552f6f1f 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -160,7 +160,16 @@ where SectionKind::UninitializedTls } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 { SectionKind::Debug - } else if section_type & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT) != 0 { + } else if section_type & xcoff::STYP_LOADER != 0 { + SectionKind::Metadata + } else if section_type + & (xcoff::STYP_INFO + | xcoff::STYP_EXCEPT + | xcoff::STYP_PAD + | xcoff::STYP_TYPCHK + | xcoff::STYP_OVRFLO) + != 0 + { SectionKind::Other } else { SectionKind::Unknown @@ -205,7 +214,7 @@ where /// /// `data` must be the entire file data. /// `offset` must be after the optional file header. - pub fn parse>(header: Xcoff, data: R, offset: &mut u64) -> Result { + pub fn parse>(header: &Xcoff, data: R, offset: &mut u64) -> Result { let section_num = header.f_nscns(); if section_num == 0 { return Ok(SectionTable::default()); diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index bd9ff53b..0a1418bb 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -235,7 +235,19 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn address(&self) -> u64 { - return self.symbol.n_value().into(); + match self.symbol.n_sclass() { + xcoff::C_GSYM + | xcoff::C_BCOMM + | xcoff::C_DECL + | xcoff::C_ENTRY + | xcoff::C_ESTAT + | xcoff::C_ECOMM + | xcoff::C_FILE + | xcoff::C_BSTAT + | xcoff::C_RPSYM + | xcoff::C_RSYM => 0, + _ => self.symbol.n_value().into(), + } } #[inline] @@ -250,7 +262,6 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> xcoff::C_FILE => SymbolKind::File, xcoff::C_NULL => SymbolKind::Null, xcoff::C_GTLS | xcoff::C_STTLS => SymbolKind::Tls, - xcoff::C_DWARF => SymbolKind::Section, _ => { if self.symbol.n_scnum() > 0 { let section = self @@ -258,10 +269,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize)) .unwrap(); match section.kind() { - SectionKind::Data - | SectionKind::Tls - | SectionKind::UninitializedData - | SectionKind::UninitializedTls => SymbolKind::Data, + SectionKind::Data | SectionKind::UninitializedData => SymbolKind::Data, + SectionKind::UninitializedTls | SectionKind::Tls => SymbolKind::Tls, SectionKind::Text => SymbolKind::Text, _ => SymbolKind::Unknown, } @@ -408,6 +417,7 @@ impl Symbol for xcoff::Symbol32 { } fn n_offset(&self) -> u32 { + // TODO: this should be `n_name` field instead of `n_offset`. 0 } From f787920e7e595170c50295309800be072667b663 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Tue, 18 Oct 2022 14:08:55 +0800 Subject: [PATCH 08/12] Support 32-bit object file and addressed comments. --- .../examples/testfiles/xcoff/base32.o.objdump | 93 +++++++++++++++++++ .../testfiles/xcoff/base32.xcoff.objdump | 0 src/read/xcoff/file.rs | 27 +----- src/read/xcoff/relocation.rs | 1 + src/read/xcoff/section.rs | 12 +-- src/read/xcoff/symbol.rs | 82 +++++++++------- src/xcoff.rs | 24 +++-- 7 files changed, 166 insertions(+), 73 deletions(-) create mode 100644 crates/examples/testfiles/xcoff/base32.o.objdump create mode 100644 crates/examples/testfiles/xcoff/base32.xcoff.objdump diff --git a/crates/examples/testfiles/xcoff/base32.o.objdump b/crates/examples/testfiles/xcoff/base32.o.objdump new file mode 100644 index 00000000..bc62559b --- /dev/null +++ b/crates/examples/testfiles/xcoff/base32.o.objdump @@ -0,0 +1,93 @@ +Format: Xcoff Big-endian 64-bit +Kind: Executable +Architecture: PowerPc64 +Flags: Xcoff { f_flags: 1002 } +Relative Address Base: 0 +Entry Address: 0 +0: Section { name: ".text", address: 1000001f8, size: 4d5, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } +1: Section { name: ".data", address: 1100006cd, size: 2ab, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } +2: Section { name: ".bss", address: 110000978, size: 0, align: 4, kind: UninitializedData, flags: Xcoff { s_flags: 80 } } +3: Section { name: ".loader", address: 0, size: 485, align: 4, kind: Metadata, flags: Xcoff { s_flags: 1000 } } + +Symbols +0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +22: Symbol { name: "__crt0v", address: 110000900, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +24: Symbol { name: "crt0_data", address: 110000908, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +26: Symbol { name: "__run_final_dtors", address: 110000910, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +28: Symbol { name: "_$STATIC", address: 110000918, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +32: Symbol { name: "atexit", address: 110000928, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +34: Symbol { name: "_cdtors", address: 110000930, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +38: Symbol { name: "exit", address: 110000940, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +40: Symbol { name: "__n_pthreads", address: 110000948, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +42: Symbol { name: "__mod_init", address: 110000950, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +46: Symbol { name: "errno", address: 110000960, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +50: Symbol { name: "printf", address: 110000970, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +58: Symbol { name: "__start", address: 110000848, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +60: Symbol { name: "crt0_data", address: 1100006d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +62: Symbol { name: "p_xargc", address: 1100008c0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +64: Symbol { name: "p_xargv", address: 1100008f0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +68: Symbol { name: "p_xrc", address: 1100008fc, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +76: Symbol { name: "", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +82: Symbol { name: "_$STATIC", address: 110000738, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +84: Symbol { name: "__threads_init", address: 110000858, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +100: Symbol { name: "", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +110: Symbol { name: "_$STATIC", address: 1100007a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +118: Symbol { name: "_cdtors", address: 110000838, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } +120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +125: Symbol { name: ".text", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +127: Symbol { name: ".main", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } + +Dynamic symbols diff --git a/crates/examples/testfiles/xcoff/base32.xcoff.objdump b/crates/examples/testfiles/xcoff/base32.xcoff.objdump new file mode 100644 index 00000000..e69de29b diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index 5d7d1af9..4177ec21 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -1,5 +1,4 @@ use core::fmt::Debug; -use core::mem; use alloc::vec::Vec; @@ -45,6 +44,8 @@ where pub fn parse(data: R) -> Result { let mut offset = 0; let header = Xcoff::parse(data, &mut offset)?; + // TODO: skip over the auxiliary header for now. + offset += header.f_opthdr() as u64; let sections = header.sections(data, &mut offset)?; let symbols = header.symbols(data)?; Ok(XcoffFile { @@ -269,30 +270,8 @@ pub trait FileHeader: Debug + Pod { Ok(header) } - /// TODO: currently only 64-bit is supported. fn is_supported(&self) -> bool { - self.is_type_64() - } - - /// Return the slice of auxiliary header. - /// - /// `data` must be the entire file data. - /// `offset` must be after the file header. - fn aux_headers<'data, R: ReadRef<'data>>( - &self, - data: R, - offset: &mut u64, - ) -> read::Result<&'data [Self::AuxHeader]> { - let ahsize = self.f_opthdr() as usize; - if ahsize == 0 { - // No program headers is ok. - return Ok(&[]); - } - if ahsize > mem::size_of::() { - return Err(Error("Invalid aux header length")); - } - data.read_slice(offset, ahsize) - .read_error("Invalid XCOFF aux header offset/size/alignment") + self.f_magic() == xcoff::MAGIC_64 || self.f_magic() == xcoff::MAGIC_32 } /// Read the section table. diff --git a/src/read/xcoff/relocation.rs b/src/read/xcoff/relocation.rs index 42b74335..c227b71a 100644 --- a/src/read/xcoff/relocation.rs +++ b/src/read/xcoff/relocation.rs @@ -34,6 +34,7 @@ where type Item = (u64, Relocation); fn next(&mut self) -> Option { + // TODO: return the relocations in the section. None } } diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index 552f6f1f..d4c5c01d 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -66,7 +66,7 @@ where impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> XcoffSection<'data, 'file, Xcoff, R> { fn bytes(&self) -> Result<&'data [u8]> { self.section - .xcoff_data(self.file.data) + .data(self.file.data) .read_error("Invalid XCOFF section offset or size") } } @@ -160,14 +160,10 @@ where SectionKind::UninitializedTls } else if section_type & (xcoff::STYP_DEBUG | xcoff::STYP_DWARF) != 0 { SectionKind::Debug - } else if section_type & xcoff::STYP_LOADER != 0 { + } else if section_type & (xcoff::STYP_LOADER | xcoff::STYP_OVRFLO) != 0 { SectionKind::Metadata } else if section_type - & (xcoff::STYP_INFO - | xcoff::STYP_EXCEPT - | xcoff::STYP_PAD - | xcoff::STYP_TYPCHK - | xcoff::STYP_OVRFLO) + & (xcoff::STYP_INFO | xcoff::STYP_EXCEPT | xcoff::STYP_PAD | xcoff::STYP_TYPCHK) != 0 { SectionKind::Other @@ -287,7 +283,7 @@ pub trait SectionHeader: Debug + Pod { /// /// Returns `Ok(&[])` if the section has no data. /// Returns `Err` for invalid values. - fn xcoff_data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> { + fn data<'data, R: ReadRef<'data>>(&self, data: R) -> result::Result<&'data [u8], ()> { if let Some((offset, size)) = self.file_range() { data.read_bytes_at(offset.into(), size.into()) } else { diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 0a1418bb..1f37531d 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -1,4 +1,5 @@ use alloc::fmt; +use core::convert::TryInto; use core::fmt::Debug; use core::str; @@ -178,7 +179,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator fn next(&mut self) -> Option { let index = self.index; let symbol = self.symbols.symbols.get(index)?; - self.index += 1; + // TODO: skip over the auxiliary symbols for now. + self.index += 1 + symbol.n_numaux() as usize; Some(XcoffSymbol { file: self.file, symbols: self.symbols, @@ -236,17 +238,14 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn address(&self) -> u64 { match self.symbol.n_sclass() { - xcoff::C_GSYM - | xcoff::C_BCOMM - | xcoff::C_DECL - | xcoff::C_ENTRY - | xcoff::C_ESTAT - | xcoff::C_ECOMM - | xcoff::C_FILE - | xcoff::C_BSTAT - | xcoff::C_RPSYM - | xcoff::C_RSYM => 0, - _ => self.symbol.n_value().into(), + // Relocatable address. + xcoff::C_EXT + | xcoff::C_WEAKEXT + | xcoff::C_HIDEXT + | xcoff::C_FCN + | xcoff::C_BLOCK + | xcoff::C_STAT => self.symbol.n_value().into(), + _ => 0, } } @@ -316,9 +315,13 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> SymbolScope::Unknown } else { match self.symbol.n_sclass() { - xcoff::C_EXT | xcoff::C_WEAKEXT => { - // TODO: determine if symbol is exported - SymbolScope::Linkage + xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { + let visbility = self.symbol.n_type() & xcoff::SYM_V_MASK; + if visbility == xcoff::SYM_V_HIDDEN || visbility == xcoff::SYM_V_EXPORTED { + SymbolScope::Linkage + } else { + SymbolScope::Dynamic + } } _ => SymbolScope::Compilation, } @@ -350,21 +353,15 @@ pub trait Symbol: Debug + Pod { type Word: Into; fn n_value(&self) -> Self::Word; - fn n_offset(&self) -> u32; fn n_scnum(&self) -> i16; fn n_type(&self) -> u16; fn n_sclass(&self) -> u8; fn n_numaux(&self) -> u8; - /// Parse the symbol name from the string table. fn name<'data, R: ReadRef<'data>>( - &self, + &'data self, strings: StringTable<'data, R>, - ) -> read::Result<&'data [u8]> { - strings - .get(self.n_offset()) - .read_error("Invalid XCOFF symbol name offset") - } + ) -> Result<&'data [u8]>; /// Return true if the symbol is undefined. #[inline] @@ -388,10 +385,6 @@ impl Symbol for xcoff::Symbol64 { self.n_value.get(BE) } - fn n_offset(&self) -> u32 { - self.n_offset.get(BE) - } - fn n_scnum(&self) -> i16 { self.n_scnum.get(BE) } @@ -407,6 +400,16 @@ impl Symbol for xcoff::Symbol64 { fn n_numaux(&self) -> u8 { self.n_numaux } + + /// Parse the symbol name for XCOFF64. + fn name<'data, R: ReadRef<'data>>( + &'data self, + strings: StringTable<'data, R>, + ) -> Result<&'data [u8]> { + strings + .get(self.n_offset.get(BE)) + .read_error("Invalid XCOFF symbol name offset") + } } impl Symbol for xcoff::Symbol32 { @@ -416,11 +419,6 @@ impl Symbol for xcoff::Symbol32 { self.n_value.get(BE) } - fn n_offset(&self) -> u32 { - // TODO: this should be `n_name` field instead of `n_offset`. - 0 - } - fn n_scnum(&self) -> i16 { self.n_scnum.get(BE) } @@ -436,4 +434,24 @@ impl Symbol for xcoff::Symbol32 { fn n_numaux(&self) -> u8 { self.n_numaux } + + /// Parse the symbol name for XCOFF32. + fn name<'data, R: ReadRef<'data>>( + &'data self, + strings: StringTable<'data, R>, + ) -> Result<&'data [u8]> { + if self.n_name[0] == 0 { + // If the name starts with 0 then the last 4 bytes are a string table offset. + let offset = u32::from_be_bytes(self.n_name[4..8].try_into().unwrap()); + strings + .get(offset) + .read_error("Invalid XCOFF symbol name offset") + } else { + // The name is inline and padded with nulls. + Ok(match memchr::memchr(b'\0', &self.n_name) { + Some(end) => &self.n_name[..end], + None => &self.n_name, + }) + } + } } diff --git a/src/xcoff.rs b/src/xcoff.rs index b6527773..f71fc169 100644 --- a/src/xcoff.rs +++ b/src/xcoff.rs @@ -246,6 +246,8 @@ pub struct SectionHeader32 { pub s_nlnno: U16, /// Flags to define the section type. pub s_flags: U16, + /// Reserved. + pub s_reserve: U16, } /// Section header. @@ -374,14 +376,18 @@ pub const N_UNDEF: i16 = 0; // Vlaues for `n_type`. // -/// External reference. -pub const XTY_ER: u8 = 0; -/// Csect definition for initialized storage. -pub const XTY_SD: u8 = 1; -/// Label definition. Defines an entry point to an initialized csect. -pub const XTY_LD: u8 = 2; -/// Common csect definition. For uninitialized storage. -pub const XTY_CM: u8 = 3; +/// Values for visibility as they would appear when encoded in the high 4 bits +/// of the 16-bit unsigned n_type field of symbol table entries. Valid for +/// 32-bit XCOFF only when the o_vstamp in the auxiliary header is greater than 1. +pub const SYM_V_MASK: u16 = 0xF000; +#[allow(missing_docs)] +pub const SYM_V_INTERNAL: u16 = 0x1000; +#[allow(missing_docs)] +pub const SYM_V_HIDDEN: u16 = 0x2000; +#[allow(missing_docs)] +pub const SYM_V_PROTECTED: u16 = 0x3000; +#[allow(missing_docs)] +pub const SYM_V_EXPORTED: u16 = 0x4000; // Values for `n_sclass`. // @@ -447,7 +453,7 @@ pub const C_BLOCK: u8 = 100; /// Beginning or end of function. pub const C_FCN: u8 = 101; /// Un-named external symbol. -pub const C_HIDEXTL: u8 = 107; +pub const C_HIDEXT: u8 = 107; /// Comment string in .info section. pub const C_INFO: u8 = 110; /// Declaration of object (type). From cd4df262e4c9029ff9566fc178560217fe6bc671 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Tue, 18 Oct 2022 14:13:04 +0800 Subject: [PATCH 09/12] Update tests. --- .../examples/testfiles/xcoff/base.o.objdump | 22 +- .../testfiles/xcoff/base.xcoff.objdump | 203 ++++++------------ .../examples/testfiles/xcoff/base32.o.objdump | 102 ++------- .../testfiles/xcoff/base32.xcoff.objdump | 91 ++++++++ 4 files changed, 175 insertions(+), 243 deletions(-) diff --git a/crates/examples/testfiles/xcoff/base.o.objdump b/crates/examples/testfiles/xcoff/base.o.objdump index 83e9166d..ae2a86af 100644 --- a/crates/examples/testfiles/xcoff/base.o.objdump +++ b/crates/examples/testfiles/xcoff/base.o.objdump @@ -9,23 +9,13 @@ Entry Address: 0 Symbols 0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -1: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -2: Symbol { name: "", address: a, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -4: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -6: Symbol { name: "IBM Open XL C/C++ for AIX 17.1.1 (5725-C72, 5765-J18), LLVM version 16.0.0git", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -7: Symbol { name: ".text", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -8: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -10: Symbol { name: "", address: 700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -12: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -13: Symbol { name: "main", address: 68, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -14: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -16: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -18: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +7: Symbol { name: ".text", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +13: Symbol { name: "main", address: 68, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } Dynamic symbols diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index dfd7eb8b..bc62559b 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -4,167 +4,90 @@ Architecture: PowerPc64 Flags: Xcoff { f_flags: 1002 } Relative Address Base: 0 Entry Address: 0 -0: Section { name: "\u{1}\u{b}", address: 1000001f8, size: 1100008b8, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } -1: Section { name: "", address: 110000848, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } -2: Section { name: "", address: 1f8, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } -3: Section { name: "", address: 6cd, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 1 } } +0: Section { name: ".text", address: 1000001f8, size: 4d5, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } +1: Section { name: ".data", address: 1100006cd, size: 2ab, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } +2: Section { name: ".bss", address: 110000978, size: 0, align: 4, kind: UninitializedData, flags: Xcoff { s_flags: 80 } } +3: Section { name: ".loader", address: 0, size: 485, align: 4, kind: Metadata, flags: Xcoff { s_flags: 1000 } } Symbols 0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -1: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -3: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -5: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -7: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -9: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -11: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -13: Symbol { name: "__mod_init", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -15: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -17: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } 18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -19: Symbol { name: "rrno", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -21: Symbol { name: "", address: 0, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -22: Symbol { name: "__crt0v", address: 110000900, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -23: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -24: Symbol { name: "crt0_data", address: 110000908, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -25: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -26: Symbol { name: "__run_final_dtors", address: 110000910, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -27: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -28: Symbol { name: "_$STATIC", address: 110000918, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -29: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -31: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -32: Symbol { name: "atexit", address: 110000928, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -33: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -34: Symbol { name: "_cdtors", address: 110000930, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -35: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -37: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -38: Symbol { name: "exit", address: 110000940, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -39: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -40: Symbol { name: "__n_pthreads", address: 110000948, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -41: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -42: Symbol { name: "__mod_init", address: 110000950, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -43: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -45: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -46: Symbol { name: "errno", address: 110000960, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -47: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -49: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -50: Symbol { name: "printf", address: 110000970, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -51: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +22: Symbol { name: "__crt0v", address: 110000900, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +24: Symbol { name: "crt0_data", address: 110000908, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +26: Symbol { name: "__run_final_dtors", address: 110000910, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +28: Symbol { name: "_$STATIC", address: 110000918, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +32: Symbol { name: "atexit", address: 110000928, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +34: Symbol { name: "_cdtors", address: 110000930, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +38: Symbol { name: "exit", address: 110000940, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +40: Symbol { name: "__n_pthreads", address: 110000948, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +42: Symbol { name: "__mod_init", address: 110000950, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +46: Symbol { name: "errno", address: 110000960, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +50: Symbol { name: "printf", address: 110000970, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } 52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } 53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -55: Symbol { name: "", address: ad00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -57: Symbol { name: "nit_routine", address: 3600000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -58: Symbol { name: "__start", address: 110000848, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -59: Symbol { name: "", address: 1000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -60: Symbol { name: "crt0_data", address: 1100006d0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -61: Symbol { name: "", address: 6800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -62: Symbol { name: "p_xargc", address: 1100008c0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -63: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -64: Symbol { name: "p_xargv", address: 1100008f0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -65: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -67: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -68: Symbol { name: "p_xrc", address: 1100008fc, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -69: Symbol { name: "", address: 400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -71: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +58: Symbol { name: "__start", address: 110000848, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +60: Symbol { name: "crt0_data", address: 1100006d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +62: Symbol { name: "p_xargc", address: 1100008c0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +64: Symbol { name: "p_xargv", address: 1100008f0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +68: Symbol { name: "p_xrc", address: 1100008fc, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } 72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -73: Symbol { name: "", address: 11c, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -74: Symbol { name: "", address: 15b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -75: Symbol { name: "", address: 175, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -76: Symbol { name: "", address: 1000002c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -77: Symbol { name: "", address: 16000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -79: Symbol { name: "nit_routine", address: 4c00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -81: Symbol { name: "nit_routine", address: 4c00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -82: Symbol { name: "_$STATIC", address: 110000738, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -83: Symbol { name: "", address: 5900000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -84: Symbol { name: "__threads_init", address: 110000858, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -85: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -87: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -89: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -91: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -93: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -95: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +76: Symbol { name: "", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +82: Symbol { name: "_$STATIC", address: 110000738, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +84: Symbol { name: "__threads_init", address: 110000858, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } 96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -97: Symbol { name: "", address: 226, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -98: Symbol { name: "", address: 261, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -99: Symbol { name: "", address: 27b, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -100: Symbol { name: "", address: 100000420, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -101: Symbol { name: "", address: 17800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -103: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -105: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -107: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -109: Symbol { name: "nit_routine", address: 6400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -110: Symbol { name: "_$STATIC", address: 1100007a0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -111: Symbol { name: "", address: 9500000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Compilation, weak: false, flags: None } -113: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -115: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -117: Symbol { name: "", address: 1800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -118: Symbol { name: "_cdtors", address: 110000838, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: true, flags: None } -119: Symbol { name: "", address: 1000000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Linkage, weak: false, flags: None } -121: Symbol { name: "", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +100: Symbol { name: "", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +110: Symbol { name: "_$STATIC", address: 1100007a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +118: Symbol { name: "_cdtors", address: 110000838, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } +120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } 122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -123: Symbol { name: "", address: 626173652e630000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -124: Symbol { name: "", address: 319, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -125: Symbol { name: ".text", address: 100000640, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -126: Symbol { name: "", address: 5700000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -127: Symbol { name: ".main", address: 100000640, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -128: Symbol { name: "nit_routine", address: 7d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -130: Symbol { name: "", address: d00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +125: Symbol { name: ".text", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +127: Symbol { name: ".main", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } 131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -133: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -135: Symbol { name: "utine", address: 8400000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } 136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -138: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -140: Symbol { name: "utine", address: 8900000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } 141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -143: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -145: Symbol { name: "utine", address: 8e00000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } 146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -148: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -150: Symbol { name: "utine", address: 9300000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } 151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Compilation, weak: false, flags: None } -153: Symbol { name: "", address: 2800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } -154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Linkage, weak: false, flags: None } -155: Symbol { name: "utine", address: 9800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None } +152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } Dynamic symbols diff --git a/crates/examples/testfiles/xcoff/base32.o.objdump b/crates/examples/testfiles/xcoff/base32.o.objdump index bc62559b..61ce089a 100644 --- a/crates/examples/testfiles/xcoff/base32.o.objdump +++ b/crates/examples/testfiles/xcoff/base32.o.objdump @@ -1,93 +1,21 @@ -Format: Xcoff Big-endian 64-bit -Kind: Executable -Architecture: PowerPc64 -Flags: Xcoff { f_flags: 1002 } +Format: Xcoff Big-endian 32-bit +Kind: Relocatable +Architecture: PowerPc +Flags: Xcoff { f_flags: 0 } Relative Address Base: 0 Entry Address: 0 -0: Section { name: ".text", address: 1000001f8, size: 4d5, align: 4, kind: Text, flags: Xcoff { s_flags: 20 } } -1: Section { name: ".data", address: 1100006cd, size: 2ab, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } -2: Section { name: ".bss", address: 110000978, size: 0, align: 4, kind: UninitializedData, flags: Xcoff { s_flags: 80 } } -3: Section { name: ".loader", address: 0, size: 485, align: 4, kind: Metadata, flags: Xcoff { s_flags: 1000 } } +0: Section { name: ".text", address: 0, size: 6c, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } +1: Section { name: ".data", address: 6c, size: 10, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } Symbols -0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -22: Symbol { name: "__crt0v", address: 110000900, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -24: Symbol { name: "crt0_data", address: 110000908, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -26: Symbol { name: "__run_final_dtors", address: 110000910, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -28: Symbol { name: "_$STATIC", address: 110000918, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -32: Symbol { name: "atexit", address: 110000928, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -34: Symbol { name: "_cdtors", address: 110000930, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -38: Symbol { name: "exit", address: 110000940, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -40: Symbol { name: "__n_pthreads", address: 110000948, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -42: Symbol { name: "__mod_init", address: 110000950, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -46: Symbol { name: "errno", address: 110000960, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -50: Symbol { name: "printf", address: 110000970, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -54: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -58: Symbol { name: "__start", address: 110000848, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -60: Symbol { name: "crt0_data", address: 1100006d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -62: Symbol { name: "p_xargc", address: 1100008c0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -64: Symbol { name: "p_xargv", address: 1100008f0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -68: Symbol { name: "p_xrc", address: 1100008fc, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -76: Symbol { name: "", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -82: Symbol { name: "_$STATIC", address: 110000738, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -84: Symbol { name: "__threads_init", address: 110000858, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -100: Symbol { name: "", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -110: Symbol { name: "_$STATIC", address: 1100007a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -118: Symbol { name: "_cdtors", address: 110000838, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } -120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -125: Symbol { name: ".text", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -127: Symbol { name: ".main", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -132: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -142: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -152: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +7: Symbol { name: ".text", address: 0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +9: Symbol { name: ".main", address: 0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +11: Symbol { name: ".rodata.str1.1L...str", address: 5c, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +13: Symbol { name: "main", address: 6c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +15: Symbol { name: "TOC", address: 78, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +17: Symbol { name: ".rodata.str1.1L...str", address: 78, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } Dynamic symbols diff --git a/crates/examples/testfiles/xcoff/base32.xcoff.objdump b/crates/examples/testfiles/xcoff/base32.xcoff.objdump index e69de29b..beeb2213 100644 --- a/crates/examples/testfiles/xcoff/base32.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base32.xcoff.objdump @@ -0,0 +1,91 @@ +Format: Xcoff Big-endian 32-bit +Kind: Executable +Architecture: PowerPc +Flags: Xcoff { f_flags: 1002 } +Relative Address Base: 0 +Entry Address: 0 +0: Section { name: ".text", address: 10000128, size: 4c9, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } +1: Section { name: ".data", address: 200005f1, size: 1b7, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } +2: Section { name: ".bss", address: 200007a8, size: 0, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } +3: Section { name: ".loader", address: 0, size: 37a, align: 4, kind: Unknown, flags: Xcoff { s_flags: 0 } } + +Symbols +0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +2: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +4: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +6: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +8: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +10: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +12: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +14: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +16: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } +18: Symbol { name: "TOC", address: 20000748, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +20: Symbol { name: "__crt0v", address: 20000770, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +22: Symbol { name: "__mod_init", address: 20000774, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +24: Symbol { name: "crt0_data", address: 20000778, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +26: Symbol { name: "__run_final_dtors", address: 2000077c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +28: Symbol { name: "_$STATIC", address: 20000780, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +30: Symbol { name: "__C_runtime_termination", address: 20000784, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +32: Symbol { name: "atexit", address: 20000788, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +34: Symbol { name: "_cdtors", address: 2000078c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +36: Symbol { name: "__run_initial_ctors", address: 20000790, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +38: Symbol { name: "exit", address: 20000794, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +40: Symbol { name: "__malloc_user_defined_name", address: 20000798, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +42: Symbol { name: "errno", address: 2000079c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +44: Symbol { name: ".rodata.str1.1L...str", address: 200007a0, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +46: Symbol { name: "printf", address: 200007a4, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +48: Symbol { name: " ", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +49: Symbol { name: "crt0main.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +50: Symbol { name: ".__start", address: 10000128, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +52: Symbol { name: ".__start", address: 10000128, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +54: Symbol { name: "__start", address: 20000710, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +56: Symbol { name: "crt0_data", address: 200005f4, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +58: Symbol { name: "p_xargc", address: 2000074c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +60: Symbol { name: "p_xargv", address: 20000764, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +62: Symbol { name: "p_xrcfg", address: 20000768, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +64: Symbol { name: "p_xrc", address: 2000076c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +66: Symbol { name: "_malloc_user_defined_name", address: 20000748, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +68: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +72: Symbol { name: "", address: 100001e0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +74: Symbol { name: ".__threads_init", address: 100001e0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +76: Symbol { name: ".__threads_init@AF2_1", address: 10000220, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +78: Symbol { name: "_$STATIC", address: 20000620, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +80: Symbol { name: "__threads_init", address: 20000718, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +82: Symbol { name: "__pth_init_routine", address: 20000750, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +84: Symbol { name: "_bsd_init_routine", address: 20000754, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +86: Symbol { name: "_xti_tli_init_routine", address: 20000758, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +88: Symbol { name: "_nsl_init_routine", address: 2000075c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +90: Symbol { name: "__dce_compat_init_routine", address: 20000760, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +92: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +96: Symbol { name: "", address: 10000340, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +98: Symbol { name: ".__User_sinit_begin", address: 10000340, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +100: Symbol { name: ".__C_runtime_termination", address: 10000368, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +102: Symbol { name: ".__C_runtime_startup", address: 100003b8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +104: Symbol { name: ".__dftdt__L304e4b28c42_5CatchFv", address: 10000440, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +106: Symbol { name: "_$STATIC", address: 20000680, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +108: Symbol { name: "__dftdt__L304e4b28c42_5CatchFv", address: 20000730, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +110: Symbol { name: "__C_runtime_termination", address: 2000073c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +112: Symbol { name: "__C_runtime_startup", address: 20000724, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +114: Symbol { name: "_cdtors", address: 20000708, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } +116: Symbol { name: "__C_runtime_pstartup", address: 2000067c, size: 0, kind: Unknown, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +118: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +121: Symbol { name: ".text", address: 10000560, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +123: Symbol { name: ".main", address: 10000560, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +125: Symbol { name: ".rodata.str1.1L...str", address: 100005e4, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +127: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +128: Symbol { name: ".exit", address: 10000530, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +130: Symbol { name: ".exit", address: 10000530, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +132: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +133: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +135: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +137: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +138: Symbol { name: ".atexit", address: 100004e0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +140: Symbol { name: ".atexit", address: 100004e0, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +142: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +143: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +145: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +147: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } +148: Symbol { name: ".printf", address: 100005bc, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +150: Symbol { name: ".printf", address: 100005bc, size: 0, kind: Unknown, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } + +Dynamic symbols From d45f52cbc6de37d3773c0de43a13ef92f4499ba0 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Tue, 18 Oct 2022 14:31:08 +0800 Subject: [PATCH 10/12] Update comments. --- src/read/xcoff/section.rs | 3 ++- src/read/xcoff/symbol.rs | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index d4c5c01d..9d2828c6 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -98,7 +98,8 @@ where } fn align(&self) -> u64 { - // TODO: return the alignment for different sections. + // TODO: return the alignment from o_algntext or o_algndata in auxiliary header. + // The default section alignment is 4. 4 } diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 1f37531d..6096379d 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -260,7 +260,6 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> match self.symbol.n_sclass() { xcoff::C_FILE => SymbolKind::File, xcoff::C_NULL => SymbolKind::Null, - xcoff::C_GTLS | xcoff::C_STTLS => SymbolKind::Tls, _ => { if self.symbol.n_scnum() > 0 { let section = self From 69ada77c9a236a975b413468050bfc3db28d80d6 Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Wed, 19 Oct 2022 11:16:07 +0800 Subject: [PATCH 11/12] Fix some small things. --- src/read/xcoff/file.rs | 3 ++- src/read/xcoff/symbol.rs | 30 ++++++++++++------------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index 4177ec21..765861b0 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -271,7 +271,8 @@ pub trait FileHeader: Debug + Pod { } fn is_supported(&self) -> bool { - self.f_magic() == xcoff::MAGIC_64 || self.f_magic() == xcoff::MAGIC_32 + (self.is_type_64() && self.f_magic() == xcoff::MAGIC_64) + || (!self.is_type_64() && self.f_magic() == xcoff::MAGIC_32) } /// Read the section table. diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 6096379d..692e3341 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -260,22 +260,16 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> match self.symbol.n_sclass() { xcoff::C_FILE => SymbolKind::File, xcoff::C_NULL => SymbolKind::Null, - _ => { - if self.symbol.n_scnum() > 0 { - let section = self - .file - .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize)) - .unwrap(); - match section.kind() { - SectionKind::Data | SectionKind::UninitializedData => SymbolKind::Data, - SectionKind::UninitializedTls | SectionKind::Tls => SymbolKind::Tls, - SectionKind::Text => SymbolKind::Text, - _ => SymbolKind::Unknown, - } - } else { - SymbolKind::Unknown - } - } + _ => self + .file + .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize)) + .map(|section| match section.kind() { + SectionKind::Data | SectionKind::UninitializedData => SymbolKind::Data, + SectionKind::UninitializedTls | SectionKind::Tls => SymbolKind::Tls, + SectionKind::Text => SymbolKind::Text, + _ => SymbolKind::Unknown, + }) + .unwrap_or(SymbolKind::Unknown), } } @@ -315,8 +309,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } else { match self.symbol.n_sclass() { xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { - let visbility = self.symbol.n_type() & xcoff::SYM_V_MASK; - if visbility == xcoff::SYM_V_HIDDEN || visbility == xcoff::SYM_V_EXPORTED { + let visibility = self.symbol.n_type() & xcoff::SYM_V_MASK; + if visibility == xcoff::SYM_V_HIDDEN { SymbolScope::Linkage } else { SymbolScope::Dynamic From 7d0e1e01c90d82ee565c45d6716cb4a57925a7cd Mon Sep 17 00:00:00 2001 From: Esme Yi Date: Wed, 19 Oct 2022 13:10:07 +0800 Subject: [PATCH 12/12] include testfiles. --- testfiles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testfiles b/testfiles index e61733ee..1f989e6b 160000 --- a/testfiles +++ b/testfiles @@ -1 +1 @@ -Subproject commit e61733eec1dddc0429285a01959fea97f2bb974f +Subproject commit 1f989e6bb927b8a8dfd00f9e03ead88258cbd820