@@ -194,24 +194,29 @@ const (
194
194
SLIBFUZZER_EXTRA_COUNTER
195
195
)
196
196
197
- type ImportCfg map [string ]ExportInfo
197
+ type ImportCfg struct {
198
+ ImportMap map [string ]string
199
+ Packages map [string ]ExportInfo
200
+ }
198
201
199
202
type ExportInfo struct {
200
203
Path string
201
204
IsSharedLib bool
202
205
}
203
206
204
- func ParseImportCfg (path string ) (ImportCfg , error ) {
207
+ func ParseImportCfg (path string ) (importCfg ImportCfg , err error ) {
205
208
data , err := ioutil .ReadFile (path )
206
209
if err != nil {
207
- return nil , fmt .Errorf ("error reading importcfg: %v" , err )
210
+ return importCfg , fmt .Errorf ("error reading importcfg: %v" , err )
208
211
}
209
212
210
213
lines := bytes .Count (data , []byte ("\n " ))
211
214
if lines == - 1 {
212
- return nil , errors .New ("error parsing importcfg: could not find any newlines" )
215
+ return importCfg , errors .New ("error parsing importcfg: could not find any newlines" )
213
216
}
214
- importMap := make (ImportCfg , lines )
217
+
218
+ importCfg .ImportMap = make (map [string ]string )
219
+ importCfg .Packages = make (map [string ]ExportInfo , lines )
215
220
216
221
for lineNum , line := range strings .Split (string (data ), "\n " ) {
217
222
lineNum ++ // 1-based
@@ -235,21 +240,26 @@ func ParseImportCfg(path string) (ImportCfg, error) {
235
240
}
236
241
switch verb {
237
242
default :
238
- return nil , fmt .Errorf ("error parsing importcfg: %s:%d: unknown directive %q" , path , lineNum , verb )
243
+ return importCfg , fmt .Errorf ("error parsing importcfg: %s:%d: unknown directive %q" , path , lineNum , verb )
244
+ case "importmap" :
245
+ if before == "" || after == "" {
246
+ return importCfg , fmt .Errorf (`error parsing importcfg: %s:%d: invalid importmap: syntax is "importmap path=path"` , path , lineNum )
247
+ }
248
+ importCfg .ImportMap [before ] = after
239
249
case "packagefile" :
240
250
if before == "" || after == "" {
241
- return nil , fmt .Errorf (`error parsing importcfg: %s:%d: invalid packagefile: syntax is "packagefile path=filename"` , path , lineNum )
251
+ return importCfg , fmt .Errorf (`error parsing importcfg: %s:%d: invalid packagefile: syntax is "packagefile path=filename"` , path , lineNum )
242
252
}
243
- importMap [before ] = ExportInfo {after , false }
253
+ importCfg . Packages [before ] = ExportInfo {after , false }
244
254
case "packageshlib" :
245
255
if before == "" || after == "" {
246
- return nil , fmt .Errorf (`error parsing importcfg: %s:%d: invalid packageshlib: syntax is "packageshlib path=filename"` , path , lineNum )
256
+ return importCfg , fmt .Errorf (`error parsing importcfg: %s:%d: invalid packageshlib: syntax is "packageshlib path=filename"` , path , lineNum )
247
257
}
248
- importMap [before ] = ExportInfo {after , true }
258
+ importCfg . Packages [before ] = ExportInfo {after , true }
249
259
}
250
260
}
251
261
252
- return importMap , nil
262
+ return importCfg , nil
253
263
}
254
264
255
265
var (
@@ -416,22 +426,27 @@ func (r *objReader) skip(n int64) {
416
426
}
417
427
}
418
428
419
- // Parse parses an object file or archive from f, assuming that its
420
- // import path is pkgpath. An import configuration file that would
421
- // be passed into the linker can optionally be passed in as importCfg
429
+ // ImportMap is a function that returns the path of a Go object
430
+ // from a given import path. If the import path is not known,
431
+ // an empty string should be returned.
432
+ type ImportMap = func (importPath string ) (objectPath string )
433
+
434
+ // Parse parses an object file or archive from objPath, assuming that
435
+ // its import path is pkgpath. A function that returns paths of object
436
+ // files from import paths can optionally be passed in as importMap
422
437
// to optimize looking up paths to dependencies' object files.
423
- func Parse (objPath , pkgPath string , importCfg ImportCfg ) (* Package , error ) {
438
+ func Parse (objPath , pkgPath string , importMap ImportMap ) (* Package , error ) {
424
439
p := new (Package )
425
440
p .ImportPath = pkgPath
426
441
427
- if _ , err := parse (objPath , p , importCfg , false ); err != nil {
442
+ if _ , err := parse (objPath , p , importMap , false ); err != nil {
428
443
return nil , err
429
444
}
430
445
431
446
return p , nil
432
447
}
433
448
434
- func parse (objPath string , p * Package , importCfg ImportCfg , returnReader bool ) (rr * goobj2.Reader , err error ) {
449
+ func parse (objPath string , p * Package , importMap ImportMap , returnReader bool ) (rr * goobj2.Reader , err error ) {
435
450
f , openErr := os .Open (objPath )
436
451
if err != nil {
437
452
return nil , openErr
@@ -457,13 +472,13 @@ func parse(objPath string, p *Package, importCfg ImportCfg, returnReader bool) (
457
472
default :
458
473
return nil , errNotObject
459
474
case bytes .Equal (rd .tmp [:8 ], archiveHeader ):
460
- rr , err = rd .parseArchive (importCfg , returnReader )
475
+ rr , err = rd .parseArchive (importMap , returnReader )
461
476
if err != nil {
462
477
return nil , err
463
478
}
464
479
case bytes .Equal (rd .tmp [:8 ], goobjHeader ):
465
480
var am * ArchiveMember
466
- rr , am , _ , err = rd .parseObject (goobjHeader , importCfg , returnReader )
481
+ rr , am , _ , err = rd .parseObject (goobjHeader , importMap , returnReader )
467
482
if err != nil {
468
483
return nil , err
469
484
}
@@ -480,7 +495,7 @@ func trimSpace(b []byte) string {
480
495
}
481
496
482
497
// parseArchive parses a Unix archive of Go object files.
483
- func (r * objReader ) parseArchive (importCfg ImportCfg , returnReader bool ) (* goobj2.Reader , error ) {
498
+ func (r * objReader ) parseArchive (importMap ImportMap , returnReader bool ) (* goobj2.Reader , error ) {
484
499
for r .offset < r .limit {
485
500
if err := r .readFull (r .tmp [:archiveHeaderLen ]); err != nil {
486
501
return nil , err
@@ -551,7 +566,7 @@ func (r *objReader) parseArchive(importCfg ImportCfg, returnReader bool) (*goobj
551
566
}
552
567
if bytes .Equal (p , goobjHeader ) {
553
568
var rr * goobj2.Reader
554
- rr , am , data , err = r .parseObject (nil , importCfg , returnReader )
569
+ rr , am , data , err = r .parseObject (nil , importMap , returnReader )
555
570
if err != nil {
556
571
return nil , fmt .Errorf ("parsing archive member %q: %v" , ar .Name , err )
557
572
}
@@ -593,7 +608,7 @@ func (r *objReader) parseArchive(importCfg ImportCfg, returnReader bool) (*goobj
593
608
// and then the part we want to parse begins.
594
609
// The format of that part is defined in a comment at the top
595
610
// of src/liblink/objfile.c.
596
- func (r * objReader ) parseObject (prefix []byte , importMap ImportCfg , returnReader bool ) (* goobj2.Reader , * ArchiveMember , []byte , error ) {
611
+ func (r * objReader ) parseObject (prefix []byte , importMap ImportMap , returnReader bool ) (* goobj2.Reader , * ArchiveMember , []byte , error ) {
597
612
h := make ([]byte , 0 , 256 )
598
613
h = append (h , prefix ... )
599
614
var c1 , c2 , c3 byte
@@ -887,12 +902,11 @@ func (r *objReader) parseObject(prefix []byte, importMap ImportCfg, returnReader
887
902
return nil , & am , h , nil
888
903
}
889
904
890
- func getArchivePath (pkg string , importMap ImportCfg ) (s string , err error ) {
905
+ func getArchivePath (pkg string , importMap ImportMap ) (s string , err error ) {
891
906
// try to get the archive path from the importMap first
892
907
if importMap != nil {
893
- path , ok := importMap [pkg ]
894
- if ok {
895
- return path .Path , nil
908
+ if path := importMap (pkg ); path != "" {
909
+ return path , nil
896
910
}
897
911
}
898
912
0 commit comments