1
+ use super :: mystd:: ffi:: { OsStr , OsString } ;
2
+ use super :: mystd:: os:: unix:: ffi:: OsStrExt ;
1
3
use super :: mystd:: str;
2
4
use super :: { Context , Mapping , Path , Stash , Vec } ;
5
+ use core:: ops:: Deref ;
6
+ use object:: read:: archive:: ArchiveFile ;
3
7
use object:: read:: xcoff:: FileHeader ;
4
8
use object:: read:: xcoff:: SectionHeader ;
5
9
use object:: read:: xcoff:: XcoffFile ;
@@ -13,10 +17,26 @@ type Xcoff = object::xcoff::FileHeader32;
13
17
type Xcoff = object:: xcoff:: FileHeader64 ;
14
18
15
19
impl Mapping {
16
- pub fn new ( path : & Path ) -> Option < Mapping > {
20
+ pub fn new ( path : & Path , member_name : & OsString ) -> Option < Mapping > {
17
21
let map = super :: mmap ( path) ?;
18
22
Mapping :: mk ( map, |data, stash| {
19
- Context :: new ( stash, Object :: parse ( data) ?, None )
23
+ if member_name. is_empty ( ) {
24
+ Context :: new ( stash, Object :: parse ( data) ?, None )
25
+ } else {
26
+ let archive = ArchiveFile :: parse ( data) . ok ( ) ?;
27
+ for member in archive. members ( ) {
28
+ if let Ok ( member) = member {
29
+ let name = OsStr :: from_bytes ( member. name ( ) ) ;
30
+ if name == member_name {
31
+ let member_data = member. data ( data) . ok ( ) ?;
32
+ if let Some ( obj) = Object :: parse ( member_data) {
33
+ return Context :: new ( stash, obj, None ) ;
34
+ }
35
+ }
36
+ }
37
+ }
38
+ None
39
+ }
20
40
} )
21
41
}
22
42
}
@@ -38,10 +58,10 @@ pub struct Image {
38
58
pub size : usize ,
39
59
}
40
60
41
- pub fn get_text_image ( data : & [ u8 ] ) -> Option < Image > {
61
+ pub fn parse_xcoff ( data : & [ u8 ] ) -> Option < Image > {
42
62
let mut offset = 0 ;
43
63
let header = Xcoff :: parse ( data, & mut offset) . ok ( ) ?;
44
- let aux_header = header. aux_header ( data, & mut offset) . ok ( ) ?;
64
+ let _ = header. aux_header ( data, & mut offset) . ok ( ) ?;
45
65
let sections = header. sections ( data, & mut offset) . ok ( ) ?;
46
66
if let Some ( section) = sections. iter ( ) . find ( |s| {
47
67
let name = str:: from_utf8 ( & s. s_name ( ) [ 0 ..5 ] ) . unwrap ( ) ;
@@ -56,19 +76,45 @@ pub fn get_text_image(data: &[u8]) -> Option<Image> {
56
76
return None ;
57
77
}
58
78
79
+ pub fn parse_image ( path : & Path , member_name : & OsString ) -> Option < Image > {
80
+ let map = super :: mmap ( path) ?;
81
+ let data = map. deref ( ) ;
82
+ if member_name. is_empty ( ) {
83
+ return parse_xcoff ( data) ;
84
+ } else {
85
+ let archive = ArchiveFile :: parse ( data) . ok ( ) ?;
86
+ for member in archive. members ( ) {
87
+ if let Ok ( member) = member {
88
+ let name = OsStr :: from_bytes ( member. name ( ) ) ;
89
+ if name == member_name {
90
+ let member_data = member. data ( data) . ok ( ) ?;
91
+ if let Some ( image) = parse_xcoff ( member_data) {
92
+ return Some ( image) ;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ return None ;
98
+ }
99
+ }
100
+
59
101
impl < ' a > Object < ' a > {
60
102
fn parse ( data : & ' a [ u8 ] ) -> Option < Object < ' a > > {
61
103
let file = XcoffFile :: parse ( data) . ok ( ) ?;
62
104
let mut syms = file
63
105
. symbols ( )
64
- . map ( |sym| {
106
+ . filter_map ( |sym| {
65
107
let address = sym. address ( ) ;
66
108
let size = sym. size ( ) ;
67
109
let name = sym. name ( ) . map_or ( "" , |v| v) ;
68
- ParsedSym {
69
- address,
70
- size,
71
- name,
110
+ if name == ".text" || name == ".data" {
111
+ None
112
+ } else {
113
+ Some ( ParsedSym {
114
+ address,
115
+ size,
116
+ name,
117
+ } )
72
118
}
73
119
} )
74
120
. collect :: < Vec < _ > > ( ) ;
@@ -87,7 +133,7 @@ impl<'a> Object<'a> {
87
133
} ;
88
134
let sym = self . syms . get ( i) ?;
89
135
if ( sym. address ..sym. address + sym. size ) . contains ( & addr) {
90
- Some ( sym. name . strip_prefix ( "." ) ? . as_bytes ( ) )
136
+ Some ( sym. name . trim_start_matches ( "." ) . as_bytes ( ) )
91
137
} else {
92
138
None
93
139
}
0 commit comments