@@ -4,6 +4,7 @@ use std::cmp::Ordering;
4
4
use crate :: chip:: Chip ;
5
5
use crate :: flasher:: FlashSize ;
6
6
use std:: fmt:: { Debug , Formatter } ;
7
+ use std:: mem:: take;
7
8
use xmas_elf:: sections:: { SectionData , ShType } ;
8
9
use xmas_elf:: ElfFile ;
9
10
@@ -55,7 +56,7 @@ impl<'a> FirmwareImage<'a> {
55
56
self . elf . header . pt2 . entry_point ( ) as u32
56
57
}
57
58
58
- pub fn segments ( & ' a self ) -> impl Iterator < Item = CodeSegment > + ' a {
59
+ pub fn segments ( & ' a self ) -> impl Iterator < Item = CodeSegment < ' a > > + ' a {
59
60
self . elf
60
61
. section_iter ( )
61
62
. filter ( |header| {
@@ -74,56 +75,75 @@ impl<'a> FirmwareImage<'a> {
74
75
} )
75
76
}
76
77
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 {
78
79
self . segments ( )
79
80
. filter ( move |segment| chip. addr_is_flash ( segment. addr ) )
80
81
}
81
82
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 {
83
84
self . segments ( )
84
85
. filter ( move |segment| !chip. addr_is_flash ( segment. addr ) )
85
86
}
86
87
}
87
88
88
89
#[ derive( Eq , Clone ) ]
89
90
/// A segment of code from the source elf
90
- pub struct CodeSegment {
91
+ pub struct CodeSegment < ' a > {
91
92
pub addr : u32 ,
92
- data : Vec < u8 > ,
93
+ data : Cow < ' a , [ u8 ] > ,
93
94
}
94
95
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 {
99
98
// pad to 4 byte
100
99
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
+ }
104
113
}
105
114
106
115
/// Split of the first `count` bytes into a new segment, adjusting the remaining segment as needed
107
116
pub fn split_off ( & mut self , count : usize ) -> Self {
108
117
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
+ } ;
110
128
let new = CodeSegment {
111
129
addr : self . addr ,
112
- data : self . data . split_off ( 0 ) ,
130
+ data : head ,
113
131
} ;
114
132
self . addr += count as u32 ;
115
- self . data = rest ;
133
+ self . data = tail ;
116
134
new
117
135
} else {
118
136
let new = self . clone ( ) ;
119
137
self . addr += self . size ( ) ;
120
- self . data = Vec :: new ( ) ;
138
+ self . data = Cow :: Borrowed ( & [ ] ) ;
121
139
new
122
140
}
123
141
}
124
142
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) ;
127
147
}
128
148
129
149
pub fn size ( & self ) -> u32 {
@@ -135,7 +155,7 @@ impl CodeSegment {
135
155
}
136
156
}
137
157
138
- impl Debug for CodeSegment {
158
+ impl Debug for CodeSegment < ' _ > {
139
159
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
140
160
f. debug_struct ( "CodeSegment" )
141
161
. field ( "addr" , & self . addr )
@@ -144,19 +164,19 @@ impl Debug for CodeSegment {
144
164
}
145
165
}
146
166
147
- impl PartialEq for CodeSegment {
167
+ impl PartialEq for CodeSegment < ' _ > {
148
168
fn eq ( & self , other : & Self ) -> bool {
149
169
self . addr . eq ( & other. addr )
150
170
}
151
171
}
152
172
153
- impl PartialOrd for CodeSegment {
173
+ impl PartialOrd for CodeSegment < ' _ > {
154
174
fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
155
175
self . addr . partial_cmp ( & other. addr )
156
176
}
157
177
}
158
178
159
- impl Ord for CodeSegment {
179
+ impl Ord for CodeSegment < ' _ > {
160
180
fn cmp ( & self , other : & Self ) -> Ordering {
161
181
self . addr . cmp ( & other. addr )
162
182
}
@@ -168,11 +188,11 @@ pub struct RomSegment<'a> {
168
188
pub data : Cow < ' a , [ u8 ] > ,
169
189
}
170
190
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 {
173
193
RomSegment {
174
194
addr : segment. addr ,
175
- data : Cow :: Owned ( segment. data ) ,
195
+ data : segment. data ,
176
196
}
177
197
}
178
198
}
0 commit comments