@@ -4,6 +4,7 @@ use std::cmp::Ordering;
44use crate :: chip:: Chip ;
55use crate :: flasher:: FlashSize ;
66use std:: fmt:: { Debug , Formatter } ;
7+ use std:: mem:: take;
78use xmas_elf:: sections:: { SectionData , ShType } ;
89use xmas_elf:: ElfFile ;
910
@@ -55,7 +56,7 @@ impl<'a> FirmwareImage<'a> {
5556 self . elf . header . pt2 . entry_point ( ) as u32
5657 }
5758
58- pub fn segments ( & ' a self ) -> impl Iterator < Item = CodeSegment > + ' a {
59+ pub fn segments ( & ' a self ) -> impl Iterator < Item = CodeSegment < ' a > > + ' a {
5960 self . elf
6061 . section_iter ( )
6162 . filter ( |header| {
@@ -74,56 +75,75 @@ impl<'a> FirmwareImage<'a> {
7475 } )
7576 }
7677
77- pub fn rom_segments ( & ' a self , chip : Chip ) -> impl Iterator < Item = CodeSegment > + ' a {
78+ pub fn rom_segments ( & ' a self , chip : Chip ) -> impl Iterator < Item = CodeSegment < ' a > > + ' a {
7879 self . segments ( )
7980 . filter ( move |segment| chip. addr_is_flash ( segment. addr ) )
8081 }
8182
82- pub fn ram_segments ( & ' a self , chip : Chip ) -> impl Iterator < Item = CodeSegment > + ' a {
83+ pub fn ram_segments ( & ' a self , chip : Chip ) -> impl Iterator < Item = CodeSegment < ' a > > + ' a {
8384 self . segments ( )
8485 . filter ( move |segment| !chip. addr_is_flash ( segment. addr ) )
8586 }
8687}
8788
8889#[ derive( Eq , Clone ) ]
8990/// A segment of code from the source elf
90- pub struct CodeSegment {
91+ pub struct CodeSegment < ' a > {
9192 pub addr : u32 ,
92- data : Vec < u8 > ,
93+ data : Cow < ' a , [ u8 ] > ,
9394}
9495
95- impl CodeSegment {
96- pub fn new ( addr : u32 , data : & [ u8 ] ) -> Self {
97- let mut data = data. to_vec ( ) ;
98-
96+ impl < ' a > CodeSegment < ' a > {
97+ pub fn new ( addr : u32 , data : & ' a [ u8 ] ) -> Self {
9998 // pad to 4 byte
10099 let padding = ( 4 - data. len ( ) % 4 ) % 4 ;
101- data. extend_from_slice ( & [ 0 ; 4 ] [ 0 ..padding] ) ;
102-
103- CodeSegment { addr, data }
100+ if padding == 0 {
101+ CodeSegment {
102+ addr,
103+ data : Cow :: Borrowed ( data) ,
104+ }
105+ } else {
106+ let mut data = data. to_vec ( ) ;
107+ data. extend_from_slice ( & [ 0 ; 4 ] [ 0 ..padding] ) ;
108+ CodeSegment {
109+ addr,
110+ data : Cow :: Owned ( data) ,
111+ }
112+ }
104113 }
105114
106115 /// Split of the first `count` bytes into a new segment, adjusting the remaining segment as needed
107116 pub fn split_off ( & mut self , count : usize ) -> Self {
108117 if count < self . data . len ( ) {
109- let rest = self . data . split_off ( count) ;
118+ let ( head, tail) = match take ( & mut self . data ) {
119+ Cow :: Borrowed ( data) => {
120+ let ( head, tail) = data. split_at ( count) ;
121+ ( Cow :: Borrowed ( head) , Cow :: Borrowed ( tail) )
122+ }
123+ Cow :: Owned ( mut data) => {
124+ let tail = data. split_off ( count) ;
125+ ( Cow :: Owned ( data) , Cow :: Owned ( tail) )
126+ }
127+ } ;
110128 let new = CodeSegment {
111129 addr : self . addr ,
112- data : self . data . split_off ( 0 ) ,
130+ data : head ,
113131 } ;
114132 self . addr += count as u32 ;
115- self . data = rest ;
133+ self . data = tail ;
116134 new
117135 } else {
118136 let new = self . clone ( ) ;
119137 self . addr += self . size ( ) ;
120- self . data = Vec :: new ( ) ;
138+ self . data = Cow :: Borrowed ( & [ ] ) ;
121139 new
122140 }
123141 }
124142
125- pub fn add ( & mut self , data : & [ u8 ] ) {
126- self . data . extend_from_slice ( data) ;
143+ pub fn add ( & mut self , extend : & [ u8 ] ) {
144+ let mut data = take ( & mut self . data ) . into_owned ( ) ;
145+ data. extend_from_slice ( extend) ;
146+ self . data = Cow :: Owned ( data) ;
127147 }
128148
129149 pub fn size ( & self ) -> u32 {
@@ -135,7 +155,7 @@ impl CodeSegment {
135155 }
136156}
137157
138- impl Debug for CodeSegment {
158+ impl Debug for CodeSegment < ' _ > {
139159 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
140160 f. debug_struct ( "CodeSegment" )
141161 . field ( "addr" , & self . addr )
@@ -144,19 +164,19 @@ impl Debug for CodeSegment {
144164 }
145165}
146166
147- impl PartialEq for CodeSegment {
167+ impl PartialEq for CodeSegment < ' _ > {
148168 fn eq ( & self , other : & Self ) -> bool {
149169 self . addr . eq ( & other. addr )
150170 }
151171}
152172
153- impl PartialOrd for CodeSegment {
173+ impl PartialOrd for CodeSegment < ' _ > {
154174 fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
155175 self . addr . partial_cmp ( & other. addr )
156176 }
157177}
158178
159- impl Ord for CodeSegment {
179+ impl Ord for CodeSegment < ' _ > {
160180 fn cmp ( & self , other : & Self ) -> Ordering {
161181 self . addr . cmp ( & other. addr )
162182 }
@@ -168,11 +188,11 @@ pub struct RomSegment<'a> {
168188 pub data : Cow < ' a , [ u8 ] > ,
169189}
170190
171- impl From < CodeSegment > for RomSegment < ' static > {
172- fn from ( segment : CodeSegment ) -> Self {
191+ impl < ' a > From < CodeSegment < ' a > > for RomSegment < ' a > {
192+ fn from ( segment : CodeSegment < ' a > ) -> Self {
173193 RomSegment {
174194 addr : segment. addr ,
175- data : Cow :: Owned ( segment. data ) ,
195+ data : segment. data ,
176196 }
177197 }
178198}
0 commit comments