Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keep-error-msg feature #740

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ xcoff = []

#=======================================
# By default, support all read features.
default = ["read", "compression"]
default = ["read", "compression", "keep-error-msg"]

#=======================================
# Umbrella feature for enabling all user-facing features of this crate. Does not
Expand Down Expand Up @@ -111,6 +111,8 @@ unstable-all = ["all", "unstable"]
# stable interface of this crate.
rustc-dep-of-std = ['core', 'compiler_builtins', 'alloc', 'memchr/rustc-dep-of-std']

keep-error-msg = []

[workspace]
members = ["crates/*"]
default-members = [".", "crates/examples"]
Expand Down
80 changes: 44 additions & 36 deletions src/build/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl<'data> Builder<'data> {
if index == symbols.section() {
SectionData::Symbol
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported SHT_SYMTAB section at index {}",
index
)));
Expand All @@ -242,7 +242,7 @@ impl<'data> Builder<'data> {
if index == symbols.shndx_section() {
SectionData::SymbolSectionIndex
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported SHT_SYMTAB_SHNDX section at index {}",
index
)));
Expand All @@ -252,7 +252,7 @@ impl<'data> Builder<'data> {
if index == dynamic_symbols.section() {
SectionData::DynamicSymbol
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported SHT_DYNSYM section at index {}",
index
)));
Expand All @@ -270,7 +270,7 @@ impl<'data> Builder<'data> {
// We simply need to preserve the data (similar to a .comment section).
SectionData::Data(section.data(endian, data)?.into())
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported SHT_STRTAB section at index {}",
index
)));
Expand Down Expand Up @@ -309,7 +309,7 @@ impl<'data> Builder<'data> {
| (elf::EM_X86_64, elf::SHT_X86_64_UNWIND) => {
SectionData::Data(section.data(endian, data)?.into())
}
_ => return Err(Error(format!("Unsupported section type {:x}", other))),
_ => return Err(Error::new(format!("Unsupported section type {:x}", other))),
},
};
let sh_flags = section.sh_flags(endian).into();
Expand All @@ -318,7 +318,7 @@ impl<'data> Builder<'data> {
None
} else {
if sh_link as usize >= sections.len() {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid sh_link {} in section at index {}",
sh_link, index
)));
Expand All @@ -330,7 +330,7 @@ impl<'data> Builder<'data> {
None
} else {
if sh_info as usize >= sections.len() {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid sh_info link {} in section at index {}",
sh_info, index
)));
Expand Down Expand Up @@ -430,7 +430,7 @@ impl<'data> Builder<'data> {
)
.map(SectionData::Relocation)
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid sh_link {} in relocation section at index {}",
link.0, index,
)));
Expand All @@ -453,7 +453,7 @@ impl<'data> Builder<'data> {
let rel = (*rel).into();
let symbol = if let Some(symbol) = rel.symbol(endian, is_mips64el) {
if symbol.0 >= symbols_len {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid symbol index {} in relocation section at index {}",
symbol, index,
)));
Expand Down Expand Up @@ -484,7 +484,7 @@ impl<'data> Builder<'data> {
let mut dynamics = Vec::with_capacity(dyns.len());
for d in dyns {
let tag = d.d_tag(endian).into().try_into().map_err(|_| {
Error(format!(
Error::new(format!(
"Unsupported dynamic tag 0x{:x}",
d.d_tag(endian).into()
))
Expand All @@ -494,12 +494,11 @@ impl<'data> Builder<'data> {
}
let val = d.d_val(endian).into();
dynamics.push(if d.is_string(endian) {
let val =
strings
.get(val.try_into().map_err(|_| {
Error(format!("Unsupported dynamic string 0x{:x}", val))
})?)
.map_err(|_| Error(format!("Invalid dynamic string 0x{:x}", val)))?;
let val = strings
.get(val.try_into().map_err(|_| {
Error::new(format!("Unsupported dynamic string 0x{:x}", val))
})?)
.map_err(|_| Error::new(format!("Invalid dynamic string 0x{:x}", val)))?;
Dynamic::String {
tag,
val: val.into(),
Expand Down Expand Up @@ -585,7 +584,7 @@ impl<'data> Builder<'data> {
while let Some(index) = indices.next()? {
let index = index as usize;
if index >= sections_len {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid section index {} in attribute",
index
)));
Expand All @@ -600,7 +599,7 @@ impl<'data> Builder<'data> {
while let Some(index) = indices.next()? {
let index = index as usize;
if index >= symbols_len {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid symbol index {} in attribute",
index
)));
Expand All @@ -610,7 +609,7 @@ impl<'data> Builder<'data> {
AttributeTag::Symbol(tag_symbols)
}
tag => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported attribute tag 0x{:x} in section at index {}",
tag, index,
)))
Expand Down Expand Up @@ -668,7 +667,10 @@ impl<'data> Builder<'data> {
let index = verdef.vd_ndx.get(endian) & elf::VERSYM_VERSION;
let id = self.versions.next_id();
if ids.insert(index, id).is_some() {
return Err(Error(format!("Duplicate SHT_GNU_VERDEF index {}", index)));
return Err(Error::new(format!(
"Duplicate SHT_GNU_VERDEF index {}",
index
)));
}

let mut names = Vec::new();
Expand Down Expand Up @@ -700,7 +702,10 @@ impl<'data> Builder<'data> {
let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION;
let id = self.versions.next_id();
if ids.insert(index, id).is_some() {
return Err(Error(format!("Duplicate SHT_GNU_VERNEED index {}", index)));
return Err(Error::new(format!(
"Duplicate SHT_GNU_VERNEED index {}",
index
)));
}

let data = VersionData::Need(VersionNeed {
Expand All @@ -724,9 +729,9 @@ impl<'data> Builder<'data> {
for (id, versym) in versyms.iter().skip(1).enumerate() {
let index = versym.0.get(endian);
let symbol = self.dynamic_symbols.get_mut(SymbolId(id));
symbol.version = *ids
.get(&(index & elf::VERSYM_VERSION))
.ok_or_else(|| Error(format!("Invalid SHT_GNU_VERSYM index {:x}", index)))?;
symbol.version = *ids.get(&(index & elf::VERSYM_VERSION)).ok_or_else(|| {
Error::new(format!("Invalid SHT_GNU_VERSYM index {:x}", index))
})?;
symbol.version_hidden = index & elf::VERSYM_HIDDEN != 0;
}
}
Expand Down Expand Up @@ -1134,7 +1139,7 @@ impl<'data> Builder<'data> {
if !self.segments.is_empty() {
// TODO: support program headers in other locations.
if self.header.e_phoff != writer.reserved_len() as u64 {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported e_phoff value 0x{:x}",
self.header.e_phoff
)));
Expand Down Expand Up @@ -1176,7 +1181,7 @@ impl<'data> Builder<'data> {
}

if section.sh_offset < writer.reserved_len() as u64 {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported sh_offset value 0x{:x} for section '{}', expected at least 0x{:x}",
section.sh_offset,
section.name,
Expand Down Expand Up @@ -1229,14 +1234,14 @@ impl<'data> Builder<'data> {
writer.reserve_gnu_verneed(verneed_count, vernaux_count)
}
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported alloc section type {:x} for section '{}'",
section.sh_type, section.name,
)));
}
};
if out_section.offset as u64 != section.sh_offset {
return Err(Error(format!(
return Err(Error::new(format!(
"Unaligned sh_offset value 0x{:x} for section '{}', expected 0x{:x}",
section.sh_offset, section.name, out_section.offset,
)));
Expand Down Expand Up @@ -1270,7 +1275,7 @@ impl<'data> Builder<'data> {
continue;
}
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported non-alloc section type {:x}",
section.sh_type
)));
Expand Down Expand Up @@ -1391,7 +1396,7 @@ impl<'data> Builder<'data> {
))?,
elf::DT_VERNEEDNUM => verneed_count as u64,
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Cannot generate value for dynamic tag 0x{:x}",
tag
)))
Expand Down Expand Up @@ -1488,7 +1493,10 @@ impl<'data> Builder<'data> {
if let VersionData::Def(def) = &version.data {
let mut names = def.names.iter();
let name = names.next().ok_or_else(|| {
Error(format!("Missing SHT_GNU_VERDEF name {}", version.id.0))
Error::new(format!(
"Missing SHT_GNU_VERDEF name {}",
version.id.0
))
})?;
writer.write_gnu_verdef(&write::elf::Verdef {
version: elf::VER_DEF_CURRENT,
Expand Down Expand Up @@ -1530,7 +1538,7 @@ impl<'data> Builder<'data> {
}
}
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported alloc section type {:x}",
section.sh_type
)));
Expand Down Expand Up @@ -1571,7 +1579,7 @@ impl<'data> Builder<'data> {
| SectionData::SymbolSectionIndex
| SectionData::String => {}
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unsupported non-alloc section type {:x}",
section.sh_type
)));
Expand Down Expand Up @@ -1655,7 +1663,7 @@ impl<'data> Builder<'data> {
}
SectionData::Attributes(_) => out_section.attributes.len() as u64,
_ => {
return Err(Error(format!(
return Err(Error::new(format!(
"Unimplemented size for section type {:x}",
section.sh_type
)))
Expand All @@ -1665,7 +1673,7 @@ impl<'data> Builder<'data> {
if let Some(index) = out_sections_index[id.0] {
index.0
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid sh_link from section '{}' to deleted section '{}'",
section.name,
self.sections.get(id).name,
Expand All @@ -1678,7 +1686,7 @@ impl<'data> Builder<'data> {
if let Some(index) = out_sections_index[id.0] {
index.0
} else {
return Err(Error(format!(
return Err(Error::new(format!(
"Invalid sh_info link from section '{}' to deleted section '{}'",
section.name,
self.sections.get(id).name,
Expand Down
38 changes: 30 additions & 8 deletions src/build/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use alloc::string::String;
#[cfg(feature = "keep-error-msg")]
use alloc::string::ToString;
use core::{fmt, result};
#[cfg(feature = "std")]
use std::error;
Expand All @@ -7,33 +9,53 @@ use crate::{read, write};

/// The error type used within the build module.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Error(pub(super) String);
pub struct Error(#[cfg(feature = "keep-error-msg")] pub(crate) String);

impl Error {
pub(super) fn new(message: impl Into<String>) -> Self {
Error(message.into())
#[inline(always)]
#[allow(dead_code)]
pub(super) fn new(#[allow(unused_variables)] message: impl Into<String>) -> Self {
Self(
#[cfg(feature = "keep-error-msg")]
message.into(),
)
}
}

impl fmt::Display for Error {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
f.write_str({
#[cfg(feature = "keep-error-msg")]
{
&self.0
}
#[cfg(not(feature = "keep-error-msg"))]
{
"Error"
}
})
}
}

#[cfg(feature = "std")]
impl error::Error for Error {}

impl From<read::Error> for Error {
fn from(error: read::Error) -> Error {
Error(format!("{}", error))
fn from(#[allow(unused_variables)] error: read::Error) -> Error {
Error(
#[cfg(feature = "keep-error-msg")]
error.0.to_string(),
)
}
}

impl From<write::Error> for Error {
fn from(error: write::Error) -> Error {
Error(error.0)
fn from(#[allow(unused_variables)] error: write::Error) -> Error {
Error(
#[cfg(feature = "keep-error-msg")]
error.0,
)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ impl<'data, R: ReadRef<'data>> File<'data, R> {
#[cfg(feature = "xcoff")]
FileKind::Xcoff64 => File::Xcoff64(xcoff::XcoffFile64::parse(data)?),
#[allow(unreachable_patterns)]
_ => return Err(Error("Unsupported file format")),
_ => return Err(Error::new("Unsupported file format")),
})
}

Expand All @@ -278,7 +278,7 @@ impl<'data, R: ReadRef<'data>> File<'data, R> {
Some(read::AddressSize::U32) => {
File::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?)
}
_ => return Err(Error("Unsupported file format")),
_ => return Err(Error::new("Unsupported file format")),
})
}

Expand Down
Loading
Loading