|
|
|
@ -3,6 +3,8 @@ use std::{
|
|
|
|
|
path::PathBuf,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub const LE_GLOBAL_SYMBOL_DUPLICATE: u32 = 701;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub enum Error {
|
|
|
|
|
IOError(Box<dyn std::error::Error>),
|
|
|
|
@ -11,19 +13,24 @@ pub enum Error {
|
|
|
|
|
InvalidSectionData,
|
|
|
|
|
ParseError(Box<dyn std::error::Error>),
|
|
|
|
|
TryFromIntError,
|
|
|
|
|
LinkingError(Trace),
|
|
|
|
|
LinkingError(LinkError),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "backtrace" for error origin
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
|
pub struct Trace {
|
|
|
|
|
pub code: u32, // specific trace code, should be >= 700
|
|
|
|
|
pub message: &'static str,
|
|
|
|
|
pub origin: PathBuf,
|
|
|
|
|
pub offset: u64, // 0 indicates unknown/invalid
|
|
|
|
|
pub source_info: Option<Box<dyn SourceInfo>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "backtrace" for error origin
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
|
pub struct LinkError {
|
|
|
|
|
pub code: u32, // specific trace code, should be >= 700
|
|
|
|
|
pub message: String,
|
|
|
|
|
pub traces: Vec<Trace>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
|
// used for programmatic input/output handling, IDE's etc.
|
|
|
|
|
pub fn code(&self) -> u32 {
|
|
|
|
@ -34,7 +41,7 @@ impl Error {
|
|
|
|
|
Error::InvalidSectionData => 400,
|
|
|
|
|
Error::ParseError(_) => 500,
|
|
|
|
|
Error::TryFromIntError => 600,
|
|
|
|
|
Error::LinkingError(trace) => trace.code,
|
|
|
|
|
Error::LinkingError(le) => le.code,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -73,23 +80,25 @@ impl Display for Error {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Display for Trace {
|
|
|
|
|
impl Display for LinkError {
|
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
let mut new_line = ""; // new line in case of previous info only
|
|
|
|
|
|
|
|
|
|
if let Some(origin) = self.origin.to_str() {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n\t{}", origin)?;
|
|
|
|
|
}
|
|
|
|
|
for trace in &self.traces {
|
|
|
|
|
if let Some(origin) = trace.origin.to_str() {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n\t{}", origin)?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if self.offset > 0 {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n@offset: {}", self.offset)?;
|
|
|
|
|
}
|
|
|
|
|
if trace.offset > 0 {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n@offset: {}", trace.offset)?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(si) = &self.source_info {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n{}", si)?;
|
|
|
|
|
if let Some(si) = &trace.source_info {
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
write!(f, "\n{}", si)?;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
write!(f, "{}{}", new_line, self.message)
|
|
|
|
|