summaryrefslogtreecommitdiffstats
path: root/third_party/rust/object/src/read/traits.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/object/src/read/traits.rs
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/object/src/read/traits.rs')
-rw-r--r--third_party/rust/object/src/read/traits.rs220
1 files changed, 220 insertions, 0 deletions
diff --git a/third_party/rust/object/src/read/traits.rs b/third_party/rust/object/src/read/traits.rs
new file mode 100644
index 0000000000..70b11e798a
--- /dev/null
+++ b/third_party/rust/object/src/read/traits.rs
@@ -0,0 +1,220 @@
+use crate::alloc::borrow::Cow;
+use crate::{Relocation, SectionIndex, SectionKind, Symbol, SymbolIndex, SymbolMap};
+use target_lexicon::{Architecture, Endianness};
+use uuid::Uuid;
+
+/// 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 = (SymbolIndex, Symbol<'data>)>;
+
+ /// Get the architecture type of the file.
+ fn architecture(&self) -> Architecture;
+
+ /// Get the endianness of the file.
+ #[inline]
+ fn endianness(&self) -> Endianness {
+ if self.is_little_endian() {
+ Endianness::Little
+ } else {
+ Endianness::Big
+ }
+ }
+
+ /// 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 can contain 64-bit addresses.
+ fn is_64(&self) -> bool;
+
+ /// 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 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. This
+ /// includes:
+ /// - if ".text" is requested for a Mach-O object file, then the actual
+ /// section name that is searched for is "__text".
+ /// - if ".debug_info" is requested for an ELF object file, then
+ /// ".zdebug_info" may be returned (and similarly for other debug sections).
+ ///
+ /// For some object files, multiple segments may contain sections with the same
+ /// name. In this case, the first matching section will be used.
+ fn section_by_name(&'file self, section_name: &str) -> Option<Self::Section>;
+
+ /// Get the section at the given index.
+ ///
+ /// The meaning of the index depends on the object file.
+ ///
+ /// For some object files, this requires iterating through all sections.
+ fn section_by_index(&'file self, index: SectionIndex) -> Option<Self::Section>;
+
+ /// Get the contents of the section named `section_name`, if such
+ /// a section exists.
+ ///
+ /// The `section_name` is interpreted according to `Self::section_by_name`.
+ ///
+ /// This may decompress section data.
+ fn section_data_by_name(&'file self, section_name: &str) -> Option<Cow<'data, [u8]>> {
+ self.section_by_name(section_name)
+ .map(|section| section.uncompressed_data())
+ }
+
+ /// Get an iterator over the sections in the file.
+ fn sections(&'file self) -> Self::SectionIterator;
+
+ /// Get the debugging symbol at the given index.
+ ///
+ /// This is similar to `self.symbols().nth(index)`, except that
+ /// the index will take into account malformed or unsupported symbols.
+ fn symbol_by_index(&self, index: SymbolIndex) -> Option<Symbol<'data>>;
+
+ /// Get an iterator over the debugging symbols in the file.
+ ///
+ /// This may skip over symbols that are malformed or unsupported.
+ fn symbols(&'file self) -> Self::SymbolIterator;
+
+ /// Get the data for the given symbol.
+ fn symbol_data(&'file self, symbol: &Symbol<'data>) -> Option<&'data [u8]> {
+ if symbol.is_undefined() {
+ return None;
+ }
+ let address = symbol.address();
+ let size = symbol.size();
+ if let Some(index) = symbol.section_index() {
+ self.section_by_index(index)
+ .and_then(|section| section.data_range(address, size))
+ } else {
+ self.segments()
+ .find_map(|segment| segment.data_range(address, size))
+ }
+ }
+
+ /// Get an iterator over the dynamic linking symbols in the file.
+ ///
+ /// This may skip over symbols that are malformed or unsupported.
+ 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 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 the alignment of the segment in memory.
+ fn align(&self) -> u64;
+
+ /// Returns the offset and size of the segment in the file.
+ fn file_range(&self) -> (u64, 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];
+
+ /// Return the segment data in the given range.
+ fn data_range(&self, address: u64, size: u64) -> Option<&'data [u8]>;
+
+ /// Returns the name of the segment.
+ fn name(&self) -> Option<&str>;
+}
+
+/// A section defined in an object file.
+pub trait ObjectSection<'data> {
+ /// An iterator over the relocations for a section.
+ ///
+ /// The first field in the item tuple is the section offset
+ /// that the relocation applies to.
+ type RelocationIterator: Iterator<Item = (u64, Relocation)>;
+
+ /// Returns the section index.
+ fn index(&self) -> SectionIndex;
+
+ /// Returns the address of the section.
+ fn address(&self) -> u64;
+
+ /// Returns the size of the section in memory.
+ fn size(&self) -> u64;
+
+ /// Returns the alignment of the section in memory.
+ fn align(&self) -> u64;
+
+ /// Returns offset and size of on-disk segment (if any)
+ fn file_range(&self) -> Option<(u64, u64)>;
+
+ /// Returns 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]>;
+
+ /// Return the raw contents of the section data in the given range.
+ ///
+ /// This does not do any decompression.
+ fn data_range(&self, address: u64, size: u64) -> Option<&'data [u8]>;
+
+ /// Returns the uncompressed contents of the section.
+ /// The length of this data may be different from the size of the
+ /// section in memory.
+ fn uncompressed_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;
+
+ /// Get the relocations for this section.
+ fn relocations(&self) -> Self::RelocationIterator;
+}