From 3c7a3d07f89c34c8bbc452059b8fc2ee7e608b89 Mon Sep 17 00:00:00 2001 From: everettjf Date: Sat, 1 Jan 2022 11:25:48 +0800 Subject: [PATCH] read: add ObjectSegment::flags (#416) --- src/common.rs | 25 +++++++++++++++++++++++++ src/read/any.rs | 8 ++++++-- src/read/coff/section.rs | 8 +++++++- src/read/elf/segment.rs | 8 +++++++- src/read/macho/segment.rs | 9 ++++++++- src/read/pe/section.rs | 8 +++++++- src/read/traits.rs | 7 +++++-- src/read/wasm.rs | 9 +++++++-- 8 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/common.rs b/src/common.rs index c86665c2..6bf5188d 100644 --- a/src/common.rs +++ b/src/common.rs @@ -366,6 +366,31 @@ pub enum FileFlags { }, } +/// Segment flags that are specific to each file format. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub enum SegmentFlags { + /// No segment flags. + None, + /// ELF segment flags. + Elf { + /// `p_flags` field in the segment header. + p_flags: u32, + }, + /// Mach-O segment flags. + MachO { + /// `maxprot` field in the segment header. + maxprot: u32, + /// `initprot` field in the segment header. + initprot: u32, + }, + /// COFF segment flags. + Coff { + /// `Characteristics` field in the segment header. + characteristics: u32, + }, +} + /// Section flags that are specific to each file format. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] diff --git a/src/read/any.rs b/src/read/any.rs index ce99bc31..02e76dcd 100644 --- a/src/read/any.rs +++ b/src/read/any.rs @@ -16,8 +16,8 @@ use crate::read::{ self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap, ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadRef, Relocation, Result, - SectionFlags, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, - SymbolMapName, SymbolScope, SymbolSection, + SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, + SymbolMap, SymbolMapName, SymbolScope, SymbolSection, }; #[allow(unused_imports)] use crate::{AddressSize, Endian, Endianness}; @@ -563,6 +563,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'f fn name(&self) -> Result> { with_inner!(self.inner, SegmentInternal, |x| x.name()) } + + fn flags(&self) -> SegmentFlags { + with_inner!(self.inner, SegmentInternal, |x| x.flags()) + } } /// An iterator of the sections of a `File`. diff --git a/src/read/coff/section.rs b/src/read/coff/section.rs index cb2edec9..731e37ca 100644 --- a/src/read/coff/section.rs +++ b/src/read/coff/section.rs @@ -6,7 +6,7 @@ use crate::pe; use crate::read::util::StringTable; use crate::read::{ self, CompressedData, CompressedFileRange, Error, ObjectSection, ObjectSegment, ReadError, - ReadRef, Result, SectionFlags, SectionIndex, SectionKind, + ReadRef, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, }; use super::{CoffFile, CoffRelocationIterator}; @@ -189,6 +189,12 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for CoffSegment<'data .read_error("Non UTF-8 COFF section name") .map(Some) } + + #[inline] + fn flags(&self) -> SegmentFlags { + let characteristics = self.section.characteristics.get(LE); + SegmentFlags::Coff { characteristics } + } } /// An iterator over the sections of a `CoffFile`. diff --git a/src/read/elf/segment.rs b/src/read/elf/segment.rs index a64a4ba5..874ea92b 100644 --- a/src/read/elf/segment.rs +++ b/src/read/elf/segment.rs @@ -4,7 +4,7 @@ use core::{mem, slice, str}; use crate::elf; use crate::endian::{self, Endianness}; use crate::pod::Pod; -use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef}; +use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef, SegmentFlags}; use super::{ElfFile, FileHeader, NoteIterator}; @@ -128,6 +128,12 @@ where fn name(&self) -> read::Result> { Ok(None) } + + #[inline] + fn flags(&self) -> SegmentFlags { + let p_flags = self.segment.p_flags(self.file.endian); + SegmentFlags::Elf { p_flags } + } } /// A trait for generic access to `ProgramHeader32` and `ProgramHeader64`. diff --git a/src/read/macho/segment.rs b/src/read/macho/segment.rs index 3a09379d..2023282c 100644 --- a/src/read/macho/segment.rs +++ b/src/read/macho/segment.rs @@ -4,7 +4,7 @@ use core::{result, slice, str}; use crate::endian::{self, Endianness}; use crate::macho; use crate::pod::Pod; -use crate::read::{self, ObjectSegment, ReadError, ReadRef, Result}; +use crate::read::{self, ObjectSegment, ReadError, ReadRef, Result, SegmentFlags}; use super::{LoadCommandData, MachHeader, MachOFile, Section}; @@ -133,6 +133,13 @@ where .read_error("Non UTF-8 Mach-O segment name")?, )) } + + #[inline] + fn flags(&self) -> SegmentFlags { + let maxprot = self.internal.segment.maxprot(self.file.endian); + let initprot = self.internal.segment.initprot(self.file.endian); + SegmentFlags::MachO { maxprot, initprot } + } } #[derive(Debug, Clone, Copy)] diff --git a/src/read/pe/section.rs b/src/read/pe/section.rs index bc4a6e0c..70ac6264 100644 --- a/src/read/pe/section.rs +++ b/src/read/pe/section.rs @@ -5,7 +5,7 @@ use crate::endian::LittleEndian as LE; use crate::pe; use crate::read::{ self, CompressedData, CompressedFileRange, ObjectSection, ObjectSegment, ReadError, ReadRef, - Relocation, Result, SectionFlags, SectionIndex, SectionKind, + Relocation, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, }; use super::{ImageNtHeaders, PeFile, SectionTable}; @@ -123,6 +123,12 @@ where .read_error("Non UTF-8 PE section name")?, )) } + + #[inline] + fn flags(&self) -> SegmentFlags { + let characteristics = self.section.characteristics.get(LE); + SegmentFlags::Coff { characteristics } + } } /// An iterator over the sections of a `PeFile32`. diff --git a/src/read/traits.rs b/src/read/traits.rs index 2581d497..f1a473e0 100644 --- a/src/read/traits.rs +++ b/src/read/traits.rs @@ -4,8 +4,8 @@ use alloc::vec::Vec; use crate::read::{ self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export, FileFlags, Import, ObjectKind, ObjectMap, Relocation, Result, SectionFlags, SectionIndex, - SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope, - SymbolSection, + SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, + SymbolScope, SymbolSection, }; use crate::Endianness; @@ -261,6 +261,9 @@ pub trait ObjectSegment<'data>: read::private::Sealed { /// /// Returns an error if the name is not UTF-8. fn name(&self) -> Result>; + + /// Return the flags of segment. + fn flags(&self) -> SegmentFlags; } /// A section defined in an object file. diff --git a/src/read/wasm.rs b/src/read/wasm.rs index ba006394..0113f597 100644 --- a/src/read/wasm.rs +++ b/src/read/wasm.rs @@ -13,8 +13,8 @@ use crate::read::{ self, Architecture, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result, - SectionFlags, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolScope, - SymbolSection, + SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, + SymbolScope, SymbolSection, }; const SECTION_CUSTOM: usize = 0; @@ -503,6 +503,11 @@ impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> { fn name(&self) -> Result> { unreachable!() } + + #[inline] + fn flags(&self) -> SegmentFlags { + unreachable!() + } } /// An iterator over the sections of a `WasmFile`.