Skip to content

Commit

Permalink
fix: GetSwiftAccessibleFunctions
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktop committed Oct 23, 2023
1 parent fac924b commit f4f54e0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
19 changes: 14 additions & 5 deletions swift.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ func (f *File) GetSwiftDynamicReplacementInfoForOpaqueTypes() (*swift.AutomaticD
}

// GetSwiftAccessibleFunctions parses the __TEXT.__swift5_acfuncs section
func (f *File) GetSwiftAccessibleFunctions() (*swift.AccessibleFunctionsSection, error) {
func (f *File) GetSwiftAccessibleFunctions() (funcs []swift.TargetAccessibleFunctionRecord, err error) {
if sec := f.Section("__TEXT", "__swift5_acfuncs"); sec != nil {
off, err := f.vma.GetOffset(f.vma.Convert(sec.Addr))
if err != nil {
Expand All @@ -526,12 +526,21 @@ func (f *File) GetSwiftAccessibleFunctions() (*swift.AccessibleFunctionsSection,
return nil, fmt.Errorf("failed to read %s.%s data: %v", sec.Seg, sec.Name, err)
}

var afsec swift.AccessibleFunctionsSection
if err := binary.Read(bytes.NewReader(dat), f.ByteOrder, &afsec); err != nil {
return nil, fmt.Errorf("failed to read %T: %v", afsec, err)
r := bytes.NewReader(dat)

for {
curr, _ := r.Seek(0, io.SeekCurrent)
var afr swift.TargetAccessibleFunctionRecord
if err := afr.Read(r, sec.Addr+uint64(curr)); err != nil {
if errors.Is(err, io.EOF) {
break
}
return nil, fmt.Errorf("failed to read swift %T: %w", afr, err)
}
funcs = append(funcs, afr)
}

return &afsec, nil
return funcs, nil
}

return nil, fmt.Errorf("MachO has no '__swift5_acfuncs' section: %w", ErrSwiftSectionError)
Expand Down
43 changes: 39 additions & 4 deletions types/swift/accessible_funcs.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package swift

import (
"encoding/binary"
"io"
)

// __swift5_acfuncs

type AccessibleFunctionsSection struct {
Expand All @@ -14,13 +19,43 @@ const (
)

type TargetAccessibleFunctionRecord struct {
Name int32 // char *
GenericEnvironment int32 // TargetGenericEnvironment
FunctionType int32 // mangled name
Function int32 // void *
Name RelativeDirectPointer // char *
GenericEnvironment RelativeDirectPointer // TargetGenericEnvironment
FunctionType RelativeDirectPointer // mangled name
Function RelativeDirectPointer // void *
Flags AccessibleFunctionFlags
}

func (r TargetAccessibleFunctionRecord) Size() int64 {
return int64(
binary.Size(r.Name.RelOff) +
binary.Size(r.GenericEnvironment.RelOff) +
binary.Size(r.FunctionType.RelOff) +
binary.Size(r.Function.RelOff) +
binary.Size(r.Flags),
)
}

func (f *TargetAccessibleFunctionRecord) Read(r io.Reader, addr uint64) error {
f.Name.Address = addr
if err := binary.Read(r, binary.LittleEndian, &f.Name.RelOff); err != nil {
return err
}
f.GenericEnvironment.Address = addr + uint64(binary.Size(f.Name.RelOff))
if err := binary.Read(r, binary.LittleEndian, &f.GenericEnvironment.RelOff); err != nil {
return err
}
f.FunctionType.Address = addr + uint64(binary.Size(f.Name.RelOff)) + uint64(binary.Size(f.GenericEnvironment.RelOff))
if err := binary.Read(r, binary.LittleEndian, &f.FunctionType.RelOff); err != nil {
return err
}
f.Function.Address = addr + uint64(binary.Size(f.Name.RelOff)) + uint64(binary.Size(f.GenericEnvironment.RelOff)) + uint64(binary.Size(f.FunctionType.RelOff))
if err := binary.Read(r, binary.LittleEndian, &f.Function.RelOff); err != nil {
return err
}
return binary.Read(r, binary.LittleEndian, &f.Flags)
}

type AccessibleFunctionCacheEntry struct {
Name string
NameLen uint32
Expand Down

0 comments on commit f4f54e0

Please sign in to comment.