MCPcopy Create free account
hub / github.com/MultiFuzz/MultiFuzz / from_elf

Function from_elf

icicle-cortexm/src/genconfig.rs:102–295  ·  view source on GitHub ↗

Attempts to generate a Fuzzware compatible config file from an ELF binary. Note: Unlike the original Fuzzware implementation, we rely entirely on the information included in the ELF file. We never attempt to manually identify sections.

(path: &Path)

Source from the content-addressed store, hash-verified

100/// Note: Unlike the original Fuzzware implementation, we rely entirely on the information included
101/// in the ELF file. We never attempt to manually identify sections.
102pub fn from_elf(path: &Path) -> anyhow::Result<FirmwareConfig> {
103 let data = std::fs::read(path)?;
104
105 // TODO: we parse the binary as a generic file, just to find names of sections we could avoid
106 // this by directly getting names specialized reader.
107 let obj_file = object::File::parse(data.as_slice())?;
108
109 let elf = object::elf::FileHeader32::<Endianness>::parse(data.as_slice())?;
110 let endian = elf.endian()?;
111
112 let file_name = path
113 .file_name()
114 .and_then(|x| x.to_str())
115 .ok_or_else(|| anyhow::format_err!("unable to extract file name"))?;
116
117 // Start with initial cortexm memory map.
118 let mut memory = cortexm_memory_map();
119 let ram_range = memory.get("ram").map(|x| x.base_addr..x.base_addr + x.size);
120
121 for section in obj_file.sections() {
122 tracing::info!(
123 "section \"{}\" address={:#x} size={:#x}",
124 section.name()?,
125 section.address(),
126 section.size()
127 );
128 }
129
130 // Determine what needs to be loaded by inspecting program headers
131 let program_headers = elf.program_headers(endian, data.as_slice())?;
132
133 for (idx, segment) in program_headers.into_iter().enumerate() {
134 if segment.p_type(endian) != object::elf::PT_LOAD {
135 continue;
136 }
137
138 let p_flags = segment.p_flags(endian);
139 let base_addr = segment.p_paddr(endian) as u64;
140 let vaddr = segment.p_vaddr(endian) as u64;
141 let in_memory_size = segment.p_memsz(endian) as u64;
142
143 // Find a name to use for the segment by looking at section headers (note: segments don't
144 // have a name for ELF files).
145 let range = vaddr..vaddr + in_memory_size.max(1);
146 let mut name =
147 find_section_name(&obj_file, range).unwrap_or_else(|| format!("memory_{base_addr:#x}"));
148
149 if let Some(suffix) = name.strip_prefix(".") {
150 name = suffix.into();
151 }
152
153 tracing::info!(
154 "PL_LOAD base_addr={base_addr:#x} (vaddr={vaddr:#x}) size={in_memory_size:#x} (name={name})"
155 );
156
157 if in_memory_size == 0 {
158 tracing::debug!("ignoring zero sized segment: Idx={idx}: {base_addr:#x} ({name})");
159 continue;

Callers 1

generate_and_saveFunction · 0.85

Calls 5

cortexm_memory_mapFunction · 0.85
find_section_nameFunction · 0.85
to_strMethod · 0.80
memory_rangeMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected