func NewMachOLoader(r io.ReaderAt, archHint string) (models.Loader, error) { var ( file *macho.File fatFile *macho.FatFile err error ) magic := getMagic(r) if bytes.Equal(magic, fatMagic) { fatFile, err = macho.NewFatFile(r) if fatFile != nil { for _, arch := range fatFile.Arches { if machineName, ok := machoCpuMap[arch.Cpu]; ok { if machineName == archHint || archHint == "any" { file = arch.File break } } } if file == nil { return nil, fmt.Errorf("Could not find Mach-O fat binary entry for arch '%s'.", archHint) } } } else { file, err = macho.NewFile(r) } if err != nil { return nil, err } var bits int switch file.Magic { case macho.Magic32: bits = 32 case macho.Magic64: bits = 64 default: return nil, errors.New("Unknown ELF class.") } machineName, ok := machoCpuMap[file.Cpu] if !ok { return nil, fmt.Errorf("Unsupported CPU: %s", file.Cpu) } entry, err := findEntry(file, bits) if err != nil { return nil, err } return &MachOLoader{ LoaderHeader: LoaderHeader{ arch: machineName, bits: bits, os: "darwin", entry: entry, }, file: file, }, nil }
func (fq *findQueue) worker() { for fp := range fq.queue { blacklisted := false for _, re := range blacklistRegexps { blacklisted = blacklisted || re.MatchString(fp) } if blacklisted { continue } f, err := os.Open(fp) if err != nil { log.Printf("%s: %v", fp, err) continue } fatFile, err := macho.NewFatFile(f) if err == nil { // The file is fat, so dump its architectures. for _, fatArch := range fatFile.Arches { fq.dumpMachOFile(fp, fatArch.File) } fatFile.Close() } else if err == macho.ErrNotFat { // The file isn't fat but may still be MachO. thinFile, err := macho.NewFile(f) if err != nil { log.Printf("%s: %v", fp, err) continue } fq.dumpMachOFile(fp, thinFile) thinFile.Close() } else { f.Close() } } }