-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
'data' subcommand to print contents of section
- Loading branch information
Showing
13 changed files
with
254 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use getopts::Options; | ||
|
||
use crate::{commands::common::{options::*, Format}, result::Error}; | ||
|
||
const COMMON_ERROR: &str = "Unable to obtain section"; | ||
|
||
const SECT_FLAG_SHORT: &str = "s"; | ||
const SECT_FLAG_LONG: &str = "sect"; | ||
|
||
pub(super) struct Config { | ||
pub(super) format: Format, | ||
pub(super) seg: String, | ||
pub(super) sect: String, | ||
} | ||
|
||
impl Config { | ||
pub(super) fn build(opts: &mut Options, args: &[String]) -> crate::result::Result<Self> { | ||
let matches = match opts.parse(args.clone()) { | ||
Ok(m) => m, | ||
Err(f) => return Err(crate::result::Error::Text(f.to_string())), | ||
}; | ||
|
||
let _ = match matches.opt_positions(SECT_FLAG_SHORT).first() { | ||
Some(pos) => pos, | ||
None => return Err(Error::Text(COMMON_ERROR.to_string())), | ||
}; | ||
|
||
match Self::search_after_sect_opt(args) { | ||
Ok((seg, sect)) => { | ||
Ok(Self { | ||
format: Format::build(opts, args)?, | ||
seg: seg.clone(), | ||
sect: sect.clone(), | ||
}) | ||
}, | ||
Err(e) => Err(e), | ||
} | ||
} | ||
|
||
fn search_after_sect_opt(args: &[String]) -> crate::result::Result<(&String, &String)> { | ||
let short = &format!("-{SECT_FLAG_SHORT}"); | ||
let long = &format!("--{SECT_FLAG_LONG}"); | ||
let pos = args.iter().enumerate().find(|a| { | ||
let arg = a.1; | ||
arg == short || arg == long | ||
}); | ||
|
||
match pos { | ||
Some((pos, _)) => Self::search_names_at(args, pos + 1), | ||
None => Err(Error::Text(COMMON_ERROR.to_string())), | ||
} | ||
} | ||
|
||
fn search_names_at(args: &[String], pos: usize) -> crate::result::Result<(&String, &String)> { | ||
const ERROR_STR: &str = "Incorrect name pattern. Provide \"segname sectname\""; | ||
let strs = args.get(pos..=pos+1); | ||
match strs { | ||
Some(strs) => { | ||
let filtered: Vec<&String> = strs.iter().filter(|s| !s.starts_with("-")).collect(); | ||
if filtered.len() == 2 { | ||
Ok((filtered[0], filtered[1])) | ||
} else { | ||
return Err(Error::Text(ERROR_STR.to_string())); | ||
} | ||
}, | ||
None => Err(Error::Text(ERROR_STR.to_string())), | ||
} | ||
} | ||
} | ||
|
||
impl Config { | ||
fn required_option_items() -> Vec<OptionItem> { | ||
vec![ | ||
OptionItem { | ||
option_type: OptionType::Arg(IsRequired(true)), | ||
name: OptionName::ShortLong(SECT_FLAG_SHORT.to_string(), SECT_FLAG_LONG.to_string()), | ||
description: "Section to display".to_string(), | ||
hint: "segname sectname".to_string(), | ||
}, | ||
] | ||
} | ||
|
||
pub(super) fn option_items() -> Vec<OptionItem> { | ||
let mut items = Self::required_option_items(); | ||
items.append(&mut Format::option_items()); | ||
items | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use super::common; | ||
use super::common::options::AddToOptions; | ||
use super::common::ObjectFilter; | ||
use super::handler; | ||
use super::handler::*; | ||
use super::Printer; | ||
use super::Result; | ||
use crate::*; | ||
use colored::*; | ||
|
||
mod config; | ||
use config::*; | ||
use getopts::Options; | ||
|
||
static SUBCOMM_NAME: &str = "data"; | ||
|
||
pub(super) struct DataHandler { | ||
printer: Printer, | ||
} | ||
|
||
impl DataHandler { | ||
pub(super) fn new(printer: Printer) -> Self { | ||
Self { printer } | ||
} | ||
} | ||
|
||
impl Handler for DataHandler { | ||
fn command_name(&self) -> String { | ||
SUBCOMM_NAME.to_string() | ||
} | ||
|
||
fn description(&self) -> String { | ||
"Prints hex dump".to_string() | ||
} | ||
|
||
fn can_handle_with_name(&self, name: &str) -> bool { | ||
SUBCOMM_NAME == name | ||
} | ||
|
||
fn handle_object(&self, object: ObjectType, other_args: Vec<String>) -> Result<()> { | ||
let mut opts = Options::new(); | ||
self.accepted_option_items().add_to_opts(&mut opts); | ||
let config = Config::build(&mut opts, &other_args)?; | ||
let filter = ObjectFilter::build(&mut opts, &other_args)?; | ||
|
||
let objects = &filter.get_objects(object); | ||
let out_arch = objects.len() > 1; | ||
for (idx, obj) in objects.iter().enumerate() { | ||
if out_arch { | ||
common::out_single_arch_title( | ||
&self.printer, | ||
&obj.header(), | ||
idx, | ||
config.format.short, | ||
); | ||
} | ||
self.handle_load_commands(obj.load_commands_iterator(), &config); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn accepted_option_items(&self) -> Vec<common::options::OptionItem> { | ||
let mut items = handler::default_option_items(); | ||
items.append(&mut Config::option_items()); | ||
items | ||
} | ||
} | ||
|
||
impl DataHandler { | ||
fn handle_load_commands(&self, commands: LoadCommandIterator, config: &Config) { | ||
let segs = commands.filter_map(|cmd| match cmd.variant { | ||
LcVariant::Segment32(s) | LcVariant::Segment64(s) => { | ||
if s.segname.to_string() == config.seg { | ||
Some(s) | ||
} else { | ||
None | ||
} | ||
} | ||
_ => None, | ||
}); | ||
|
||
let sections = segs.filter_map(|seg| { | ||
seg.sections_iterator() | ||
.find(|s| s.sectname.to_string() == config.sect) | ||
}); | ||
|
||
for sect in sections { | ||
self.handle_section(sect); | ||
} | ||
} | ||
|
||
fn handle_section(&self, sect: Section) { | ||
use crate::output::hex::*; | ||
println!("{} {}", sect.segname.to_string().yellow(), sect.sectname.to_string().yellow()); | ||
|
||
_ = dump_section(§); | ||
println!("") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
use crate::result::Result; | ||
use kex::*; | ||
use std::io::{stdout}; | ||
|
||
use crate::Section; | ||
|
||
pub(crate) fn dump_section(sect: &Section) -> Result<()> { | ||
let fmt = Formatters::new( | ||
AddressFormatter::new(16), | ||
ByteFormatter::new(), | ||
CharFormatter::new(), | ||
); | ||
let config = Config::new(fmt, 16, 4, ("|".to_string(), '|'.to_string())); | ||
let mut out = Printer::new(Box::new(stdout()), sect.addr.0 as usize, config); | ||
let result = sect.read_data_to(&mut out); | ||
out.finish(); | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod table; | ||
pub mod hex; | ||
|
||
use colored::{self, ColoredString, Colorize}; | ||
use std::fmt::Display; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters