third_party/rust/object/src/traits.rs
author Markus Stange <mstange@themasta.com>
Tue, 02 Oct 2018 01:50:56 +0000
changeset 497549 255e04ebe3bd06b1ecdcea2a5a699ffc7fd9920d
parent 497506 ac3deff9340f230fc2c91e4b05531ba32c827235
permissions -rw-r--r--
Bug 1457481 - Run mach vendor rust. r=froydnj,erahm Most importantly, this picks up "object" and "goblin" for ELF binary parsing. We only use the ELF code from goblin, so the mach-O parsing code gets eliminated by the linker. Overall, this increases the Android installer size by 20KB. Try pushes for reference: before: https://treeherder.mozilla.org/#/jobs?repo=try&revision=834b56dc5ab3d63a43a32f740ee8212296ac726d&selectedJob=201600899 after: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6983b27e8d3cb715d3b7e6cbd276683f6466e3cc&selectedJob=201600475 installer size: 34524820 -> 34542861 (34.52MB -> 34.54MB) $ mach vendor rust Updating registry `https://github.com/rust-lang/crates.io-index` Adding goblin v0.0.17 Adding memmap v0.6.2 Adding miniz-sys v0.1.10 Adding object v0.10.0 Adding parity-wasm v0.31.3 Adding plain v0.2.3 Adding profiler_helper v0.1.0 (file:///Users/mstange/code/mozilla/tools/profiler/rust-helper) Adding scroll v0.9.1 Adding scroll_derive v0.9.5 Adding syn v0.15.5 Adding thin-vec v0.1.0 Adding uuid v0.6.5 0:30.11 The following files exceed the filesize limit of 102400: third_party/rust/miniz-sys/miniz.c third_party/rust/syn-0.14.6/src/expr.rs third_party/rust/syn-0.14.6/src/gen/fold.rs third_party/rust/syn-0.14.6/src/gen/visit.rs third_party/rust/syn-0.14.6/src/gen/visit_mut.rs The syn dependency is not compiled for goblin, as far as I can tell - it's only needed for the 'syn' feature of scroll_derive, and scroll does not ask for scroll_derive/syn. object -> goblin -> scroll -> scroll_derive -/-> syn But it looks like other versions of syn were already in the tree. Depends on D7021 Differential Revision: https://phabricator.services.mozilla.com/D7023

use alloc::borrow::Cow;
use {Uuid, Machine, SectionKind, Symbol, SymbolMap};

/// An object file.
pub trait Object<'data, 'file> {
    /// A segment in the object file.
    type Segment: ObjectSegment<'data>;

    /// An iterator over the segments in the object file.
    type SegmentIterator: Iterator<Item = Self::Segment>;

    /// A section in the object file.
    type Section: ObjectSection<'data>;

    /// An iterator over the sections in the object file.
    type SectionIterator: Iterator<Item = Self::Section>;

    /// An iterator over the symbols in the object file.
    type SymbolIterator: Iterator<Item = Symbol<'data>>;

    /// Get the machine type of the file.
    fn machine(&self) -> Machine;

    /// Get an iterator over the segments in the file.
    fn segments(&'file self) -> Self::SegmentIterator;

    /// Get the entry point address of the binary
    fn entry(&'file self) -> u64;

    /// Get the contents of the section named `section_name`, if such
    /// a section exists.
    ///
    /// If `section_name` starts with a '.' then it is treated as a system section name,
    /// and is compared using the conventions specific to the object file format.
    /// For example, if ".text" is requested for a Mach-O object file, then the actual
    /// section name that is searched for is "__text".
    ///
    /// For some object files, multiple segments may contain sections with the same
    /// name. In this case, the first matching section will be used.
    ///
    /// This may decompress section data.
    fn section_data_by_name(&self, section_name: &str) -> Option<Cow<'data, [u8]>>;

    /// Get an iterator over the sections in the file.
    fn sections(&'file self) -> Self::SectionIterator;

    /// Get an iterator over the debugging symbols in the file.
    fn symbols(&'file self) -> Self::SymbolIterator;

    /// Get an iterator over the dynamic linking symbols in the file.
    fn dynamic_symbols(&'file self) -> Self::SymbolIterator;

    /// Construct a map from addresses to symbols.
    fn symbol_map(&self) -> SymbolMap<'data>;

    /// Return true if the file is little endian, false if it is big endian.
    fn is_little_endian(&self) -> bool;

    /// Return true if the file contains debug information sections, false if not.
    fn has_debug_symbols(&self) -> bool;

    /// The UUID from a Mach-O `LC_UUID` load command.
    #[inline]
    fn mach_uuid(&self) -> Option<Uuid> {
        None
    }

    /// The build ID from an ELF `NT_GNU_BUILD_ID` note.
    #[inline]
    fn build_id(&self) -> Option<&'data [u8]> {
        None
    }

    /// The filename and CRC from a `.gnu_debuglink` section.
    #[inline]
    fn gnu_debuglink(&self) -> Option<(&'data [u8], u32)> {
        None
    }
}

/// A loadable segment defined in an object file.
///
/// For ELF, this is a program header with type `PT_LOAD`.
/// For Mach-O, this is a load command with type `LC_SEGMENT` or `LC_SEGMENT_64`.
pub trait ObjectSegment<'data> {
    /// Returns the virtual address of the segment.
    fn address(&self) -> u64;

    /// Returns the size of the segment in memory.
    fn size(&self) -> u64;

    /// Returns a reference to the file contents of the segment.
    /// The length of this data may be different from the size of the
    /// segment in memory.
    fn data(&self) -> &'data [u8];

    /// Returns the name of the segment.
    fn name(&self) -> Option<&str>;
}

/// A section defined in an object file.
pub trait ObjectSection<'data> {
    /// Returns the address of the section.
    fn address(&self) -> u64;

    /// Returns the size of the section in memory.
    fn size(&self) -> u64;

    /// Returns a reference to the raw contents of the section.
    /// The length of this data may be different from the size of the
    /// section in memory.
    ///
    /// This does not do any decompression.
    fn data(&self) -> Cow<'data, [u8]>;

    /// Returns the name of the section.
    fn name(&self) -> Option<&str>;

    /// Returns the name of the segment for this section.
    fn segment_name(&self) -> Option<&str>;

    /// Return the kind of this section.
    fn kind(&self) -> SectionKind;
}