Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read/xcoff: initial support. #469

Merged
merged 12 commits into from
Oct 19, 2022
31 changes: 31 additions & 0 deletions crates/examples/testfiles/xcoff/base.o.objdump
Original file line number Diff line number Diff line change
@@ -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: "<invalid>", 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: "<invalid>", 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: "<invalid>", 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: "<invalid>", 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: "<invalid>", 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: "<invalid>", address: 800000000, size: 0, kind: Null, section: Undefined, scope: Unknown, weak: false, flags: None }

Dynamic symbols
170 changes: 170 additions & 0 deletions crates/examples/testfiles/xcoff/base.xcoff.objdump

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub enum BinaryFormat {
MachO,
Pe,
Wasm,
Xcoff,
}

/// The kind of a section.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
90 changes: 90 additions & 0 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
}
};
}
Expand All @@ -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,
}
};
}
Expand All @@ -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),
}
};
}
Expand All @@ -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),
}
};
}
Expand All @@ -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),
}
};
}
Expand All @@ -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),
}
};
}
Expand Down Expand Up @@ -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> {
Expand All @@ -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")),
};
Expand Down Expand Up @@ -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,
}
}
}
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -947,6 +1011,10 @@ where
Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)),
#[cfg(feature = "xcoff")]
Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "xcoff")]
Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData<R>)),
}

impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {}
Expand Down Expand Up @@ -1027,6 +1095,20 @@ where
Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)),
#[cfg(feature = "xcoff")]
Xcoff32(
(
xcoff::XcoffSymbolIterator32<'data, 'file, R>,
PhantomData<R>,
),
),
#[cfg(feature = "xcoff")]
Xcoff64(
(
xcoff::XcoffSymbolIterator64<'data, 'file, R>,
PhantomData<R>,
),
),
}

impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> {
Expand Down Expand Up @@ -1090,6 +1172,10 @@ where
Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "wasm")]
Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)),
#[cfg(feature = "xcoff")]
Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData<R>)),
#[cfg(feature = "xcoff")]
Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData<R>)),
}

impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> {
Expand Down Expand Up @@ -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> {
Expand Down
25 changes: 20 additions & 5 deletions src/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ pub use util::*;
feature = "elf",
feature = "macho",
feature = "pe",
feature = "wasm"
feature = "wasm",
feature = "xcoff"
))]
mod any;
#[cfg(any(
feature = "coff",
feature = "elf",
feature = "macho",
feature = "pe",
feature = "wasm"
feature = "wasm",
feature = "xcoff"
))]
pub use any::*;

Expand All @@ -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 {}
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
Loading