summaryrefslogtreecommitdiffstats
path: root/vendor/gimli-0.27.3/examples/dwarf-validate.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gimli-0.27.3/examples/dwarf-validate.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gimli-0.27.3/examples/dwarf-validate.rs')
-rw-r--r--vendor/gimli-0.27.3/examples/dwarf-validate.rs267
1 files changed, 0 insertions, 267 deletions
diff --git a/vendor/gimli-0.27.3/examples/dwarf-validate.rs b/vendor/gimli-0.27.3/examples/dwarf-validate.rs
deleted file mode 100644
index 54d8f3a1d..000000000
--- a/vendor/gimli-0.27.3/examples/dwarf-validate.rs
+++ /dev/null
@@ -1,267 +0,0 @@
-// Allow clippy lints when building without clippy.
-#![allow(unknown_lints)]
-
-use gimli::{AttributeValue, UnitHeader};
-use object::{Object, ObjectSection};
-use rayon::prelude::*;
-use std::borrow::{Borrow, Cow};
-use std::env;
-use std::fs;
-use std::io::{self, BufWriter, Write};
-use std::iter::Iterator;
-use std::path::{Path, PathBuf};
-use std::process;
-use std::sync::Mutex;
-use typed_arena::Arena;
-
-trait Reader: gimli::Reader<Offset = usize> + Send + Sync {
- type SyncSendEndian: gimli::Endianity + Send + Sync;
-}
-
-impl<'input, Endian> Reader for gimli::EndianSlice<'input, Endian>
-where
- Endian: gimli::Endianity + Send + Sync,
-{
- type SyncSendEndian = Endian;
-}
-
-struct ErrorWriter<W: Write + Send> {
- inner: Mutex<(W, usize)>,
- path: PathBuf,
-}
-
-impl<W: Write + Send> ErrorWriter<W> {
- #[allow(clippy::needless_pass_by_value)]
- fn error(&self, s: String) {
- let mut lock = self.inner.lock().unwrap();
- writeln!(&mut lock.0, "DWARF error in {}: {}", self.path.display(), s).unwrap();
- lock.1 += 1;
- }
-}
-
-fn main() {
- let mut w = BufWriter::new(io::stdout());
- let mut errors = 0;
- for arg in env::args_os().skip(1) {
- let path = Path::new(&arg);
- let file = match fs::File::open(&path) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to open file '{}': {}", path.display(), err);
- errors += 1;
- continue;
- }
- };
- let file = match unsafe { memmap2::Mmap::map(&file) } {
- Ok(mmap) => mmap,
- Err(err) => {
- eprintln!("Failed to map file '{}': {}", path.display(), &err);
- errors += 1;
- continue;
- }
- };
- let file = match object::File::parse(&*file) {
- Ok(file) => file,
- Err(err) => {
- eprintln!("Failed to parse file '{}': {}", path.display(), err);
- errors += 1;
- continue;
- }
- };
-
- let endian = if file.is_little_endian() {
- gimli::RunTimeEndian::Little
- } else {
- gimli::RunTimeEndian::Big
- };
- let mut error_writer = ErrorWriter {
- inner: Mutex::new((&mut w, 0)),
- path: path.to_owned(),
- };
- validate_file(&mut error_writer, &file, endian);
- errors += error_writer.inner.into_inner().unwrap().1;
- }
- // Flush any errors.
- drop(w);
- if errors > 0 {
- process::exit(1);
- }
-}
-
-fn validate_file<W, Endian>(w: &mut ErrorWriter<W>, file: &object::File, endian: Endian)
-where
- W: Write + Send,
- Endian: gimli::Endianity + Send + Sync,
-{
- let arena = Arena::new();
-
- fn load_section<'a, 'file, 'input, S, Endian>(
- arena: &'a Arena<Cow<'file, [u8]>>,
- file: &'file object::File<'input>,
- endian: Endian,
- ) -> S
- where
- S: gimli::Section<gimli::EndianSlice<'a, Endian>>,
- Endian: gimli::Endianity + Send + Sync,
- 'file: 'input,
- 'a: 'file,
- {
- let data = match file.section_by_name(S::section_name()) {
- Some(ref section) => section
- .uncompressed_data()
- .unwrap_or(Cow::Borrowed(&[][..])),
- None => Cow::Borrowed(&[][..]),
- };
- let data_ref = (*arena.alloc(data)).borrow();
- S::from(gimli::EndianSlice::new(data_ref, endian))
- }
-
- // Variables representing sections of the file. The type of each is inferred from its use in the
- // validate_info function below.
- let debug_abbrev = &load_section(&arena, file, endian);
- let debug_info = &load_section(&arena, file, endian);
-
- validate_info(w, debug_info, debug_abbrev);
-}
-
-struct UnitSummary {
- // True if we successfully parsed all the DIEs and attributes in the compilation unit
- internally_valid: bool,
- offset: gimli::DebugInfoOffset,
- die_offsets: Vec<gimli::UnitOffset>,
- global_die_references: Vec<(gimli::UnitOffset, gimli::DebugInfoOffset)>,
-}
-
-fn validate_info<W, R>(
- w: &mut ErrorWriter<W>,
- debug_info: &gimli::DebugInfo<R>,
- debug_abbrev: &gimli::DebugAbbrev<R>,
-) where
- W: Write + Send,
- R: Reader,
-{
- let mut units = Vec::new();
- let mut units_iter = debug_info.units();
- let mut last_offset = 0;
- loop {
- let u = match units_iter.next() {
- Err(err) => {
- w.error(format!(
- "Can't read unit header at offset {:#x}, stopping reading units: {}",
- last_offset, err
- ));
- break;
- }
- Ok(None) => break,
- Ok(Some(u)) => u,
- };
- last_offset = u.offset().as_debug_info_offset().unwrap().0 + u.length_including_self();
- units.push(u);
- }
- let process_unit = |unit: UnitHeader<R>| -> UnitSummary {
- let unit_offset = unit.offset().as_debug_info_offset().unwrap();
- let mut ret = UnitSummary {
- internally_valid: false,
- offset: unit_offset,
- die_offsets: Vec::new(),
- global_die_references: Vec::new(),
- };
- let abbrevs = match unit.abbreviations(debug_abbrev) {
- Ok(abbrevs) => abbrevs,
- Err(err) => {
- w.error(format!(
- "Invalid abbrevs for unit {:#x}: {}",
- unit_offset.0, &err
- ));
- return ret;
- }
- };
- let mut entries = unit.entries(&abbrevs);
- let mut unit_refs = Vec::new();
- loop {
- let (_, entry) = match entries.next_dfs() {
- Err(err) => {
- w.error(format!(
- "Invalid DIE for unit {:#x}: {}",
- unit_offset.0, &err
- ));
- return ret;
- }
- Ok(None) => break,
- Ok(Some(entry)) => entry,
- };
- ret.die_offsets.push(entry.offset());
-
- let mut attrs = entry.attrs();
- loop {
- let attr = match attrs.next() {
- Err(err) => {
- w.error(format!(
- "Invalid attribute for unit {:#x} at DIE {:#x}: {}",
- unit_offset.0,
- entry.offset().0,
- &err
- ));
- return ret;
- }
- Ok(None) => break,
- Ok(Some(attr)) => attr,
- };
- match attr.value() {
- AttributeValue::UnitRef(offset) => {
- unit_refs.push((entry.offset(), offset));
- }
- AttributeValue::DebugInfoRef(offset) => {
- ret.global_die_references.push((entry.offset(), offset));
- }
- _ => (),
- }
- }
- }
- ret.internally_valid = true;
- ret.die_offsets.shrink_to_fit();
- ret.global_die_references.shrink_to_fit();
-
- // Check intra-unit references
- for (from, to) in unit_refs {
- if ret.die_offsets.binary_search(&to).is_err() {
- w.error(format!(
- "Invalid intra-unit reference in unit {:#x} from DIE {:#x} to {:#x}",
- unit_offset.0, from.0, to.0
- ));
- }
- }
-
- ret
- };
- let processed_units = units.into_par_iter().map(process_unit).collect::<Vec<_>>();
-
- let check_unit = |summary: &UnitSummary| {
- if !summary.internally_valid {
- return;
- }
- for &(from, to) in summary.global_die_references.iter() {
- let u = match processed_units.binary_search_by_key(&to, |v| v.offset) {
- Ok(i) => &processed_units[i],
- Err(i) => {
- if i > 0 {
- &processed_units[i - 1]
- } else {
- w.error(format!("Invalid cross-unit reference in unit {:#x} from DIE {:#x} to global DIE {:#x}: no unit found",
- summary.offset.0, from.0, to.0));
- continue;
- }
- }
- };
- if !u.internally_valid {
- continue;
- }
- let to_offset = gimli::UnitOffset(to.0 - u.offset.0);
- if u.die_offsets.binary_search(&to_offset).is_err() {
- w.error(format!("Invalid cross-unit reference in unit {:#x} from DIE {:#x} to global DIE {:#x}: unit at {:#x} contains no DIE {:#x}",
- summary.offset.0, from.0, to.0, u.offset.0, to_offset.0));
- }
- }
- };
- processed_units.par_iter().for_each(check_unit);
-}