@@ -12,6 +12,8 @@ pub struct BinaryInfo {
12
12
pub symbols : HashMap < String , u64 > ,
13
13
pub bss_addr : u64 ,
14
14
pub bss_size : u64 ,
15
+ pub pyruntime_addr : u64 ,
16
+ pub pyruntime_size : u64 ,
15
17
#[ allow( dead_code) ]
16
18
pub addr : u64 ,
17
19
#[ allow( dead_code) ]
@@ -65,11 +67,23 @@ pub fn parse_binary(filename: &Path, addr: u64, size: u64) -> Result<BinaryInfo,
65
67
}
66
68
} ;
67
69
70
+ let mut pyruntime_addr = 0 ;
71
+ let mut pyruntime_size = 0 ;
68
72
let mut bss_addr = 0 ;
69
73
let mut bss_size = 0 ;
70
74
for segment in mach. segments . iter ( ) {
71
75
for ( section, _) in & segment. sections ( ) ? {
72
- if section. name ( ) ? == "__bss" {
76
+ let name = section. name ( ) ?;
77
+ if name == "PyRuntime" {
78
+ if let Some ( addr) = section. addr . checked_add ( offset) {
79
+ if addr. checked_add ( section. size ) . is_some ( ) {
80
+ pyruntime_addr = addr;
81
+ pyruntime_size = section. size ;
82
+ }
83
+ }
84
+ }
85
+
86
+ if name == "__bss" {
73
87
if let Some ( addr) = section. addr . checked_add ( offset) {
74
88
if addr. checked_add ( section. size ) . is_some ( ) {
75
89
bss_addr = addr;
@@ -94,6 +108,8 @@ pub fn parse_binary(filename: &Path, addr: u64, size: u64) -> Result<BinaryInfo,
94
108
symbols,
95
109
bss_addr,
96
110
bss_size,
111
+ pyruntime_addr,
112
+ pyruntime_size,
97
113
addr,
98
114
size,
99
115
} )
@@ -153,6 +169,21 @@ pub fn parse_binary(filename: &Path, addr: u64, size: u64) -> Result<BinaryInfo,
153
169
bss_end = bss_header. sh_addr + bss_header. sh_size ;
154
170
}
155
171
172
+ let pyruntime_header = elf. section_headers . iter ( ) . find ( |header| {
173
+ strtab
174
+ . get_at ( header. sh_name )
175
+ . map_or ( false , |name| name == ".PyRuntime" )
176
+ } ) ;
177
+
178
+ let mut pyruntime_addr = 0 ;
179
+ let mut pyruntime_size = 0 ;
180
+ if let Some ( header) = pyruntime_header {
181
+ if let Some ( addr) = header. sh_addr . checked_add ( offset) {
182
+ pyruntime_addr = addr;
183
+ pyruntime_size = header. sh_size ;
184
+ }
185
+ }
186
+
156
187
for sym in elf. syms . iter ( ) {
157
188
// Skip imported symbols
158
189
if sym. is_import ( )
@@ -194,6 +225,8 @@ pub fn parse_binary(filename: &Path, addr: u64, size: u64) -> Result<BinaryInfo,
194
225
symbols,
195
226
bss_addr,
196
227
bss_size,
228
+ pyruntime_addr,
229
+ pyruntime_size,
197
230
addr,
198
231
size,
199
232
} )
@@ -207,33 +240,48 @@ pub fn parse_binary(filename: &Path, addr: u64, size: u64) -> Result<BinaryInfo,
207
240
}
208
241
}
209
242
210
- pe. sections
211
- . iter ( )
212
- . find ( |section| section. name . starts_with ( b".data" ) )
213
- . ok_or_else ( || {
214
- format_err ! (
215
- "Failed to find .data section in PE binary of {}" ,
216
- filename. display( )
217
- )
218
- } )
219
- . map ( |data_section| {
220
- let mut bss_addr = 0 ;
221
- let mut bss_size = 0 ;
222
- if let Some ( addr) = offset. checked_add ( data_section. virtual_address as u64 ) {
223
- if addr. checked_add ( data_section. virtual_size as u64 ) . is_some ( ) {
243
+ let mut bss_addr = 0 ;
244
+ let mut bss_size = 0 ;
245
+ let mut pyruntime_addr = 0 ;
246
+ let mut pyruntime_size = 0 ;
247
+ let mut found_data = false ;
248
+ for section in pe. sections . iter ( ) {
249
+ if section. name . starts_with ( b".data" ) {
250
+ found_data = true ;
251
+ if let Some ( addr) = offset. checked_add ( section. virtual_address as u64 ) {
252
+ if addr. checked_add ( section. virtual_size as u64 ) . is_some ( ) {
224
253
bss_addr = addr;
225
- bss_size = u64:: from ( data_section . virtual_size ) ;
254
+ bss_size = u64:: from ( section . virtual_size ) ;
226
255
}
227
256
}
228
-
229
- BinaryInfo {
230
- symbols,
231
- bss_addr,
232
- bss_size,
233
- addr,
234
- size,
257
+ } else if section. name . starts_with ( b"PyRuntim" ) {
258
+ // note that the name is only 8 chars here, so we don't check for
259
+ // trailing 'e' in PyRuntime
260
+ if let Some ( addr) = offset. checked_add ( section. virtual_address as u64 ) {
261
+ if addr. checked_add ( section. virtual_size as u64 ) . is_some ( ) {
262
+ pyruntime_addr = addr;
263
+ pyruntime_size = u64:: from ( section. virtual_size ) ;
264
+ }
235
265
}
236
- } )
266
+ }
267
+ }
268
+
269
+ if !found_data {
270
+ return Err ( format_err ! (
271
+ "Failed to find .data section in PE binary of {}" ,
272
+ filename. display( )
273
+ ) ) ;
274
+ }
275
+
276
+ Ok ( BinaryInfo {
277
+ symbols,
278
+ bss_addr,
279
+ bss_size,
280
+ pyruntime_size,
281
+ pyruntime_addr,
282
+ addr,
283
+ size,
284
+ } )
237
285
}
238
286
_ => Err ( format_err ! ( "Unhandled binary type" ) ) ,
239
287
}
0 commit comments