Skip to content

Commit

Permalink
add functionality to insert items based on the elf section
Browse files Browse the repository at this point in the history
Examples:
    ... --characteristic-section .data
    ... --measurement-section .data

Fixes #24
  • Loading branch information
DanielT committed Apr 18, 2024
1 parent baf9f15 commit 6146c01
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/dwarf/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ mod test {
typenames: HashMap::new(),
demangled_names,
unit_names: vec![Some("file_a.c".to_string()), Some("file_b.c".to_string())],
sections: HashMap::new(),
};

// test iter.next_sibling()
Expand Down
26 changes: 24 additions & 2 deletions src/dwarf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ pub(crate) struct DebugData {
pub(crate) typenames: HashMap<String, Vec<usize>>,
pub(crate) demangled_names: HashMap<String, String>,
pub(crate) unit_names: Vec<Option<String>>,
pub(crate) sections: HashMap<String, (u64, u64)>,
}

struct DebugDataReader<'elffile> {
Expand All @@ -100,6 +101,7 @@ struct DebugDataReader<'elffile> {
units: UnitList<'elffile>,
unit_names: Vec<Option<String>>,
endian: Endianness,
sections: HashMap<String, (u64, u64)>,
}

impl DebugData {
Expand All @@ -109,12 +111,15 @@ impl DebugData {
let elffile = load_elf_file(&filename.to_string_lossy(), &filedata)?;
let dwarf = load_dwarf(&elffile)?;

let mut dbg_reader = DebugDataReader {
let sections = get_elf_sections(&elffile);

let dbg_reader = DebugDataReader {
dwarf,
verbose,
units: UnitList::new(),
unit_names: Vec::new(),
endian: elffile.endianness(),
sections,
};

Ok(dbg_reader.read_debug_info_entries())
Expand Down Expand Up @@ -159,6 +164,22 @@ fn load_elf_file<'data>(
}
}

fn get_elf_sections(elffile: &object::read::File) -> HashMap<String, (u64, u64)> {
let mut map = HashMap::new();

for section in elffile.sections() {
let addr = section.address();
let size = section.size();
if addr != 0 && size != 0 {
if let Ok(name) = section.name() {
map.insert(name.to_string(), (addr, addr + size));
}
}
}

map
}

// load the SWARF debug info from the .debug_<xyz> sections
fn load_dwarf<'data>(
elffile: &object::read::File<'data>,
Expand Down Expand Up @@ -195,7 +216,7 @@ fn get_endian(elffile: &object::read::File) -> RunTimeEndian {

impl<'elffile> DebugDataReader<'elffile> {
// read the debug information entries in the DWAF data to get all the global variables and their types
fn read_debug_info_entries(&mut self) -> DebugData {
fn read_debug_info_entries(mut self) -> DebugData {
let variables = self.load_variables();
let (types, typenames) = self.load_types(&variables);
let varname_list: Vec<&String> = variables.keys().collect();
Expand All @@ -210,6 +231,7 @@ impl<'elffile> DebugDataReader<'elffile> {
typenames,
demangled_names,
unit_names,
sections: self.sections,
}
}

Expand Down
67 changes: 63 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,16 +359,36 @@ fn core() -> Result<(), String> {
|| arg_matches.contains_id("INSERT_MEASUREMENT_RANGE")
|| arg_matches.contains_id("INSERT_CHARACTERISTIC_REGEX")
|| arg_matches.contains_id("INSERT_MEASUREMENT_REGEX")
|| arg_matches.contains_id("INSERT_CHARACTERISTIC_SECTION")
|| arg_matches.contains_id("INSERT_MEASUREMENT_SECTION")
{
cond_print!(verbose, now, "Inserting new items from range/regex");
cond_print!(
verbose,
now,
"Inserting new items from range, regex, or section"
);
let target_group = arg_matches
.get_one::<String>("TARGET_GROUP")
.map(|group| &**group);

let meas_ranges =
let mut meas_ranges =
range_args_to_ranges(arg_matches.get_many::<u64>("INSERT_MEASUREMENT_RANGE"));
let char_ranges =
let mut char_ranges =
range_args_to_ranges(arg_matches.get_many::<u64>("INSERT_CHARACTERISTIC_RANGE"));

let mut meas_section_ranges = section_args_to_ranges(
arg_matches.get_many::<String>("INSERT_MEASUREMENT_SECTION"),
debugdata,
verbose,
);
let mut char_section_ranges = section_args_to_ranges(
arg_matches.get_many::<String>("INSERT_CHARACTERISTIC_SECTION"),
debugdata,
verbose,
);
meas_ranges.append(&mut meas_section_ranges);
char_ranges.append(&mut char_section_ranges);

let meas_regexes: Vec<&str> =
match arg_matches.get_many::<String>("INSERT_MEASUREMENT_REGEX") {
Some(values) => values.map(|x| &**x).collect(),
Expand Down Expand Up @@ -688,6 +708,15 @@ fn get_args() -> ArgMatches {
.value_name("REGEX")
.action(clap::ArgAction::Append)
)
.arg(Arg::new("INSERT_CHARACTERISTIC_SECTION")
.help("Insert all variables from the given section as CHARACTERISTICs.")
.long("characteristic-section")
.aliases(["insert-characteristic-section"])
.number_of_values(1)
.requires("ELFFILE")
.value_name("SECTION")
.action(clap::ArgAction::Append)
)
.arg(Arg::new("INSERT_MEASUREMENT")
.help("Insert a MEASUREMENT based on a variable in the elf file. The variable name can be complex, e.g. var.element[0].subelement")
.short('M')
Expand Down Expand Up @@ -717,6 +746,15 @@ fn get_args() -> ArgMatches {
.value_name("REGEX")
.action(clap::ArgAction::Append)
)
.arg(Arg::new("INSERT_MEASUREMENT_SECTION")
.help("Insert all variables from the given section as MEASUREMENTs.")
.long("measurement-section")
.aliases(["insert-measurement-section"])
.number_of_values(1)
.requires("ELFFILE")
.value_name("SECTION")
.action(clap::ArgAction::Append)
)
.arg(Arg::new("TARGET_GROUP")
.help("When inserting items, put them into the group named in this option. The group will be created if it doe not exist.")
.long("target-group")
Expand All @@ -738,7 +776,8 @@ fn get_args() -> ArgMatches {
.group(
ArgGroup::new("INSERT_ARGGROUP")
.args(["INSERT_CHARACTERISTIC", "INSERT_CHARACTERISTIC_RANGE", "INSERT_CHARACTERISTIC_REGEX",
"INSERT_MEASUREMENT", "INSERT_MEASUREMENT_RANGE", "INSERT_MEASUREMENT_REGEX", ])
"INSERT_MEASUREMENT", "INSERT_MEASUREMENT_RANGE", "INSERT_MEASUREMENT_REGEX",
"INSERT_MEASUREMENT_SECTION", "INSERT_MEASUREMENT_SECTION", ])
.multiple(true)
)
.next_line_help(false)
Expand All @@ -758,6 +797,26 @@ fn range_args_to_ranges(args: Option<ValuesRef<u64>>) -> Vec<(u64, u64)> {
}
}

fn section_args_to_ranges(
args: Option<ValuesRef<String>>,
debug_data: &DebugData,
verbose: u8,
) -> Vec<(u64, u64)> {
if let Some(values) = args {
let mut addr_ranges: Vec<(u64, u64)> = Vec::new();
for section in values {
if let Some(range) = debug_data.sections.get(section).copied() {
addr_ranges.push(range);
} else if verbose > 0 {
println!("Cannot insert items from non-existent section {section}!");
}
}
addr_ranges
} else {
Vec::new()
}
}

#[derive(Clone)]
struct AddressValueParser;

Expand Down
3 changes: 3 additions & 0 deletions src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ mod test {
variables: IndexMap::new(),
demangled_names: HashMap::new(),
unit_names: Vec::new(),
sections: HashMap::new(),
};
// global variable: uint32_t my_array[2]
dbgdata.variables.insert(
Expand Down Expand Up @@ -410,6 +411,7 @@ mod test {
variables: IndexMap::new(),
demangled_names: HashMap::new(),
unit_names: Vec::new(),
sections: HashMap::new(),
};
// global variable defined in C like this:
// struct {
Expand Down Expand Up @@ -481,6 +483,7 @@ mod test {
variables: IndexMap::new(),
demangled_names: HashMap::new(),
unit_names: Vec::new(),
sections: HashMap::new(),
};
debug_data.types.insert(
0,
Expand Down

0 comments on commit 6146c01

Please sign in to comment.