summaryrefslogtreecommitdiffstats
path: root/vendor/object/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src')
-rw-r--r--vendor/object/src/common.rs2
-rw-r--r--vendor/object/src/elf.rs18
-rw-r--r--vendor/object/src/pe.rs4
-rw-r--r--vendor/object/src/read/any.rs125
-rw-r--r--vendor/object/src/read/coff/import.rs209
-rw-r--r--vendor/object/src/read/coff/mod.rs3
-rw-r--r--vendor/object/src/read/elf/file.rs1
-rw-r--r--vendor/object/src/read/elf/note.rs23
-rw-r--r--vendor/object/src/read/elf/relocation.rs5
-rw-r--r--vendor/object/src/read/elf/symbol.rs8
-rw-r--r--vendor/object/src/read/mod.rs11
-rw-r--r--vendor/object/src/write/elf/object.rs12
-rw-r--r--vendor/object/src/write/macho.rs30
13 files changed, 347 insertions, 104 deletions
diff --git a/vendor/object/src/common.rs b/vendor/object/src/common.rs
index 7d789a71d..0e6af091c 100644
--- a/vendor/object/src/common.rs
+++ b/vendor/object/src/common.rs
@@ -10,6 +10,7 @@ pub enum Architecture {
Arm,
Avr,
Bpf,
+ Csky,
I386,
X86_64,
#[allow(non_camel_case_types)]
@@ -43,6 +44,7 @@ impl Architecture {
Architecture::Arm => Some(AddressSize::U32),
Architecture::Avr => Some(AddressSize::U8),
Architecture::Bpf => Some(AddressSize::U64),
+ Architecture::Csky => Some(AddressSize::U32),
Architecture::I386 => Some(AddressSize::U32),
Architecture::X86_64 => Some(AddressSize::U64),
Architecture::X86_64_X32 => Some(AddressSize::U32),
diff --git a/vendor/object/src/elf.rs b/vendor/object/src/elf.rs
index 202b3a2cc..da68ec2d4 100644
--- a/vendor/object/src/elf.rs
+++ b/vendor/object/src/elf.rs
@@ -1308,11 +1308,11 @@ pub const PF_MASKOS: u32 = 0x0ff0_0000;
pub const PF_MASKPROC: u32 = 0xf000_0000;
/// Note name for core files.
-pub static ELF_NOTE_CORE: &[u8] = b"CORE";
+pub const ELF_NOTE_CORE: &[u8] = b"CORE";
/// Note name for linux core files.
///
/// Notes in linux core files may also use `ELF_NOTE_CORE`.
-pub static ELF_NOTE_LINUX: &[u8] = b"LINUX";
+pub const ELF_NOTE_LINUX: &[u8] = b"LINUX";
// Values for `NoteHeader*::n_type` in core files.
//
@@ -1826,14 +1826,18 @@ pub struct NoteHeader64<E: Endian> {
}
/// Solaris entries in the note section have this name.
-pub static ELF_NOTE_SOLARIS: &[u8] = b"SUNW Solaris";
+pub const ELF_NOTE_SOLARIS: &[u8] = b"SUNW Solaris";
// Values for `n_type` when the name is `ELF_NOTE_SOLARIS`.
/// Desired pagesize for the binary.
pub const NT_SOLARIS_PAGESIZE_HINT: u32 = 1;
/// GNU entries in the note section have this name.
-pub static ELF_NOTE_GNU: &[u8] = b"GNU";
+pub const ELF_NOTE_GNU: &[u8] = b"GNU";
+
+/// Go entries in the note section have this name.
+// See https://go-review.googlesource.com/9520 and https://go-review.googlesource.com/10704.
+pub const ELF_NOTE_GO: &[u8] = b"Go";
// Note types for `ELF_NOTE_GNU`.
@@ -1870,6 +1874,12 @@ pub const NT_GNU_HWCAP: u32 = 2;
/// The descriptor consists of any nonzero number of bytes.
pub const NT_GNU_BUILD_ID: u32 = 3;
+/// Build ID bits as generated by Go's gc compiler.
+///
+/// The descriptor consists of any nonzero number of bytes.
+// See https://go-review.googlesource.com/10707.
+pub const NT_GO_BUILD_ID: u32 = 4;
+
/// Version note generated by GNU gold containing a version string.
pub const NT_GNU_GOLD_VERSION: u32 = 4;
diff --git a/vendor/object/src/pe.rs b/vendor/object/src/pe.rs
index bac101ea0..f274d2270 100644
--- a/vendor/object/src/pe.rs
+++ b/vendor/object/src/pe.rs
@@ -2873,10 +2873,14 @@ pub struct ImportObjectHeader {
pub name_type: U16<LE>,
}
+pub const IMPORT_OBJECT_TYPE_MASK: u16 = 0b11;
+pub const IMPORT_OBJECT_TYPE_SHIFT: u16 = 0;
pub const IMPORT_OBJECT_CODE: u16 = 0;
pub const IMPORT_OBJECT_DATA: u16 = 1;
pub const IMPORT_OBJECT_CONST: u16 = 2;
+pub const IMPORT_OBJECT_NAME_MASK: u16 = 0b111;
+pub const IMPORT_OBJECT_NAME_SHIFT: u16 = 2;
/// Import by ordinal
pub const IMPORT_OBJECT_ORDINAL: u16 = 0;
/// Import name == public symbol name.
diff --git a/vendor/object/src/read/any.rs b/vendor/object/src/read/any.rs
index 342ad75fd..2e147c672 100644
--- a/vendor/object/src/read/any.rs
+++ b/vendor/object/src/read/any.rs
@@ -208,12 +208,9 @@ macro_rules! next_inner {
///
/// Most functionality is provided by the `Object` trait implementation.
#[derive(Debug)]
-pub struct File<'data, R: ReadRef<'data> = &'data [u8]> {
- inner: FileInternal<'data, R>,
-}
-
-#[derive(Debug)]
-enum FileInternal<'data, R: ReadRef<'data>> {
+#[non_exhaustive]
+#[allow(missing_docs)]
+pub enum File<'data, R: ReadRef<'data> = &'data [u8]> {
#[cfg(feature = "coff")]
Coff(coff::CoffFile<'data, R>),
#[cfg(feature = "coff")]
@@ -241,33 +238,32 @@ enum FileInternal<'data, R: ReadRef<'data>> {
impl<'data, R: ReadRef<'data>> File<'data, R> {
/// Parse the raw file data.
pub fn parse(data: R) -> Result<Self> {
- let inner = match FileKind::parse(data)? {
+ Ok(match FileKind::parse(data)? {
#[cfg(feature = "elf")]
- FileKind::Elf32 => FileInternal::Elf32(elf::ElfFile32::parse(data)?),
+ FileKind::Elf32 => File::Elf32(elf::ElfFile32::parse(data)?),
#[cfg(feature = "elf")]
- FileKind::Elf64 => FileInternal::Elf64(elf::ElfFile64::parse(data)?),
+ FileKind::Elf64 => File::Elf64(elf::ElfFile64::parse(data)?),
#[cfg(feature = "macho")]
- FileKind::MachO32 => FileInternal::MachO32(macho::MachOFile32::parse(data)?),
+ FileKind::MachO32 => File::MachO32(macho::MachOFile32::parse(data)?),
#[cfg(feature = "macho")]
- FileKind::MachO64 => FileInternal::MachO64(macho::MachOFile64::parse(data)?),
+ FileKind::MachO64 => File::MachO64(macho::MachOFile64::parse(data)?),
#[cfg(feature = "wasm")]
- FileKind::Wasm => FileInternal::Wasm(wasm::WasmFile::parse(data)?),
+ FileKind::Wasm => File::Wasm(wasm::WasmFile::parse(data)?),
#[cfg(feature = "pe")]
- FileKind::Pe32 => FileInternal::Pe32(pe::PeFile32::parse(data)?),
+ FileKind::Pe32 => File::Pe32(pe::PeFile32::parse(data)?),
#[cfg(feature = "pe")]
- FileKind::Pe64 => FileInternal::Pe64(pe::PeFile64::parse(data)?),
+ FileKind::Pe64 => File::Pe64(pe::PeFile64::parse(data)?),
#[cfg(feature = "coff")]
- FileKind::Coff => FileInternal::Coff(coff::CoffFile::parse(data)?),
+ FileKind::Coff => File::Coff(coff::CoffFile::parse(data)?),
#[cfg(feature = "coff")]
- FileKind::CoffBig => FileInternal::CoffBig(coff::CoffBigFile::parse(data)?),
+ FileKind::CoffBig => File::CoffBig(coff::CoffBigFile::parse(data)?),
#[cfg(feature = "xcoff")]
- FileKind::Xcoff32 => FileInternal::Xcoff32(xcoff::XcoffFile32::parse(data)?),
+ FileKind::Xcoff32 => File::Xcoff32(xcoff::XcoffFile32::parse(data)?),
#[cfg(feature = "xcoff")]
- FileKind::Xcoff64 => FileInternal::Xcoff64(xcoff::XcoffFile64::parse(data)?),
+ FileKind::Xcoff64 => File::Xcoff64(xcoff::XcoffFile64::parse(data)?),
#[allow(unreachable_patterns)]
_ => return Err(Error("Unsupported file format")),
- };
- Ok(File { inner })
+ })
}
/// Parse a Mach-O image from the dyld shared cache.
@@ -275,33 +271,32 @@ impl<'data, R: ReadRef<'data>> File<'data, R> {
pub fn parse_dyld_cache_image<'cache, E: Endian>(
image: &macho::DyldCacheImage<'data, 'cache, E, R>,
) -> Result<Self> {
- let inner = match image.cache.architecture().address_size() {
+ Ok(match image.cache.architecture().address_size() {
Some(AddressSize::U64) => {
- FileInternal::MachO64(macho::MachOFile64::parse_dyld_cache_image(image)?)
+ File::MachO64(macho::MachOFile64::parse_dyld_cache_image(image)?)
}
Some(AddressSize::U32) => {
- FileInternal::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?)
+ File::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?)
}
_ => return Err(Error("Unsupported file format")),
- };
- Ok(File { inner })
+ })
}
/// Return the file format.
pub fn format(&self) -> BinaryFormat {
- match self.inner {
+ match self {
#[cfg(feature = "coff")]
- FileInternal::Coff(_) | FileInternal::CoffBig(_) => BinaryFormat::Coff,
+ File::Coff(_) | File::CoffBig(_) => BinaryFormat::Coff,
#[cfg(feature = "elf")]
- FileInternal::Elf32(_) | FileInternal::Elf64(_) => BinaryFormat::Elf,
+ File::Elf32(_) | File::Elf64(_) => BinaryFormat::Elf,
#[cfg(feature = "macho")]
- FileInternal::MachO32(_) | FileInternal::MachO64(_) => BinaryFormat::MachO,
+ File::MachO32(_) | File::MachO64(_) => BinaryFormat::MachO,
#[cfg(feature = "pe")]
- FileInternal::Pe32(_) | FileInternal::Pe64(_) => BinaryFormat::Pe,
+ File::Pe32(_) | File::Pe64(_) => BinaryFormat::Pe,
#[cfg(feature = "wasm")]
- FileInternal::Wasm(_) => BinaryFormat::Wasm,
+ File::Wasm(_) => BinaryFormat::Wasm,
#[cfg(feature = "xcoff")]
- FileInternal::Xcoff32(_) | FileInternal::Xcoff64(_) => BinaryFormat::Xcoff,
+ File::Xcoff32(_) | File::Xcoff64(_) => BinaryFormat::Xcoff,
}
}
}
@@ -325,56 +320,52 @@ where
type DynamicRelocationIterator = DynamicRelocationIterator<'data, 'file, R>;
fn architecture(&self) -> Architecture {
- with_inner!(self.inner, FileInternal, |x| x.architecture())
+ with_inner!(self, File, |x| x.architecture())
}
fn is_little_endian(&self) -> bool {
- with_inner!(self.inner, FileInternal, |x| x.is_little_endian())
+ with_inner!(self, File, |x| x.is_little_endian())
}
fn is_64(&self) -> bool {
- with_inner!(self.inner, FileInternal, |x| x.is_64())
+ with_inner!(self, File, |x| x.is_64())
}
fn kind(&self) -> ObjectKind {
- with_inner!(self.inner, FileInternal, |x| x.kind())
+ with_inner!(self, File, |x| x.kind())
}
fn segments(&'file self) -> SegmentIterator<'data, 'file, R> {
SegmentIterator {
- inner: map_inner!(self.inner, FileInternal, SegmentIteratorInternal, |x| x
- .segments()),
+ inner: map_inner!(self, File, SegmentIteratorInternal, |x| x.segments()),
}
}
fn section_by_name_bytes(&'file self, section_name: &[u8]) -> Option<Section<'data, 'file, R>> {
- map_inner_option!(self.inner, FileInternal, SectionInternal, |x| x
+ map_inner_option!(self, File, SectionInternal, |x| x
.section_by_name_bytes(section_name))
.map(|inner| Section { inner })
}
fn section_by_index(&'file self, index: SectionIndex) -> Result<Section<'data, 'file, R>> {
- map_inner_option!(self.inner, FileInternal, SectionInternal, |x| x
- .section_by_index(index))
- .map(|inner| Section { inner })
+ map_inner_option!(self, File, SectionInternal, |x| x.section_by_index(index))
+ .map(|inner| Section { inner })
}
fn sections(&'file self) -> SectionIterator<'data, 'file, R> {
SectionIterator {
- inner: map_inner!(self.inner, FileInternal, SectionIteratorInternal, |x| x
- .sections()),
+ inner: map_inner!(self, File, SectionIteratorInternal, |x| x.sections()),
}
}
fn comdats(&'file self) -> ComdatIterator<'data, 'file, R> {
ComdatIterator {
- inner: map_inner!(self.inner, FileInternal, ComdatIteratorInternal, |x| x
- .comdats()),
+ inner: map_inner!(self, File, ComdatIteratorInternal, |x| x.comdats()),
}
}
fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Symbol<'data, 'file, R>> {
- map_inner_option!(self.inner, FileInternal, SymbolInternal, |x| x
+ map_inner_option!(self, File, SymbolInternal, |x| x
.symbol_by_index(index)
.map(|x| (x, PhantomData)))
.map(|inner| Symbol { inner })
@@ -382,7 +373,7 @@ where
fn symbols(&'file self) -> SymbolIterator<'data, 'file, R> {
SymbolIterator {
- inner: map_inner!(self.inner, FileInternal, SymbolIteratorInternal, |x| (
+ inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
x.symbols(),
PhantomData
)),
@@ -390,7 +381,7 @@ where
}
fn symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> {
- map_inner_option!(self.inner, FileInternal, SymbolTableInternal, |x| x
+ map_inner_option!(self, File, SymbolTableInternal, |x| x
.symbol_table()
.map(|x| (x, PhantomData)))
.map(|inner| SymbolTable { inner })
@@ -398,7 +389,7 @@ where
fn dynamic_symbols(&'file self) -> SymbolIterator<'data, 'file, R> {
SymbolIterator {
- inner: map_inner!(self.inner, FileInternal, SymbolIteratorInternal, |x| (
+ inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
x.dynamic_symbols(),
PhantomData
)),
@@ -406,7 +397,7 @@ where
}
fn dynamic_symbol_table(&'file self) -> Option<SymbolTable<'data, 'file, R>> {
- map_inner_option!(self.inner, FileInternal, SymbolTableInternal, |x| x
+ map_inner_option!(self, File, SymbolTableInternal, |x| x
.dynamic_symbol_table()
.map(|x| (x, PhantomData)))
.map(|inner| SymbolTable { inner })
@@ -414,11 +405,11 @@ where
#[cfg(feature = "elf")]
fn dynamic_relocations(&'file self) -> Option<DynamicRelocationIterator<'data, 'file, R>> {
- let inner = match self.inner {
- FileInternal::Elf32(ref elf) => {
+ let inner = match self {
+ File::Elf32(ref elf) => {
DynamicRelocationIteratorInternal::Elf32(elf.dynamic_relocations()?)
}
- FileInternal::Elf64(ref elf) => {
+ File::Elf64(ref elf) => {
DynamicRelocationIteratorInternal::Elf64(elf.dynamic_relocations()?)
}
#[allow(unreachable_patterns)]
@@ -433,60 +424,60 @@ where
}
fn symbol_map(&self) -> SymbolMap<SymbolMapName<'data>> {
- with_inner!(self.inner, FileInternal, |x| x.symbol_map())
+ with_inner!(self, File, |x| x.symbol_map())
}
fn object_map(&self) -> ObjectMap<'data> {
- with_inner!(self.inner, FileInternal, |x| x.object_map())
+ with_inner!(self, File, |x| x.object_map())
}
fn imports(&self) -> Result<Vec<Import<'data>>> {
- with_inner!(self.inner, FileInternal, |x| x.imports())
+ with_inner!(self, File, |x| x.imports())
}
fn exports(&self) -> Result<Vec<Export<'data>>> {
- with_inner!(self.inner, FileInternal, |x| x.exports())
+ with_inner!(self, File, |x| x.exports())
}
fn has_debug_symbols(&self) -> bool {
- with_inner!(self.inner, FileInternal, |x| x.has_debug_symbols())
+ with_inner!(self, File, |x| x.has_debug_symbols())
}
#[inline]
fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
- with_inner!(self.inner, FileInternal, |x| x.mach_uuid())
+ with_inner!(self, File, |x| x.mach_uuid())
}
#[inline]
fn build_id(&self) -> Result<Option<&'data [u8]>> {
- with_inner!(self.inner, FileInternal, |x| x.build_id())
+ with_inner!(self, File, |x| x.build_id())
}
#[inline]
fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
- with_inner!(self.inner, FileInternal, |x| x.gnu_debuglink())
+ with_inner!(self, File, |x| x.gnu_debuglink())
}
#[inline]
fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
- with_inner!(self.inner, FileInternal, |x| x.gnu_debugaltlink())
+ with_inner!(self, File, |x| x.gnu_debugaltlink())
}
#[inline]
fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
- with_inner!(self.inner, FileInternal, |x| x.pdb_info())
+ with_inner!(self, File, |x| x.pdb_info())
}
fn relative_address_base(&self) -> u64 {
- with_inner!(self.inner, FileInternal, |x| x.relative_address_base())
+ with_inner!(self, File, |x| x.relative_address_base())
}
fn entry(&self) -> u64 {
- with_inner!(self.inner, FileInternal, |x| x.entry())
+ with_inner!(self, File, |x| x.entry())
}
fn flags(&self) -> FileFlags {
- with_inner!(self.inner, FileInternal, |x| x.flags())
+ with_inner!(self, File, |x| x.flags())
}
}
diff --git a/vendor/object/src/read/coff/import.rs b/vendor/object/src/read/coff/import.rs
new file mode 100644
index 000000000..d635e7592
--- /dev/null
+++ b/vendor/object/src/read/coff/import.rs
@@ -0,0 +1,209 @@
+//! Support for reading short import files.
+//!
+//! These are used by some Windows linkers as a more compact way to describe
+//! dynamically imported symbols.
+
+use crate::read::{Architecture, Error, ReadError, ReadRef, Result};
+use crate::{pe, ByteString, Bytes, LittleEndian as LE};
+
+/// A Windows short form description of a symbol to import.
+///
+/// Used in Windows import libraries to provide a mapping from
+/// a symbol name to a DLL export. This is not an object file.
+#[derive(Debug, Clone)]
+pub struct ImportFile<'data> {
+ header: &'data pe::ImportObjectHeader,
+ kind: ImportType,
+ dll: ByteString<'data>,
+ symbol: ByteString<'data>,
+ import: Option<ByteString<'data>>,
+}
+
+impl<'data> ImportFile<'data> {
+ /// Parse it.
+ pub fn parse<R: ReadRef<'data>>(data: R) -> Result<Self> {
+ let mut offset = 0;
+ let header = pe::ImportObjectHeader::parse(data, &mut offset)?;
+ let data = header.parse_data(data, &mut offset)?;
+
+ // Unmangles a name by removing a `?`, `@` or `_` prefix.
+ fn strip_prefix(s: &[u8]) -> &[u8] {
+ match s.split_first() {
+ Some((b, rest)) if [b'?', b'@', b'_'].contains(b) => rest,
+ _ => s,
+ }
+ }
+ Ok(Self {
+ header,
+ dll: data.dll,
+ symbol: data.symbol,
+ kind: match header.import_type() {
+ pe::IMPORT_OBJECT_CODE => ImportType::Code,
+ pe::IMPORT_OBJECT_DATA => ImportType::Data,
+ pe::IMPORT_OBJECT_CONST => ImportType::Const,
+ _ => return Err(Error("Invalid COFF import library import type")),
+ },
+ import: match header.name_type() {
+ pe::IMPORT_OBJECT_ORDINAL => None,
+ pe::IMPORT_OBJECT_NAME => Some(data.symbol()),
+ pe::IMPORT_OBJECT_NAME_NO_PREFIX => Some(strip_prefix(data.symbol())),
+ pe::IMPORT_OBJECT_NAME_UNDECORATE => Some(
+ strip_prefix(data.symbol())
+ .split(|&b| b == b'@')
+ .next()
+ .unwrap(),
+ ),
+ pe::IMPORT_OBJECT_NAME_EXPORTAS => data.export(),
+ _ => return Err(Error("Unknown COFF import library name type")),
+ }
+ .map(ByteString),
+ })
+ }
+
+ /// Get the machine type.
+ pub fn architecture(&self) -> Architecture {
+ match self.header.machine.get(LE) {
+ pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
+ pe::IMAGE_FILE_MACHINE_ARM64 => Architecture::Aarch64,
+ pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
+ pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
+ _ => Architecture::Unknown,
+ }
+ }
+
+ /// The public symbol name.
+ pub fn symbol(&self) -> &'data [u8] {
+ self.symbol.0
+ }
+
+ /// The name of the DLL to import the symbol from.
+ pub fn dll(&self) -> &'data [u8] {
+ self.dll.0
+ }
+
+ /// The name exported from the DLL.
+ pub fn import(&self) -> ImportName<'data> {
+ match self.import {
+ Some(name) => ImportName::Name(name.0),
+ None => ImportName::Ordinal(self.header.ordinal_or_hint.get(LE)),
+ }
+ }
+
+ /// The type of import. Usually either a function or data.
+ pub fn import_type(&self) -> ImportType {
+ self.kind
+ }
+}
+
+/// The name or ordinal to import from a DLL.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ImportName<'data> {
+ /// Import by ordinal. Ordinarily this is a 1-based index.
+ Ordinal(u16),
+ /// Import by name.
+ Name(&'data [u8]),
+}
+
+/// The kind of import symbol.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum ImportType {
+ /// An executable code symbol.
+ Code,
+ /// A data symbol.
+ Data,
+ /// A constant value.
+ Const,
+}
+
+impl pe::ImportObjectHeader {
+ /// Read the short import header.
+ ///
+ /// Also checks that the signature and version are valid.
+ /// Directly following this header will be the string data.
+ pub fn parse<'data, R: ReadRef<'data>>(data: R, offset: &mut u64) -> Result<&'data Self> {
+ let header = data
+ .read::<pe::ImportObjectHeader>(offset)
+ .read_error("Invalid COFF import library header size")?;
+ if header.sig1.get(LE) != 0 || header.sig2.get(LE) != pe::IMPORT_OBJECT_HDR_SIG2 {
+ Err(Error("Invalid COFF import library header"))
+ } else if header.version.get(LE) != 0 {
+ Err(Error("Unknown COFF import library header version"))
+ } else {
+ Ok(header)
+ }
+ }
+
+ /// Parse the data following the header.
+ pub fn parse_data<'data, R: ReadRef<'data>>(
+ &self,
+ data: R,
+ offset: &mut u64,
+ ) -> Result<ImportObjectData<'data>> {
+ let mut data = Bytes(
+ data.read_bytes(offset, u64::from(self.size_of_data.get(LE)))
+ .read_error("Invalid COFF import library data size")?,
+ );
+ let symbol = data
+ .read_string()
+ .map(ByteString)
+ .read_error("Could not read COFF import library symbol name")?;
+ let dll = data
+ .read_string()
+ .map(ByteString)
+ .read_error("Could not read COFF import library DLL name")?;
+ let export = if self.name_type() == pe::IMPORT_OBJECT_NAME_EXPORTAS {
+ data.read_string()
+ .map(ByteString)
+ .map(Some)
+ .read_error("Could not read COFF import library export name")?
+ } else {
+ None
+ };
+ Ok(ImportObjectData {
+ symbol,
+ dll,
+ export,
+ })
+ }
+
+ /// The type of import.
+ ///
+ /// This is one of the `IMPORT_OBJECT_*` constants.
+ pub fn import_type(&self) -> u16 {
+ self.name_type.get(LE) & pe::IMPORT_OBJECT_TYPE_MASK
+ }
+
+ /// The type of import name.
+ ///
+ /// This is one of the `IMPORT_OBJECT_*` constants.
+ pub fn name_type(&self) -> u16 {
+ (self.name_type.get(LE) >> pe::IMPORT_OBJECT_NAME_SHIFT) & pe::IMPORT_OBJECT_NAME_MASK
+ }
+}
+
+/// The data following `ImportObjectHeader`.
+#[derive(Debug, Clone)]
+pub struct ImportObjectData<'data> {
+ symbol: ByteString<'data>,
+ dll: ByteString<'data>,
+ export: Option<ByteString<'data>>,
+}
+
+impl<'data> ImportObjectData<'data> {
+ /// The public symbol name.
+ pub fn symbol(&self) -> &'data [u8] {
+ self.symbol.0
+ }
+
+ /// The name of the DLL to import the symbol from.
+ pub fn dll(&self) -> &'data [u8] {
+ self.dll.0
+ }
+
+ /// The name exported from the DLL.
+ ///
+ /// This is only set if the name is not derived from the symbol name.
+ pub fn export(&self) -> Option<&'data [u8]> {
+ self.export.map(|export| export.0)
+ }
+}
diff --git a/vendor/object/src/read/coff/mod.rs b/vendor/object/src/read/coff/mod.rs
index d5b3caf32..26020d797 100644
--- a/vendor/object/src/read/coff/mod.rs
+++ b/vendor/object/src/read/coff/mod.rs
@@ -16,3 +16,6 @@ pub use relocation::*;
mod comdat;
pub use comdat::*;
+
+mod import;
+pub use import::*;
diff --git a/vendor/object/src/read/elf/file.rs b/vendor/object/src/read/elf/file.rs
index aac66e7cc..67be37e21 100644
--- a/vendor/object/src/read/elf/file.rs
+++ b/vendor/object/src/read/elf/file.rs
@@ -161,6 +161,7 @@ where
(elf::EM_ARM, _) => Architecture::Arm,
(elf::EM_AVR, _) => Architecture::Avr,
(elf::EM_BPF, _) => Architecture::Bpf,
+ (elf::EM_CSKY, _) => Architecture::Csky,
(elf::EM_386, _) => Architecture::I386,
(elf::EM_X86_64, false) => Architecture::X86_64_X32,
(elf::EM_X86_64, true) => Architecture::X86_64,
diff --git a/vendor/object/src/read/elf/note.rs b/vendor/object/src/read/elf/note.rs
index fc5aa7753..84d4179de 100644
--- a/vendor/object/src/read/elf/note.rs
+++ b/vendor/object/src/read/elf/note.rs
@@ -113,21 +113,24 @@ impl<'data, Elf: FileHeader> Note<'data, Elf> {
self.header.n_descsz(endian)
}
- /// Return the bytes for the name field following the `NoteHeader`,
- /// excluding any null terminator.
+ /// Return the bytes for the name field following the `NoteHeader`.
///
- /// This field is usually a string including a null terminator
+ /// This field is usually a string including one or more trailing null bytes
/// (but it is not required to be).
///
- /// The length of this field (including any null terminator) is given by
- /// `n_namesz`.
+ /// The length of this field is given by `n_namesz`.
+ pub fn name_bytes(&self) -> &'data [u8] {
+ self.name
+ }
+
+ /// Return the bytes for the name field following the `NoteHeader`,
+ /// excluding all trailing null bytes.
pub fn name(&self) -> &'data [u8] {
- if let Some((last, name)) = self.name.split_last() {
- if *last == 0 {
- return name;
- }
+ let mut name = self.name;
+ while let [rest @ .., 0] = name {
+ name = rest;
}
- self.name
+ name
}
/// Return the bytes for the desc field following the `NoteHeader`.
diff --git a/vendor/object/src/read/elf/relocation.rs b/vendor/object/src/read/elf/relocation.rs
index 8443dbc75..78032dfdb 100644
--- a/vendor/object/src/read/elf/relocation.rs
+++ b/vendor/object/src/read/elf/relocation.rs
@@ -276,6 +276,11 @@ fn parse_relocation<Elf: FileHeader>(
elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
+ elf::EM_CSKY => match reloc.r_type(endian, false) {
+ elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32),
+ elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32),
+ r_type => (RelocationKind::Elf(r_type), 0),
+ },
elf::EM_386 => match reloc.r_type(endian, false) {
elf::R_386_32 => (RelocationKind::Absolute, 32),
elf::R_386_PC32 => (RelocationKind::Relative, 32),
diff --git a/vendor/object/src/read/elf/symbol.rs b/vendor/object/src/read/elf/symbol.rs
index ac1095705..ee5aa37f1 100644
--- a/vendor/object/src/read/elf/symbol.rs
+++ b/vendor/object/src/read/elf/symbol.rs
@@ -309,6 +309,14 @@ where
pub(super) symbol: &'data Elf::Sym,
}
+impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSymbol<'data, 'file, Elf, R> {
+ /// Return a reference to the raw symbol structure.
+ #[inline]
+ pub fn raw_symbol(&self) -> &'data Elf::Sym {
+ self.symbol
+ }
+}
+
impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> read::private::Sealed
for ElfSymbol<'data, 'file, Elf, R>
{
diff --git a/vendor/object/src/read/mod.rs b/vendor/object/src/read/mod.rs
index 0a450359f..8230d43ba 100644
--- a/vendor/object/src/read/mod.rs
+++ b/vendor/object/src/read/mod.rs
@@ -156,6 +156,9 @@ pub enum FileKind {
/// This supports a larger number of sections.
#[cfg(feature = "coff")]
CoffBig,
+ /// A Windows short import file.
+ #[cfg(feature = "coff")]
+ CoffImport,
/// A dyld cache file containing Mach-O images.
#[cfg(feature = "macho")]
DyldCache,
@@ -232,6 +235,7 @@ impl FileKind {
[0x00, b'a', b's', b'm', ..] => FileKind::Wasm,
#[cfg(feature = "pe")]
[b'M', b'Z', ..] if offset == 0 => {
+ // offset == 0 restriction is because optional_header_magic only looks at offset 0
match pe::optional_header_magic(data) {
Ok(crate::pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC) => {
FileKind::Pe32
@@ -253,16 +257,19 @@ impl FileKind {
// COFF x86-64
| [0x64, 0x86, ..] => FileKind::Coff,
#[cfg(feature = "coff")]
+ [0x00, 0x00, 0xff, 0xff, 0x00, 0x00, ..] => FileKind::CoffImport,
+ #[cfg(feature = "coff")]
[0x00, 0x00, 0xff, 0xff, 0x02, 0x00, ..] if offset == 0 => {
+ // offset == 0 restriction is because anon_object_class_id only looks at offset 0
match coff::anon_object_class_id(data) {
Ok(crate::pe::ANON_OBJECT_HEADER_BIGOBJ_CLASS_ID) => FileKind::CoffBig,
_ => return Err(Error("Unknown anon object file")),
}
}
#[cfg(feature = "xcoff")]
- [0x01, 0xDF, ..] => FileKind::Xcoff32,
+ [0x01, 0xdf, ..] => FileKind::Xcoff32,
#[cfg(feature = "xcoff")]
- [0x01, 0xF7, ..] => FileKind::Xcoff64,
+ [0x01, 0xf7, ..] => FileKind::Xcoff64,
_ => return Err(Error("Unknown file magic")),
};
Ok(kind)
diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs
index 8b9eadaf8..acc820c9e 100644
--- a/vendor/object/src/write/elf/object.rs
+++ b/vendor/object/src/write/elf/object.rs
@@ -126,6 +126,7 @@ impl<'a> Object<'a> {
Architecture::Arm => false,
Architecture::Avr => true,
Architecture::Bpf => false,
+ Architecture::Csky => true,
Architecture::I386 => false,
Architecture::X86_64 => true,
Architecture::X86_64_X32 => true,
@@ -329,6 +330,7 @@ impl<'a> Object<'a> {
Architecture::Arm => elf::EM_ARM,
Architecture::Avr => elf::EM_AVR,
Architecture::Bpf => elf::EM_BPF,
+ Architecture::Csky => elf::EM_CSKY,
Architecture::I386 => elf::EM_386,
Architecture::X86_64 => elf::EM_X86_64,
Architecture::X86_64_X32 => elf::EM_X86_64,
@@ -548,6 +550,16 @@ impl<'a> Object<'a> {
return Err(Error(format!("unimplemented relocation {:?}", reloc)));
}
},
+ Architecture::Csky => match (reloc.kind, reloc.encoding, reloc.size) {
+ (RelocationKind::Absolute, _, 32) => elf::R_CKCORE_ADDR32,
+ (RelocationKind::Relative, RelocationEncoding::Generic, 32) => {
+ elf::R_CKCORE_PCREL32
+ }
+ (RelocationKind::Elf(x), _, _) => x,
+ _ => {
+ return Err(Error(format!("unimplemented relocation {:?}", reloc)));
+ }
+ },
Architecture::I386 => match (reloc.kind, reloc.size) {
(RelocationKind::Absolute, 32) => elf::R_386_32,
(RelocationKind::Relative, 32) => elf::R_386_PC32,
diff --git a/vendor/object/src/write/macho.rs b/vendor/object/src/write/macho.rs
index 0e082b69d..e3ce55bb4 100644
--- a/vendor/object/src/write/macho.rs
+++ b/vendor/object/src/write/macho.rs
@@ -303,39 +303,29 @@ impl<'a> Object<'a> {
let sizeofcmds = offset - command_offset;
// Calculate size of section data.
- let mut segment_file_offset = None;
+ // Section data can immediately follow the load commands without any alignment padding.
+ let segment_file_offset = offset;
let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()];
let mut address = 0;
for (index, section) in self.sections.iter().enumerate() {
section_offsets[index].index = 1 + index;
if !section.is_bss() {
- let len = section.data.len();
- if len != 0 {
- offset = align(offset, section.align as usize);
- section_offsets[index].offset = offset;
- if segment_file_offset.is_none() {
- segment_file_offset = Some(offset);
- }
- offset += len;
- } else {
- section_offsets[index].offset = offset;
- }
address = align_u64(address, section.align);
section_offsets[index].address = address;
+ section_offsets[index].offset = segment_file_offset + address as usize;
address += section.size;
}
}
+ let segment_file_size = address as usize;
+ offset += address as usize;
for (index, section) in self.sections.iter().enumerate() {
- if section.kind.is_bss() {
- assert!(section.data.is_empty());
+ if section.is_bss() {
+ debug_assert!(section.data.is_empty());
address = align_u64(address, section.align);
section_offsets[index].address = address;
address += section.size;
}
}
- let segment_file_offset = segment_file_offset.unwrap_or(offset);
- let segment_file_size = offset - segment_file_offset;
- debug_assert!(segment_file_size as u64 <= address);
// Count symbols and add symbol strings to strtab.
let mut strtab = StringTable::default();
@@ -537,10 +527,8 @@ impl<'a> Object<'a> {
// Write section data.
for (index, section) in self.sections.iter().enumerate() {
- let len = section.data.len();
- if len != 0 {
- write_align(buffer, section.align as usize);
- debug_assert_eq!(section_offsets[index].offset, buffer.len());
+ if !section.is_bss() {
+ buffer.resize(section_offsets[index].offset);
buffer.write_bytes(&section.data);
}
}