2 releases

0.1.1 Jun 15, 2024
0.1.0 Jun 10, 2024

#613 in Parser implementations

Download history 184/week @ 2024-06-07 220/week @ 2024-06-14 60/week @ 2024-06-21

464 downloads per month

MIT license

115KB
3K SLoC

arm-attr

Parses ARM build attributes from ELF files according to the 2023Q3 ARM ABI.

Contents

Examples

The two examples below show two different methods to read build attributes: iterator (lazy and fast) and struct (eager and slow but correct).

By iterator

This first example reads the tags directly. It's faster, but:

  • It doesn't consider that one type of tag may appear multiple times.
  • It doesn't handle enclosing scopes, i.e. section or symbol-specific attributes.
  • If a tag could not be parsed, the iterator will stop with no error.
use arm_attr::{read::Endian, tag::Tag, BuildAttrs};

let data = [/* byte contents of .ARM.attributes */];
let build_attrs = BuildAttrs::new(&data, Endian::Little).unwrap();
for subsection in build_attrs.subsections() {
    let subsection = subsection.unwrap();
    if subsection.is_aeabi() {
        for (_, tag) in subsection.into_public_tag_iter().unwrap() {
            match tag {
                Tag::CpuName(name) => println!("CPU name: {name}"),
                _ => {}
            }
        }
    }
}

By struct

This second example collects all tags using into_public_attributes. It's slower but doesn't suffer from the flaws mentioned in the first example.

let data = [/* byte contents of .ARM.attributes */];
let build_attrs = BuildAttrs::new(&data, Endian::Little).unwrap();
for subsection in build_attrs.subsections() {
    let subsection = subsection.unwrap();
    if subsection.is_aeabi() {
        let file = subsection.into_public_attributes().unwrap();
        if let Some(name) = file.attributes.cpu_name {
            println!("CPU name: {name}");
        }
        for (sections, section) in file.sections {
            if let Some(name) = section.attributes.cpu_name {
                println!("CPU name in sections {sections:?}: {name}");
            }
            for (symbols, symbol) in section.symbols {
                if let Some(name) = symbol.attributes.cpu_name {
                    println!("CPU name in symbols {symbols:?} of sections {sections:?}: {name}");
                }
            }
        }
    }
}

Dependencies

~300–760KB
~18K SLoC