Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
konoui committed May 16, 2024
1 parent e7c8b10 commit b9c1e3a
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 82 deletions.
2 changes: 1 addition & 1 deletion pkg/lipo/arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func OpenArches(inputs []*ArchInput) ([]Arch, error) {
sr := io.NewSectionReader(f, 0, stats.Size())
obj, err := lmacho.NewArch(sr)
if err != nil {
return nil, err // todo detail error
return nil, err
}

if input.Arch != "" {
Expand Down
27 changes: 18 additions & 9 deletions pkg/lipo/archs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,42 @@ func (l *Lipo) Archs() ([]string, error) {
}

bin := l.in[0]
return archs(bin)
cpus, _, err := archs(bin)
return cpus, err
}

func archs(bin string) ([]string, error) {
obj, typ, err := inspect(bin)
func archs(bin string) ([]string, inspectType, error) {
typ, err := inspect(bin)
if err != nil {
return nil, err
return nil, inspectUnknown, err
}

switch typ {
case inspectThin:
fallthrough
objs, err := OpenArches([]*ArchInput{{Bin: bin}})
if err != nil {
return nil, typ, err
}
return []string{objs[0].CPUString()}, inspectThin, nil
case inspectArchive:
return []string{obj.CPUString()}, nil
objs, err := OpenArchiveArches(bin)
if err != nil {
return nil, typ, err
}
return []string{objs[0].CPUString()}, typ, nil
case inspectFat:
fat, err := OpenFatFile(bin)
if err != nil {
return nil, fmt.Errorf("internal error: %w", err)
return nil, typ, fmt.Errorf("internal error: %w", err)
}
defer fat.Close()

cpus := make([]string, len(fat.Arches))
for i := range cpus {
cpus[i] = fat.Arches[i].CPUString()
}
return cpus, nil
return cpus, typ, nil
default:
return nil, fmt.Errorf("unexpected type: %d", typ)
return nil, inspectUnknown, fmt.Errorf("unexpected type: %d", typ)
}
}
2 changes: 1 addition & 1 deletion pkg/lipo/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func createFatBinary[T Arch](path string, arches []T, perm os.FileMode, fat64 bo
}
defer out.Close()

if err := lmacho.Create(out, arches, fat64, hideARM64); err != nil {
if err := lmacho.CreateFat(out, arches, fat64, hideARM64); err != nil {
return err
}

Expand Down
7 changes: 3 additions & 4 deletions pkg/lipo/detailed_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type tplFatBinary struct {
func detailedInfo(bin string) (string, bool, error) {
var out strings.Builder

_, typ, err := inspect(bin)
typ, err := inspect(bin)
if err != nil {
return "", false, err
}
Expand Down Expand Up @@ -133,13 +133,12 @@ func detailedInfo(bin string) (string, bool, error) {

func tplArch(a *lmacho.FatArch) *tplFatArch {
c, s := lmacho.ToCpuValues(a.CPU(), a.SubCPU())
arch := lmacho.ToCpuString(a.CPU(), a.SubCPU())
return &tplFatArch{
Arch: arch,
Arch: a.CPUString(),
CpuType: c,
SubCpuType: s,
Capabilities: fmt.Sprintf("0x%x", (a.SubCPU()&lmacho.MaskSubCpuType)>>24),
Offset: a.FatArchHeader().Offset,
Offset: a.Offset(),
Size: a.Size(),
AlignBit: a.Align(),
Align: 1 << a.Align(),
Expand Down
24 changes: 8 additions & 16 deletions pkg/lipo/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ func (l *Lipo) Info() ([]string, error) {
fat := make([]string, 0, len(l.in))
thin := make([]string, 0, len(l.in))
for _, bin := range l.in {
v, isFat, err := info(bin)
v, typ, err := info(bin)
if err != nil {
return nil, err
}
if isFat {
if typ == inspectFat {
fat = append(fat, v)
} else {
thin = append(thin, v)
Expand All @@ -27,29 +27,21 @@ func (l *Lipo) Info() ([]string, error) {
return append(fat, thin...), nil
}

func info(bin string) (string, bool, error) {
fatFmt := "Architectures in the fat file: %s are: %s"

arches, err := archs(bin)
func info(bin string) (string, inspectType, error) {
arches, typ, err := archs(bin)
if err != nil {
return "", false, err
return "", typ, err
}

v := strings.Join(arches, " ")

_, typ, err := inspect(bin)
if err != nil {
return "", false, err
}

switch typ {
case inspectThin:
fallthrough
case inspectArchive:
return fmt.Sprintf("Non-fat file: %s is architecture: %s", bin, v), false, nil
return fmt.Sprintf("Non-fat file: %s is architecture: %s", bin, v), typ, nil
case inspectFat:
return fmt.Sprintf(fatFmt, bin, v), true, nil
return fmt.Sprintf("Architectures in the fat file: %s are: %s", bin, v), typ, nil
default:
return "", false, fmt.Errorf("unexpected type: %d", typ)
return "", inspectUnknown, fmt.Errorf("unexpected type: %d", typ)
}
}
39 changes: 17 additions & 22 deletions pkg/lipo/operation.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package lipo

import (
"bytes"
"errors"
"fmt"
"math"
"os"
"strconv"
"strings"

"github.com/konoui/lipo/pkg/ar"
"github.com/konoui/lipo/pkg/lmacho"
"github.com/konoui/lipo/pkg/util"
)
Expand Down Expand Up @@ -120,43 +122,36 @@ const (
inspectUnknown
)

// inspect return object if the file is ar or macho(thin) object
func inspect(p string) (Arch, inspectType, error) {
// handle general errors
func inspect(p string) (inspectType, error) {
f, err := os.Open(p)
if err != nil {
return nil, inspectUnknown, err
return inspectUnknown, err
}
defer f.Close()

baseErr := fmt.Errorf("can't figure out the architecture type of: %s", p)
inspectedErrs := []error{}
ff, err := OpenFatFile(p)
if err == nil {
defer ff.Close()
return nil, inspectFat, nil

buf := make([]byte, 40)
if _, err := f.Read(buf); err != nil {
return inspectUnknown, errors.Join(baseErr, errors.New("cannot read first 40 bytes"))
}

_, err = lmacho.NewFatReader(bytes.NewReader(buf))
if err == nil {
return inspectFat, nil
}
if errors.Is(err, lmacho.ErrThin) {
a, err := OpenArches([]*ArchInput{{Bin: p}})
if err != nil {
return nil, inspectUnknown, err // unexpected error
}
defer close(a...)
return a[0], inspectThin, nil
return inspectThin, nil
}

inspectedErrs = append(inspectedErrs, err)

objs, err := OpenArchiveArches(p)
_, err = ar.NewReader(bytes.NewReader(buf))
if err == nil {
defer close(objs...)
return objs[0], inspectArchive, nil
}
if strings.HasPrefix(err.Error(), "archive member") {
return nil, inspectUnknown, err
return inspectArchive, nil
}

inspectedErrs = append(inspectedErrs, err)

return nil, inspectUnknown, errors.Join(fmt.Errorf("can't figure out the architecture type of: %s", p), errors.Join(inspectedErrs...))
return inspectUnknown, errors.Join(baseErr, errors.Join(inspectedErrs...))
}
10 changes: 5 additions & 5 deletions pkg/lmacho/fat.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ func (fa *FatArch) Type() macho.Type {
return fa.typ
}

func (fa *FatArch) Offset() uint64 {
return fa.faHdr.Offset
}

func (fa *FatArch) CPUString() string {
return ToCpuString(fa.CPU(), fa.SubCPU())
}
Expand All @@ -86,10 +90,6 @@ func (fa *FatArch) Seek(offset int64, whence int) (int64, error) {
return fa.sr.Seek(offset, whence)
}

func (fa *FatArch) FatArchHeader() FatArchHeader {
return fa.faHdr
}

// Arch presents an object of thin file
type Arch struct {
cpu Cpu
Expand Down Expand Up @@ -150,7 +150,7 @@ type FatFile struct {

// NewFatFile is wrapper for Fat Reader
func NewFatFile(ra io.ReaderAt) (*FatFile, error) {
r, err := NewReader(ra)
r, err := NewFatReader(ra)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/lmacho/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Reader struct {
nextNArch uint32
}

func NewReader(r io.ReaderAt) (*Reader, error) {
func NewFatReader(r io.ReaderAt) (*Reader, error) {
sr := io.NewSectionReader(r, 0, 1<<63-1)

var ff FatHeader
Expand Down
2 changes: 1 addition & 1 deletion pkg/lmacho/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestNewReader(t *testing.T) {
}
defer f.Close()

reader, err := lmacho.NewReader(f)
reader, err := lmacho.NewFatReader(f)
if err != nil {
t.Errorf("NewReader() error = %v", err)
return
Expand Down
34 changes: 13 additions & 21 deletions pkg/lmacho/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ import (
"io"
)

func Create[T Object](w io.Writer, objects []T, fat64 bool, hideARM64 bool) error {
func CreateFat[T Object](w io.Writer, objects []T, fat64 bool, hideARM64 bool) error {
if len(objects) == 0 {
return errors.New("file contains no images")
}

newobjects := make([]Object, len(objects))
for i := range newobjects {
newobjects[i] = objects[i]
}

if err := validateHideARM64Objects(objects, hideARM64); err != nil {
return err
}
Expand All @@ -27,7 +22,7 @@ func Create[T Object](w io.Writer, objects []T, fat64 bool, hideARM64 bool) erro
magic = MagicFat64
}

fatArches := newFatArches(newobjects)
fatArches := newFatArches(objects)
hdr := makeFatHeader(fatArches, magic, hideARM64)
if err := sortAndUpdateArches(fatArches, hdr.Magic); err != nil {
return err
Expand All @@ -44,22 +39,19 @@ func Create[T Object](w io.Writer, objects []T, fat64 bool, hideARM64 bool) erro
return nil
}

func newFatArches(objects []Object) []*FatArch {
func newFatArches[T Object](objects []T) []*FatArch {
arches := make([]*FatArch, len(objects))
for i, obj := range objects {
fa, ok := obj.(*FatArch)
if !ok {
fa = &FatArch{
sr: io.NewSectionReader(obj, 0, int64(obj.Size())),
typ: obj.Type(),
faHdr: FatArchHeader{
Cpu: obj.CPU(),
SubCpu: obj.SubCPU(),
Size: obj.Size(),
Offset: 0, // will be filled
Align: obj.Align(),
},
}
fa := &FatArch{
sr: io.NewSectionReader(obj, 0, int64(obj.Size())),
typ: obj.Type(),
faHdr: FatArchHeader{
Cpu: obj.CPU(),
SubCpu: obj.SubCPU(),
Size: obj.Size(),
Offset: 0, // will be filled
Align: obj.Align(),
},
}
arches[i] = fa
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/lmacho/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestNewWriter(t *testing.T) {
arches = append(arches, a)
}

if err := lmacho.Create(out, arches, false, false); err != nil {
if err := lmacho.CreateFat(out, arches, false, false); err != nil {
t.Fatal(err)
}

Expand Down

0 comments on commit b9c1e3a

Please sign in to comment.