From bb799349ff42249bd3203235b957014709cd5c44 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 11 Jul 2023 21:37:37 +0200 Subject: [PATCH 1/7] Create objdump file --- src/Tools/Tools.code-workspace | 2 +- src/Tools/readmap/src/main.rs | 45 +++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index aed8c246..77ceba0c 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -82,7 +82,7 @@ "", "--help", "--list -o ../Tests/Test_Planschbecken psx bin-cue ../Tests/ISO_Planschbecken.xml", - "${workspaceFolder}/../../examples/PoolBox/application/bin/PSX-release/PoolBox.map" + "--wsl ../../../examples/PoolBox/application/bin/PSX-release/PoolBox.elf" ], "default": "", "description": "Argument options to pass to cargo run" diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index 91445a6f..f380a065 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,16 +1,53 @@ use clap::Parser; use readmap::types::{Content::*, Section}; use tool_helper::{Error, exit_with_error}; -use std::{fs::File, io::{BufWriter, Write}, path::PathBuf}; +use std::{fs::File, io::{BufRead, BufReader, BufWriter, Write}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: Option + input: PathBuf, + #[clap(long="wsl", default_value_t=false)] + use_wsl: bool, +} + +fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { + let command_list = ["wsl", "objdump", "-x"]; + let start_idx = { + if use_wsl { + 0 + } + + else { + 1 + } + }; + let mut process = Command::new(command_list[start_idx]); + + for arg in command_list.iter().skip(start_idx + 1) { + process.arg(arg); + } + process.arg(input.to_str().ok_or_else(||{Error::from_str("Failed converting input string")})?); + + println!("Miau: {:?}", process); + Ok(process.stdout(Stdio::piped()).spawn()?) } fn run_main(cmd: CommandLine) -> Result<(), Error> { + let mut child = run_objdump(cmd.use_wsl, cmd.input)?; + if let Some(stdout) = &mut child.stdout { + for line in BufReader::new(stdout).lines() { + if let Ok(line) = line { + println!("{}", line); + } + } + } + + Ok(()) +} + +fn _run_main(cmd: CommandLine) -> Result<(), Error> { fn value_to_hex(value: T) -> String { return format!("0x{:X}", value); } @@ -25,8 +62,8 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { } } - let sections = readmap::scan(tool_helper::open_input(cmd.input)?)?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.txt"))?; + let sections = readmap::scan(tool_helper::open_input(Some(cmd.input))?)?; + let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; for section in sections { fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { From 947177661abacf042d8b61f3272a3a44200487b4 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 11 Jul 2023 22:00:57 +0200 Subject: [PATCH 2/7] Support scan stdout of objdump --- src/Tools/readmap/src/lib.rs | 196 +---------------------------- src/Tools/readmap/src/main.rs | 70 ++--------- src/Tools/readmap/src/types/mod.rs | 43 +++---- 3 files changed, 30 insertions(+), 279 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index abde9b95..03810f6d 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,196 +1,8 @@ pub mod types; -use tool_helper::{Error, Input}; -use std::io::BufRead; -use types::{Content, Section}; +use tool_helper::Error; +use types::MemoryMap; -pub fn scan(input: Input) -> Result, Error> { - let sections = process(input.lines().map(|l| l.unwrap()).into_iter())?; - - Ok(sections) -} - -fn process>(mut line_iter:F) -> Result, Error> { - let mut sections = Vec::new(); - while let Some(mut line) = line_iter.next() { - loop { - if line.starts_with(".") { - let (new_line, new_section) = process_section(line, &mut line_iter)?; - - sections.push(new_section); - line = new_line; - } - - else { - break; - } - } - } - - sections.sort_by(|left, right| { - left.adr.cmp(&right.adr) - }); - Ok(sections) -} - -fn process_section>(line: String, line_iter:&mut F) -> Result<(String, Section), Error> { - let mut next_line_closure = || { - line_iter.next().ok_or(Error::from_str("Unexpected end of file")) - }; - let (mut section, line) = read_section(line, &mut next_line_closure)?; - - Ok((process_subsection(&mut section, line, &mut next_line_closure)?, section)) -} - -fn process_subsection Result>(section: &mut Section, line: Option, next_line: &mut F) -> Result { - fn push_sub_section(section: &mut Section, sub_section: Option
) { - if let Some(sub_section) = sub_section { - section.content.push(Content::Section(sub_section)); - } - } - fn add_element(sub_section: Option
, section: &mut Section, value: T, callback: fn(&mut Section, T)) -> Option
{ - if let Some(mut sub_section) = sub_section { - callback(&mut sub_section, value); - Some(sub_section) - } - - else { - callback(section, value); - None - } - } - - let mut line = { - if let Some(line) = line { - line - } - - else { - next_line()? - } - }; - - let mut next_line_closure = || -> Result { - if let Ok(line) = next_line() { - return Ok(line); - } - - else { - // EOF - return Ok(String::from("")); - } - }; - - let mut sub_section = None; - - loop { - if line.starts_with(" .") { - push_sub_section(section, sub_section); - let (section, new_line) = read_section(line, &mut next_line_closure)?; - - sub_section = Some(section); - - if let Some(new_line) = new_line { - line = new_line; - continue; - } - } - - else if line.starts_with(" *fill*") { - let fill = read_fill(line)?; - sub_section = add_element(sub_section, section, fill, |section, fill| { - section.content.push(Content::Fill(fill)); - }); - } - - else if line.starts_with(" 0x") { - if let Some(symbol) = parse_symbol(read_symbol(line)?) { - sub_section = add_element(sub_section, section, symbol, |section, symbol| { - section.content.push(Content::Symbol(symbol)); - }); - } - } - - else if line.is_empty() { - push_sub_section(section, sub_section); - return Ok(line); - } - - line = next_line_closure()?; - } -} - -fn read_section Result>(mut line: String, next_line: &mut F) -> Result<(Section, Option), Error> { - let mut split_line = line.split_whitespace(); - let name = split_line.next().ok_or(Error::from_str("Couldn't locate section name"))?.to_string(); - let need_new_line = name.chars().count() > 16; - - if need_new_line { - line = next_line()?; - split_line = line.split_whitespace(); - } - - let adr = read_as::(split_line.next()); - if adr.is_none() { - return Ok((Section::new(name, None, None, None), { - if need_new_line { - Some(line) - } - - else { - None - } - })); - } - - let size = read_as::(split_line.next()); - let file = { - if let Some(file) = split_line.next() { - Some(file.to_string()) - } - - else { - None - } - }; - Ok((Section::new(name, adr, size, file), None)) -} - -fn read_fill(line: String) -> Result { - let mut split_line = line.split_whitespace().skip(1); - let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires an address")})?; - let size = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("*fill* statement requires a size")})?; - - Ok(types::Fill::new(adr, size)) -} - -fn read_symbol(line: String) -> Result { - let mut split_line = line.split_whitespace(); - let adr = read_as::(split_line.next()).ok_or_else(|| {return Error::from_str("Symbol statement requires an address")})?; - let mut name = split_line.next().ok_or_else(|| {return Error::from_str("Symbol statement requires a symbol name")})?.to_string(); - - for fragment in split_line { - name += fragment; - } - - Ok(types::Symbol::new(name, adr)) -} - -fn parse_symbol(mut symbol: types::Symbol) -> Option { - if symbol.name.starts_with(".") { - return None; - } - - symbol.name = symbol.name.split('=').next().unwrap().to_owned(); - Some(symbol) -} - -fn read_as(str: Option<&str>) -> Option { - if let Some(str) = str { - F::from_str_radix(str.trim_start_matches("0x"), 16).ok() - } - - else { - None - } +pub fn scan Option>(_next_line: F) -> Result { + Err(Error::not_implemented("scan")) } \ No newline at end of file diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index f380a065..bbc3954d 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,7 +1,6 @@ use clap::Parser; -use readmap::types::{Content::*, Section}; use tool_helper::{Error, exit_with_error}; -use std::{fs::File, io::{BufRead, BufReader, BufWriter, Write}, path::PathBuf, process::{Child, Command, Stdio}}; +use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] @@ -15,13 +14,8 @@ struct CommandLine { fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { let command_list = ["wsl", "objdump", "-x"]; let start_idx = { - if use_wsl { - 0 - } - - else { - 1 - } + if use_wsl {0} + else {1} }; let mut process = Command::new(command_list[start_idx]); @@ -30,65 +24,23 @@ fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { } process.arg(input.to_str().ok_or_else(||{Error::from_str("Failed converting input string")})?); - println!("Miau: {:?}", process); Ok(process.stdout(Stdio::piped()).spawn()?) } fn run_main(cmd: CommandLine) -> Result<(), Error> { let mut child = run_objdump(cmd.use_wsl, cmd.input)?; if let Some(stdout) = &mut child.stdout { - for line in BufReader::new(stdout).lines() { - if let Ok(line) = line { - println!("{}", line); - } - } + let mut line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); + + readmap::scan(|| { + line_iter.next() + })?; + Ok(()) } - Ok(()) -} - -fn _run_main(cmd: CommandLine) -> Result<(), Error> { - fn value_to_hex(value: T) -> String { - return format!("0x{:X}", value); + else { + Err(Error::from_str("Failed opening \"stdout\" for objdump")) } - - fn option_to_hex(value: Option) -> String { - if let Some(value) = value { - return value_to_hex(value); - } - - else { - return String::from(""); - } - } - - let sections = readmap::scan(tool_helper::open_input(Some(cmd.input))?)?; - let mut file = tool_helper::open_output_file(&PathBuf::from("./planschi.d"))?; - - for section in sections { - fn print_content(tab_level: usize, file: &mut BufWriter, section: Section) -> Result<(), Error> { - for content in section.content { - match content { - Fill(fill) => { - writeln!(file, "{:>tab_level$}*fill* @{}, {}", ' ', value_to_hex(fill.adr), value_to_hex(fill.size), tab_level=tab_level*4)?; - }, - Section(section) => { - writeln!(file, "{:>tab_level$} {} @{}, {}", ' ', section.name, option_to_hex(section.adr), option_to_hex(section.size), tab_level=tab_level*4)?; - print_content(tab_level + 1, file, section)?; - }, - Symbol(symbol) => { - writeln!(file, "{:>tab_level$}{} @{}", ' ', symbol.name, value_to_hex(symbol.adr), tab_level=tab_level*4)?; - } - } - } - - Ok(()) - } - - writeln!(file, "{}: @{}, {}", section.name, option_to_hex(section.adr), option_to_hex(section.size))?; - print_content(1, &mut file, section)?; - } - Ok(()) } pub fn main() { diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index 8d4b1493..80b60f7c 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -1,12 +1,23 @@ use std::default::Default; +#[derive(Default)] +pub struct MemoryMap { + pub global: Vec, + pub sections: Vec
+} + #[derive(Default)] pub struct Section { pub name: String, - pub adr: Option, - pub size: Option, - pub file: Option, - pub content: Vec + pub adr: u64, + pub size: usize, + pub symbols: Vec +} + +impl Section { + pub fn new(name: String, adr: u64, size: usize) -> Section { + Section{name, adr, size, symbols: Vec::new()} + } } #[derive(Default)] @@ -15,32 +26,8 @@ pub struct Symbol { pub adr: u64, } -#[derive(Default)] -pub struct Fill { - pub adr: u64, - pub size: usize, -} - -pub enum Content { - Fill(Fill), - Section(Section), - Symbol(Symbol), -} - -impl Section { - pub fn new(name: String, adr: Option, size: Option, file: Option) -> Section { - Section{name, adr, size, file, content: Vec::new()} - } -} - impl Symbol { pub fn new(name: String, adr: u64) -> Symbol { Symbol{name, adr} } -} - -impl Fill { - pub fn new(adr: u64, size: usize) -> Fill { - Fill{adr, size} - } } \ No newline at end of file From 59472a3f315962312fb3298ad11d1bf0f0eae269 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 11 Jul 2023 23:05:20 +0200 Subject: [PATCH 3/7] Parse with weird printf bug --- src/Tools/readmap/src/lib.rs | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 03810f6d..543bd42a 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,8 +1,46 @@ pub mod types; use tool_helper::Error; -use types::MemoryMap; +use types::{MemoryMap, Section}; -pub fn scan Option>(_next_line: F) -> Result { +pub fn scan Option>(mut next_line: F) -> Result { + const SECTION_IDENTIFIER:&'static str = "Sections:"; + const SYMBOL_TABLE_IDENTIFIER:&'static str = "SYMBOL TABLE:"; + + while let Some(line) = next_line() { + if line == SECTION_IDENTIFIER { + scan_sections(&mut next_line)?; + } + + if line == SYMBOL_TABLE_IDENTIFIER {} + } Err(Error::not_implemented("scan")) +} + +fn scan_sections Option>(next_line: &mut F) -> Result, Error> { + while let Some(_) = next_line() { + // We read every other line + let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; + let mut split_line = line.split_whitespace(); + if let Ok(_) = split_line_radix(&mut split_line, 10, "") { + let name = split_line.next().ok_or(Error::from_str("Failed reading Section Name"))?; + let size = split_line_radix(&mut split_line, 16, "Section Size")?; + let adr = split_line_radix(&mut split_line, 16, "Section Address")?; + + println!("\"{}\" @0x{:X} -> 0x{:X}", name, adr, (adr + size)); + } + + else { + return Err(Error::from_str("")); + } + } + + Err(Error::not_implemented("scan")) +} + +fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { + match u64::from_str_radix(split_line.next().ok_or(Error::from_text(format!("Failed reading: {}", value_name)))?, radix) { + Ok(value) => Ok(value), + Err(error) => Err(Error::from_text(format!("Converting value for {} failed with: {}", value_name, error))) + } } \ No newline at end of file From 2ab4e8b155339a7d8bb9bf9e3e6c17be95307605 Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 17 Jul 2023 18:41:15 +0200 Subject: [PATCH 4/7] Scan and print sections - prepare for SymbolTable --- src/Tools/readmap/src/lib.rs | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 543bd42a..932a58d9 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -7,17 +7,32 @@ pub fn scan Option>(mut next_line: F) -> Result Option>(next_line: &mut F) -> Result, Error> { +fn scan_sections Option>(next_line: &mut F, sections: &mut Vec
) -> Result { while let Some(_) = next_line() { // We read every other line let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; @@ -27,15 +42,15 @@ fn scan_sections Option>(next_line: &mut F) -> Result 0x{:X}", name, adr, (adr + size)); + sections.push(Section::new(name.to_string(), adr, size as usize)); } else { - return Err(Error::from_str("")); + return Ok(line); } } - Err(Error::not_implemented("scan")) + Err(Error::not_implemented("Failed obtaining complete section")) } fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { From 8d1dda56ef531edd15fd811659b14795adbf4975 Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 20 Jul 2023 20:31:25 +0200 Subject: [PATCH 5/7] Collect Symbols --- src/Tools/readmap/src/lib.rs | 65 +++++++++++++++++++++++++++--- src/Tools/readmap/src/types/mod.rs | 9 ++++- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 932a58d9..9dfd3c51 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,7 +1,7 @@ pub mod types; use tool_helper::Error; -use types::{MemoryMap, Section}; +use types::{MemoryMap, Section, Symbol}; pub fn scan Option>(mut next_line: F) -> Result { const SECTION_IDENTIFIER:&'static str = "Sections:"; @@ -19,23 +19,76 @@ pub fn scan Option>(mut next_line: F) -> Result ({})", memory_map.global.len()); for section in memory_map.sections { - println!("Name: {}", section.name); + println!("Name: {} ({})", section.name, section.symbols.len()); } - Err(Error::not_implemented("scan")) + Err(Error::from_str("Symbols should be sorted by address now - not implemented yet")) +} + +fn scan_symbols Option>(next_line: &mut F, memory_map: &mut MemoryMap) -> Result { + fn find_section<'a>(name: &str, memory_map: &'a mut MemoryMap) -> Option<&'a mut Section> { + for section in &mut memory_map.sections { + if section.name == name { + return Some(section); + } + } + + None + } + + fn skip_symbol(name: &str, section_name: &str) -> bool { + name == section_name || name.ends_with(".cpp") || name.ends_with(".c") || name.ends_with(".cxx") + } + + while let Some(line) = next_line() { + if line.chars().all(char::is_whitespace) { + return Ok(line); + } + + let split_count = line.split_whitespace().count(); + let mut split_line = line.split_whitespace(); + let adr = split_line_radix(&mut split_line, 16, "Address of Symbol")?; + let _type = split_line.next().ok_or(Error::from_str("Failed obtaining type of symbol"))?; + if split_count > 5 { + let _flag = split_line.next().ok_or(Error::from_str("Failed obtaining flag of symbol"))?; + } + let section = split_line.next().ok_or(Error::from_str("Failed obtaining section of symbol"))?; + let size = split_line_radix(&mut split_line, 16, "Size of Symbol")? as usize; + let name = split_line.next().ok_or(Error::from_str("Failed obtaining name of symbol"))?; + + if skip_symbol(name, section) { + // Not of interest + continue; + } + + let symbol = Symbol::new(name.to_string(), adr, size); + if let Some(section) = find_section(section, memory_map) { + if section.contains_adr(adr) { + section.symbols.push(symbol); + // Do not add to global cause they have a section + continue; + } + } + + memory_map.global.push(symbol); + } + + Err(Error::from_str("Failed obtaining all Symbols")) } fn scan_sections Option>(next_line: &mut F, sections: &mut Vec
) -> Result { while let Some(_) = next_line() { // We read every other line - let line = next_line().ok_or(Error::from_str("Failed skipping section line"))?; + let line = next_line().ok_or(Error::from_str("Failed skipping to next section"))?; let mut split_line = line.split_whitespace(); if let Ok(_) = split_line_radix(&mut split_line, 10, "") { let name = split_line.next().ok_or(Error::from_str("Failed reading Section Name"))?; @@ -50,7 +103,7 @@ fn scan_sections Option>(next_line: &mut F, sections: &mut } } - Err(Error::not_implemented("Failed obtaining complete section")) + Err(Error::from_str("Failed obtaining complete section")) } fn split_line_radix<'a>(split_line: &mut std::str::SplitWhitespace<'a>, radix: u32, value_name: &str) -> Result { diff --git a/src/Tools/readmap/src/types/mod.rs b/src/Tools/readmap/src/types/mod.rs index 80b60f7c..0509eda3 100644 --- a/src/Tools/readmap/src/types/mod.rs +++ b/src/Tools/readmap/src/types/mod.rs @@ -18,16 +18,21 @@ impl Section { pub fn new(name: String, adr: u64, size: usize) -> Section { Section{name, adr, size, symbols: Vec::new()} } + + pub fn contains_adr(&self, adr: u64) -> bool { + adr >= self.adr && adr < (self.adr + self.size as u64) + } } #[derive(Default)] pub struct Symbol { pub name: String, pub adr: u64, + pub size: usize } impl Symbol { - pub fn new(name: String, adr: u64) -> Symbol { - Symbol{name, adr} + pub fn new(name: String, adr: u64, size: usize) -> Symbol { + Symbol{name, adr, size} } } \ No newline at end of file From aa365c328e6904b92debd95f37ad0e84ea3de5bc Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 24 Jul 2023 20:41:38 +0200 Subject: [PATCH 6/7] Sort map --- src/Tools/readmap/src/lib.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 9dfd3c51..17e7c1d7 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -26,12 +26,28 @@ pub fn scan Option>(mut next_line: F) -> Result ({})", memory_map.global.len()); - for section in memory_map.sections { - println!("Name: {} ({})", section.name, section.symbols.len()); + sort_memory_map(&mut memory_map); + Ok(memory_map) +} + +fn sort_memory_map(memory_map: &mut MemoryMap) { + fn sort_symbol_vec(symbol_vec: &mut Vec) { + symbol_vec.sort_by(|a, b| { + a.adr.cmp(&b.adr) + }); + } + + fn sort_section_vec(section_vec: &mut Vec
) { + section_vec.sort_by(|a, b| { + a.adr.cmp(&b.adr) + }); + } + + sort_section_vec(&mut memory_map.sections); + sort_symbol_vec(&mut memory_map.global); + for section in &mut memory_map.sections { + sort_symbol_vec(&mut section.symbols); } - Err(Error::from_str("Symbols should be sorted by address now - not implemented yet")) } fn scan_symbols Option>(next_line: &mut F, memory_map: &mut MemoryMap) -> Result { From eb1546923894932dc07ec949e26458ce67b85fa1 Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 24 Jul 2023 22:22:17 +0200 Subject: [PATCH 7/7] Print memory map --- src/Tools/readmap/src/dump/mod.rs | 32 ++++++++++++++++++++ src/Tools/readmap/src/lib.rs | 1 + src/Tools/readmap/src/main.rs | 50 ++++++++++++++++++------------- 3 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 src/Tools/readmap/src/dump/mod.rs diff --git a/src/Tools/readmap/src/dump/mod.rs b/src/Tools/readmap/src/dump/mod.rs new file mode 100644 index 00000000..c5bb163b --- /dev/null +++ b/src/Tools/readmap/src/dump/mod.rs @@ -0,0 +1,32 @@ +use super::Error; +use super::types::{MemoryMap, Symbol}; +use tool_helper::Output; + +pub fn write(mut out: Output, memory_map: &MemoryMap) -> Result { + const NAME_WIDTH:usize = 64; + fn print_symbols(out: &mut Output, symbols: &Vec) -> Result<(), Error> { + for symbol in symbols { + let mut name = symbol.name.as_str(); + + if name.len() > NAME_WIDTH { + writeln!(out, "\t{}", name)?; + name = " "; + } + + writeln!(out, "\t{::")?; + print_symbols(&mut out, &memory_map.global)?; + for section in &memory_map.sections { + let section_end = section.adr + section.size as u64; + + writeln!(out, "{}: @0x{:X} - 0x{:X}", section.name, section.adr, section_end)?; + print_symbols(&mut out, §ion.symbols)?; + } + + Ok(out) +} \ No newline at end of file diff --git a/src/Tools/readmap/src/lib.rs b/src/Tools/readmap/src/lib.rs index 17e7c1d7..4bf8b38e 100644 --- a/src/Tools/readmap/src/lib.rs +++ b/src/Tools/readmap/src/lib.rs @@ -1,4 +1,5 @@ pub mod types; +pub mod dump; use tool_helper::Error; use types::{MemoryMap, Section, Symbol}; diff --git a/src/Tools/readmap/src/main.rs b/src/Tools/readmap/src/main.rs index bbc3954d..8f121ac1 100644 --- a/src/Tools/readmap/src/main.rs +++ b/src/Tools/readmap/src/main.rs @@ -1,14 +1,31 @@ use clap::Parser; use tool_helper::{Error, exit_with_error}; +use readmap::types::MemoryMap; use std::{io::{BufRead, BufReader}, path::PathBuf, process::{Child, Command, Stdio}}; #[derive(Parser)] #[clap(about = "Opens and scans a MAP file to print extended information", long_about = None)] struct CommandLine { #[clap(value_parser, help="Input MAP file for scannning")] - input: PathBuf, + input: PathBuf, #[clap(long="wsl", default_value_t=false)] - use_wsl: bool, + use_wsl: bool, + #[clap(short='o')] + output: Option +} + +pub fn main() { + match CommandLine::try_parse() { + Ok(cmd_line) => { + match run_main(cmd_line) { + Ok(_) => (), + Err(error) => exit_with_error(error) + } + }, + Err(error) => { + println!("{}", error) + } + } } fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { @@ -28,31 +45,24 @@ fn run_objdump(use_wsl: bool, input: PathBuf) -> Result { } fn run_main(cmd: CommandLine) -> Result<(), Error> { - let mut child = run_objdump(cmd.use_wsl, cmd.input)?; + let output = tool_helper::open_output(cmd.output)?; + let memory_map = generate_memory_map(cmd.use_wsl, cmd.input)?; + + readmap::dump::write(output, &memory_map)?; + Ok(()) +} + +fn generate_memory_map(use_wsl: bool, input: PathBuf) -> Result { + let mut child = run_objdump(use_wsl, input)?; if let Some(stdout) = &mut child.stdout { let mut line_iter = BufReader::new(stdout).lines().map(|l| l.unwrap()).into_iter(); readmap::scan(|| { line_iter.next() - })?; - Ok(()) + }) } else { Err(Error::from_str("Failed opening \"stdout\" for objdump")) - } + } } - -pub fn main() { - match CommandLine::try_parse() { - Ok(cmd_line) => { - match run_main(cmd_line) { - Ok(_) => (), - Err(error) => exit_with_error(error) - } - }, - Err(error) => { - println!("{}", error) - } - } -} \ No newline at end of file