summaryrefslogtreecommitdiffstats
path: root/vendor/object/src/read/xcoff
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/object/src/read/xcoff
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/object/src/read/xcoff')
-rw-r--r--vendor/object/src/read/xcoff/comdat.rs1
-rw-r--r--vendor/object/src/read/xcoff/relocation.rs1
-rw-r--r--vendor/object/src/read/xcoff/section.rs7
-rw-r--r--vendor/object/src/read/xcoff/segment.rs2
-rw-r--r--vendor/object/src/read/xcoff/symbol.rs121
5 files changed, 95 insertions, 37 deletions
diff --git a/vendor/object/src/read/xcoff/comdat.rs b/vendor/object/src/read/xcoff/comdat.rs
index eeed2f54d..2b23d1dba 100644
--- a/vendor/object/src/read/xcoff/comdat.rs
+++ b/vendor/object/src/read/xcoff/comdat.rs
@@ -109,7 +109,6 @@ pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> =
#[derive(Debug)]
pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
diff --git a/vendor/object/src/read/xcoff/relocation.rs b/vendor/object/src/read/xcoff/relocation.rs
index 8107a2e82..78c6acfc7 100644
--- a/vendor/object/src/read/xcoff/relocation.rs
+++ b/vendor/object/src/read/xcoff/relocation.rs
@@ -19,7 +19,6 @@ pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> =
/// An iterator over the relocations in a `XcoffSection`.
pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
diff --git a/vendor/object/src/read/xcoff/section.rs b/vendor/object/src/read/xcoff/section.rs
index 0944e10c8..77453fcd2 100644
--- a/vendor/object/src/read/xcoff/section.rs
+++ b/vendor/object/src/read/xcoff/section.rs
@@ -36,7 +36,7 @@ where
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, section)| XcoffSection {
- index: SectionIndex(index),
+ index: SectionIndex(index + 1),
file: self.file,
section,
})
@@ -54,7 +54,6 @@ pub type XcoffSection64<'data, 'file, R = &'data [u8]> =
#[derive(Debug)]
pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
@@ -252,9 +251,11 @@ where
}
/// Return the section header at the given index.
+ ///
+ /// The index is 1-based.
pub fn section(&self, index: SectionIndex) -> read::Result<&'data Xcoff::SectionHeader> {
self.sections
- .get(index.0)
+ .get(index.0.wrapping_sub(1))
.read_error("Invalid XCOFF section index")
}
}
diff --git a/vendor/object/src/read/xcoff/segment.rs b/vendor/object/src/read/xcoff/segment.rs
index 49969438d..7eca72367 100644
--- a/vendor/object/src/read/xcoff/segment.rs
+++ b/vendor/object/src/read/xcoff/segment.rs
@@ -19,7 +19,6 @@ pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> =
#[derive(Debug)]
pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
@@ -50,7 +49,6 @@ pub type XcoffSegment64<'data, 'file, R = &'data [u8]> =
#[derive(Debug)]
pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
diff --git a/vendor/object/src/read/xcoff/symbol.rs b/vendor/object/src/read/xcoff/symbol.rs
index 6738ad171..7ce215fac 100644
--- a/vendor/object/src/read/xcoff/symbol.rs
+++ b/vendor/object/src/read/xcoff/symbol.rs
@@ -5,9 +5,9 @@ use core::marker::PhantomData;
use core::str;
use crate::endian::{BigEndian as BE, U32Bytes};
-use crate::pod::Pod;
+use crate::pod::{bytes_of, Pod};
use crate::read::util::StringTable;
-use crate::{bytes_of, xcoff, Object, ObjectSection, SectionKind};
+use crate::xcoff;
use crate::read::{
self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex,
@@ -95,10 +95,10 @@ where
self.get::<Xcoff::Symbol>(index, 0)
}
- /// Return the file auxiliary symbol.
- pub fn aux_file(&self, index: usize) -> Result<&'data Xcoff::FileAux> {
+ /// Return a file auxiliary symbol.
+ pub fn aux_file(&self, index: usize, offset: usize) -> Result<&'data Xcoff::FileAux> {
debug_assert!(self.symbol(index)?.has_aux_file());
- let aux_file = self.get::<Xcoff::FileAux>(index, 1)?;
+ let aux_file = self.get::<Xcoff::FileAux>(index, offset)?;
if let Some(aux_type) = aux_file.x_auxtype() {
if aux_type != xcoff::AUX_FILE {
return Err(Error("Invalid index for file auxiliary symbol."));
@@ -145,7 +145,6 @@ pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> =
#[derive(Debug, Clone, Copy)]
pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
@@ -193,7 +192,6 @@ pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> =
/// An iterator over the symbols of an `XcoffFile`.
pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
@@ -240,7 +238,6 @@ pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> =
#[derive(Debug, Clone, Copy)]
pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]>
where
- 'data: 'file,
Xcoff: FileHeader,
R: ReadRef<'data>,
{
@@ -264,7 +261,14 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
}
fn name_bytes(&self) -> Result<&'data [u8]> {
- self.symbol.name(self.symbols.strings)
+ if self.symbol.has_aux_file() {
+ // By convention the file name is in the first auxiliary entry.
+ self.symbols
+ .aux_file(self.index.0, 1)?
+ .fname(self.symbols.strings)
+ } else {
+ self.symbol.name(self.symbols.strings)
+ }
}
fn name(&self) -> Result<&'data str> {
@@ -283,7 +287,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
| xcoff::C_HIDEXT
| xcoff::C_FCN
| xcoff::C_BLOCK
- | xcoff::C_STAT => self.symbol.n_value().into(),
+ | xcoff::C_STAT
+ | xcoff::C_INFO => self.symbol.n_value().into(),
_ => 0,
}
}
@@ -300,32 +305,46 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
{
let sym_type = aux_csect.sym_type() & 0x07;
if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
- aux_csect.x_scnlen()
- } else {
- 0
+ return aux_csect.x_scnlen();
}
- } else {
- 0
}
- } else {
- 0
}
+ 0
}
fn kind(&self) -> SymbolKind {
+ if self.symbol.has_aux_csect() {
+ if let Ok(aux_csect) = self
+ .file
+ .symbols
+ .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
+ {
+ let sym_type = aux_csect.sym_type() & 0x07;
+ if sym_type == xcoff::XTY_SD || sym_type == xcoff::XTY_CM {
+ return match aux_csect.x_smclas() {
+ xcoff::XMC_PR | xcoff::XMC_GL => SymbolKind::Text,
+ xcoff::XMC_RO | xcoff::XMC_RW | xcoff::XMC_TD | xcoff::XMC_BS => {
+ SymbolKind::Data
+ }
+ xcoff::XMC_TL | xcoff::XMC_UL => SymbolKind::Tls,
+ xcoff::XMC_DS | xcoff::XMC_TC0 | xcoff::XMC_TC => {
+ // `Metadata` might be a better kind for these if we had it.
+ SymbolKind::Data
+ }
+ _ => SymbolKind::Unknown,
+ };
+ } else if sym_type == xcoff::XTY_LD {
+ // A function entry point. Neither `Text` nor `Label` are a good fit for this.
+ return SymbolKind::Text;
+ } else if sym_type == xcoff::XTY_ER {
+ return SymbolKind::Unknown;
+ }
+ }
+ }
match self.symbol.n_sclass() {
- xcoff::C_FILE => SymbolKind::File,
xcoff::C_NULL => SymbolKind::Null,
- _ => self
- .file
- .section_by_index(SectionIndex((self.symbol.n_scnum() - 1) as usize))
- .map(|section| match section.kind() {
- SectionKind::Data | SectionKind::UninitializedData => SymbolKind::Data,
- SectionKind::UninitializedTls | SectionKind::Tls => SymbolKind::Tls,
- SectionKind::Text => SymbolKind::Text,
- _ => SymbolKind::Unknown,
- })
- .unwrap_or(SymbolKind::Unknown),
+ xcoff::C_FILE => SymbolKind::File,
+ _ => SymbolKind::Unknown,
}
}
@@ -407,8 +426,29 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
}
#[inline]
- fn flags(&self) -> SymbolFlags<SectionIndex> {
- SymbolFlags::None
+ fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
+ let mut x_smtyp = 0;
+ let mut x_smclas = 0;
+ let mut containing_csect = None;
+ if self.symbol.has_aux_csect() {
+ if let Ok(aux_csect) = self
+ .file
+ .symbols
+ .aux_csect(self.index.0, self.symbol.n_numaux() as usize)
+ {
+ x_smtyp = aux_csect.x_smtyp();
+ x_smclas = aux_csect.x_smclas();
+ if x_smtyp == xcoff::XTY_LD {
+ containing_csect = Some(SymbolIndex(aux_csect.x_scnlen() as usize))
+ }
+ }
+ }
+ SymbolFlags::Xcoff {
+ n_sclass: self.symbol.n_sclass(),
+ x_smtyp,
+ x_smclas,
+ containing_csect,
+ }
}
}
@@ -536,6 +576,27 @@ pub trait FileAux: Debug + Pod {
fn x_fname(&self) -> &[u8; 8];
fn x_ftype(&self) -> u8;
fn x_auxtype(&self) -> Option<u8>;
+
+ /// Parse the x_fname field, which may be an inline string or a string table offset.
+ fn fname<'data, R: ReadRef<'data>>(
+ &'data self,
+ strings: StringTable<'data, R>,
+ ) -> Result<&'data [u8]> {
+ let x_fname = self.x_fname();
+ if x_fname[0] == 0 {
+ // If the name starts with 0 then the last 4 bytes are a string table offset.
+ let offset = u32::from_be_bytes(x_fname[4..8].try_into().unwrap());
+ strings
+ .get(offset)
+ .read_error("Invalid XCOFF symbol name offset")
+ } else {
+ // The name is inline and padded with nulls.
+ Ok(match memchr::memchr(b'\0', x_fname) {
+ Some(end) => &x_fname[..end],
+ None => x_fname,
+ })
+ }
+ }
}
impl FileAux for xcoff::FileAux64 {