use comfy_table::{Cell, Table}; use elf::ElfStream; use elf::endian::AnyEndian; use std::fs::File; /* From https://github.com/cole14/rust-readelf/blob/419f78ac79d2e5b538ffe28777b54a487d953840/src/rust-readelf.rs SPDX-SnippetBegin SPDX-License-Identifier: MIT SPDX-SnippetCopyrightText: Christopher Cole */ #[allow(dead_code)] pub fn print_dynamic_symbol_table(elf_file: &mut ElfStream) { // Get the .dynsym table. If this file doesn't have one, then we're done let (dynsyms, dynstrs) = match elf_file .dynamic_symbol_table() .expect("failed to get .dynsym and string table") { Some(tables) => tables, None => { return; } }; // Parse out all the symbols so that we can look up versions for them if needed. let symbols: Vec<(String, elf::symbol::Symbol)> = dynsyms .iter() .map(|sym| { ( dynstrs .get(sym.st_name as usize) .expect("failed to get symbol name") .to_string(), sym, ) }) .collect(); let vertab = elf_file .symbol_version_table() .expect("failed to parse GNU symbol versions"); let mut table = Table::new(); table.set_header([ "ndx", "value", "size", "type", "bind", "visibility", "shndx", "needs version", "name", ]); for (sym_idx, (sym_name, sym)) in symbols.iter().enumerate() { let needs_name = match &vertab { Some(vertab) => { if sym.is_undefined() { match vertab .get_requirement(sym_idx) .expect("failed to parse symbol requirement") { Some(req) => req.name, None => "None", } } else { "None" } } None => "None", }; let cells: Vec = vec![ sym_idx.into(), format!("{:#x}", sym.st_value).into(), sym.st_size.into(), elf::to_str::st_symtype_to_string(sym.st_symtype()).into(), elf::to_str::st_bind_to_string(sym.st_bind()).into(), elf::to_str::st_vis_to_string(sym.st_vis()).into(), sym.st_shndx.into(), needs_name.into(), sym_name.into(), ]; table.add_row(cells); } println!("{table}"); } /* SPDX-SnippetEnd */