Skip to content

Commit a5a01f7

Browse files
committed
use elf sections instead of elf segments for flashing
1 parent 898cbf6 commit a5a01f7

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

espflash/src/elf.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::cmp::Ordering;
33

44
use crate::chip::Chip;
55
use crate::flasher::FlashSize;
6-
use xmas_elf::program::{SegmentData, Type};
6+
use std::fmt::{Debug, Formatter};
7+
use xmas_elf::sections::{SectionData, ShType};
78
use xmas_elf::ElfFile;
89

910
pub const ESP_CHECKSUM_MAGIC: u8 = 0xef;
@@ -56,15 +57,18 @@ impl<'a> FirmwareImage<'a> {
5657

5758
pub fn segments(&'a self) -> impl Iterator<Item = CodeSegment<'a>> + 'a {
5859
self.elf
59-
.program_iter()
60+
.section_iter()
6061
.filter(|header| {
61-
header.file_size() > 0 && header.get_type() == Ok(Type::Load) && header.offset() > 0
62+
header.size() > 0
63+
&& header.get_type() == Ok(ShType::ProgBits)
64+
&& header.offset() > 0
65+
&& header.address() > 0
6266
})
6367
.flat_map(move |header| {
64-
let addr = header.virtual_addr() as u32;
65-
let size = header.file_size() as u32;
68+
let addr = header.address() as u32;
69+
let size = header.size() as u32;
6670
let data = match header.get_data(&self.elf) {
67-
Ok(SegmentData::Undefined(data)) => data,
71+
Ok(SectionData::Undefined(data)) => data,
6872
_ => return None,
6973
};
7074
Some(CodeSegment { addr, data, size })
@@ -82,14 +86,48 @@ impl<'a> FirmwareImage<'a> {
8286
}
8387
}
8488

85-
#[derive(Debug, Ord, Eq)]
89+
#[derive(Ord, Eq, Clone)]
8690
/// A segment of code from the source elf
8791
pub struct CodeSegment<'a> {
8892
pub addr: u32,
8993
pub size: u32,
9094
pub data: &'a [u8],
9195
}
9296

97+
impl<'a> CodeSegment<'a> {
98+
/// Split of the first `count` bytes into a new segment, adjusting the remaining segment as needed
99+
pub fn split_off(&mut self, count: usize) -> CodeSegment<'a> {
100+
if count < self.data.len() {
101+
let data = &self.data[0..count];
102+
let new = CodeSegment {
103+
addr: self.addr,
104+
size: data.len() as u32,
105+
data,
106+
};
107+
self.addr += data.len() as u32;
108+
self.size += data.len() as u32;
109+
self.data = &self.data[count..];
110+
new
111+
} else {
112+
let new = self.clone();
113+
self.addr += self.size;
114+
self.size = 0;
115+
self.data = &[];
116+
new
117+
}
118+
}
119+
}
120+
121+
impl Debug for CodeSegment<'_> {
122+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123+
f.debug_struct("CodeSegment")
124+
.field("addr", &self.addr)
125+
.field("size", &self.size)
126+
.field("data", &"...")
127+
.finish()
128+
}
129+
}
130+
93131
impl PartialEq for CodeSegment<'_> {
94132
fn eq(&self, other: &Self) -> bool {
95133
self.addr.eq(&other.addr)

0 commit comments

Comments
 (0)