@@ -99,28 +99,32 @@ func GetAllEnums(path string) (map[string]*dwf.EnumType, error) {
99
99
return enums , nil
100
100
}
101
101
102
- func GetName (path , name string ) (ft * dwf.FuncType , filename string , err error ) {
102
+ func GetName (path , name string ) (nameMap map [string ]* dwf.FuncType , err error ) {
103
+ nameMap = make (map [string ]* dwf.FuncType )
104
+
103
105
m , err := macho .Open (path )
104
106
if err != nil {
105
- return nil , "" , err
107
+ return nil , err
106
108
}
107
109
defer m .Close ()
108
110
109
111
df , err := m .DWARF ()
110
112
if err != nil {
111
- return nil , "" , err
113
+ return nil , err
112
114
}
113
115
114
116
r := df .Reader ()
115
117
118
+ var nameOffs []dwf.Offset
119
+
116
120
off , err := df .LookupName (name )
117
121
if err != nil {
118
122
if ! errors .Is (err , dwf .ErrHashNotFound ) {
119
- return nil , "" , fmt .Errorf ("failed to find name %s: %v" , name , err )
123
+ return nil , fmt .Errorf ("failed to find name %s: %v" , name , err )
120
124
}
121
125
offs , err := df .LookupDebugName (name )
122
126
if err != nil {
123
- return nil , "" , fmt .Errorf ("failed to find debug name %s: %v" , name , err )
127
+ return nil , fmt .Errorf ("failed to find debug name %s: %v" , name , err )
124
128
}
125
129
if len (offs ) > 1 {
126
130
log .Warnf ("found multiple debug names entries for %s" , name )
@@ -129,125 +133,149 @@ func GetName(path, name string) (ft *dwf.FuncType, filename string, err error) {
129
133
switch o .Tag {
130
134
case dwf .TagStructType , dwf .TagEnumerationType , dwf .TagUnionType , dwf .TagTypedef , dwf .TagArrayType , dwf .TagPointerType :
131
135
default :
132
- r .Seek (o .CUOffset )
133
- r .Next ()
134
- off = o .DIEOffset
136
+ nameOffs = append (nameOffs , o .DIEOffset )
135
137
}
136
138
}
139
+ } else {
140
+ nameOffs = append (nameOffs , off )
137
141
}
138
142
139
- r .Seek (off )
143
+ for _ , off := range nameOffs {
144
+ filename := "<unknown>"
140
145
141
- entry , err := r .Next ()
142
- if err != nil {
143
- return nil , "" , err
144
- }
146
+ r .Seek (off )
145
147
146
- fs , err := df .FilesForEntry (entry )
147
- if err != nil {
148
- return nil , "" , fmt .Errorf ("failed to get files for entry: %v" , err )
149
- }
150
- if idx , ok := entry .Val (dwf .AttrDeclFile ).(int64 ); ok {
151
- if idx < int64 (len (fs )) {
152
- filename = fs [idx ].Name
148
+ entry , err := r .Next ()
149
+ if err != nil {
150
+ return nil , err
153
151
}
154
- }
155
152
156
- if entry .Tag == dwf .TagSubprogram || entry .Tag == dwf .TagSubroutineType || entry .Tag == dwf .TagInlinedSubroutine {
157
- typ , err := df .Type (entry .Offset )
153
+ fs , err := df .FilesForEntry (entry )
158
154
if err != nil {
159
- return nil , " " , err
155
+ return nil , fmt . Errorf ( "failed to get files for entry: %v " , err )
160
156
}
161
- ft = typ .(* dwf.FuncType )
162
- } else {
163
- typ , err := df .Type (entry .Offset )
164
- if err != nil {
165
- return nil , "" , err
157
+ if idx , ok := entry .Val (dwf .AttrDeclFile ).(int64 ); ok {
158
+ if idx < int64 (len (fs )) {
159
+ filename = fs [idx ].Name
160
+ }
161
+ }
162
+ if idx , ok := entry .Val (dwf .AttrCallFile ).(int64 ); ok {
163
+ if idx < int64 (len (fs )) {
164
+ filename = fs [idx ].Name
165
+ }
166
+ }
167
+ if line , ok := entry .Val (dwf .AttrDeclLine ).(int64 ); ok {
168
+ filename += fmt .Sprintf ("#L%d" , line )
169
+ }
170
+ if line , ok := entry .Val (dwf .AttrCallLine ).(int64 ); ok {
171
+ filename += fmt .Sprintf ("#L%d" , line )
172
+ }
173
+
174
+ if entry .Tag == dwf .TagSubprogram || entry .Tag == dwf .TagSubroutineType || entry .Tag == dwf .TagInlinedSubroutine {
175
+ typ , err := df .Type (entry .Offset )
176
+ if err != nil {
177
+ return nil , err
178
+ }
179
+ nameMap [filename ] = typ .(* dwf.FuncType )
180
+ } else {
181
+ typ , err := df .Type (entry .Offset )
182
+ if err != nil {
183
+ return nil , err
184
+ }
185
+ return nil , fmt .Errorf ("did not find tag func type: found %s; %s" , entry .Tag , typ .String ())
166
186
}
167
- return nil , "" , fmt .Errorf ("did not find tag func type: found %s; %s" , entry .Tag , typ .String ())
168
187
}
169
188
170
- return
189
+ return nameMap , nil
171
190
}
172
191
173
- func GetType (path , name string , showOffsets bool ) (typeStr string , filename string , err error ) {
192
+ func GetType (path , name string , showOffsets bool ) (typeMap map [string ]string , err error ) {
193
+ typeMap = make (map [string ]string )
194
+
174
195
m , err := macho .Open (path )
175
196
if err != nil {
176
- return "" , "" , err
197
+ return nil , err
177
198
}
178
199
defer m .Close ()
179
200
180
201
df , err := m .DWARF ()
181
202
if err != nil {
182
- return "" , "" , err
203
+ return nil , err
183
204
}
184
205
185
206
r := df .Reader ()
186
207
208
+ var typoffs []dwf.Offset
209
+
187
210
off , err := df .LookupType (name )
188
211
if err != nil {
189
212
if ! errors .Is (err , dwf .ErrHashNotFound ) {
190
- return "" , "" , fmt .Errorf ("failed to find name %s: %v" , name , err )
213
+ return nil , fmt .Errorf ("failed to find name %s: %v" , name , err )
191
214
}
192
215
offs , err := df .LookupDebugName (name )
193
216
if err != nil {
194
- return "" , "" , fmt .Errorf ("failed to find debug name %s: %v" , name , err )
217
+ return nil , fmt .Errorf ("failed to find debug name %s: %v" , name , err )
195
218
}
196
219
if len (offs ) > 1 {
197
220
log .Warnf ("found multiple debug names entries for %s" , name )
198
221
}
199
222
for _ , o := range offs {
200
223
switch o .Tag {
201
224
case dwf .TagStructType , dwf .TagEnumerationType , dwf .TagUnionType , dwf .TagTypedef , dwf .TagArrayType , dwf .TagPointerType :
202
- r .Seek (o .CUOffset )
203
- r .Next ()
204
- off = o .DIEOffset
225
+ typoffs = append (typoffs , o .DIEOffset )
205
226
}
206
227
}
228
+ } else {
229
+ typoffs = append (typoffs , off )
207
230
}
208
231
209
- r .Seek (off )
232
+ for _ , off := range typoffs {
233
+ filename := "<unknown>"
210
234
211
- entry , err := r .Next ()
212
- if err != nil {
213
- return "" , "" , err
214
- }
235
+ r .Seek (off )
215
236
216
- fs , err := df .FilesForEntry (entry )
217
- if err != nil {
218
- return "" , "" , fmt .Errorf ("failed to get files for entry: %v" , err )
219
- }
220
- if idx , ok := entry .Val (dwf .AttrDeclFile ).(int64 ); ok {
221
- if idx < int64 (len (fs )) {
222
- filename = fs [idx ].Name
237
+ entry , err := r .Next ()
238
+ if err != nil {
239
+ return nil , err
223
240
}
224
- }
225
241
226
- typ , err := df .Type (entry .Offset )
227
- if err != nil {
228
- return "" , "" , fmt .Errorf ("failed to get type for entry: %v" , err )
229
- }
242
+ fs , err := df .FilesForEntry (entry )
243
+ if err != nil {
244
+ return nil , fmt .Errorf ("failed to get files for entry: %v" , err )
245
+ }
246
+ if idx , ok := entry .Val (dwf .AttrDeclFile ).(int64 ); ok {
247
+ if idx < int64 (len (fs )) {
248
+ filename = fs [idx ].Name
249
+ }
250
+ }
251
+ if line , ok := entry .Val (dwf .AttrDeclLine ).(int64 ); ok {
252
+ filename += fmt .Sprintf ("#L%d" , line )
253
+ }
254
+
255
+ typ , err := df .Type (entry .Offset )
256
+ if err != nil {
257
+ return nil , fmt .Errorf ("failed to get type for entry: %v" , err )
258
+ }
230
259
231
- switch t := typ .(type ) {
232
- case * dwf.StructType :
233
- if t .Incomplete {
234
- return "" , "" , fmt .Errorf ("type %s is incomplete" , name )
235
- }
236
- return t .Defn (showOffsets ), filename , nil
237
- case * dwf.ArrayType :
238
- return t .String (), filename , nil
239
- case * dwf.PtrType :
240
- return t .String (), filename , nil
241
- case * dwf.EnumType :
242
- return t .String (), filename , nil
243
- case * dwf.TypedefType :
244
- if enum , ok := t .Type .(* dwf.EnumType ); ok {
245
- return fmt .Sprintf ("typedef %s %s;" , enum .String (), t .Name ), filename , nil
246
- }
247
- return fmt .Sprintf ("typedef %s %s;" , t .Type .Common ().Name , t .Name ), filename , nil
248
- default :
249
- return "" , "" , fmt .Errorf ("did not find supported type: found %s; %s" , entry .Tag , typ .String ())
260
+ switch t := typ .(type ) {
261
+ case * dwf.StructType :
262
+ if t .Incomplete {
263
+ continue
264
+ }
265
+ typeMap [filename ] = t .Defn (showOffsets )
266
+ case * dwf.ArrayType , * dwf.PtrType , * dwf.EnumType :
267
+ typeMap [filename ] = t .String ()
268
+ case * dwf.TypedefType :
269
+ if enum , ok := t .Type .(* dwf.EnumType ); ok {
270
+ typeMap [filename ] = fmt .Sprintf ("typedef %s %s;" , enum .String (), t .Name )
271
+ }
272
+ typeMap [filename ] = fmt .Sprintf ("typedef %s %s;" , t .Type .Common ().Name , t .Name )
273
+ default :
274
+ return nil , fmt .Errorf ("did not find supported type: found %s; %s" , entry .Tag , typ .String ())
275
+ }
250
276
}
277
+
278
+ return typeMap , nil
251
279
}
252
280
253
281
func DiffStructures (prevMachO , currMachO string , conf * Config ) (string , error ) {
0 commit comments