macho/macho-go/internal/wrapper/addr2line/resolver.go
2023-05-31 16:17:03 +07:00

82 lines
1.5 KiB
Go

package addr2line
import (
"errors"
"fmt"
. "ios-wrapper/pkg/ios/macho"
)
type Resolver struct {
symbols []*Symbol
debuglineInfo *DebuglineInfo
aslr uint64
addresses []string
}
type Resolved struct {
Raw uint64
Base uint64
Symbol string
File string
Line uint32
}
func (r *Resolved) Valid() bool {
return r.File == "" && r.Line == 0
}
func (resolver *Resolver) HasNext() bool {
return len(resolver.addresses) > 0
}
func (resolver *Resolver) Next() (*Resolved, error) {
if !resolver.HasNext() {
return nil, errors.New("There is no more address to resolve")
}
head, tail := resolver.addresses[0], resolver.addresses[1:]
resolver.addresses = tail
tofind_aslr, err := ParseAddressString(head)
if err != nil {
return nil, fmt.Errorf("Cannot parse hex address (%s)", head)
}
tofind := tofind_aslr - resolver.aslr
symbol := FindSymbol(resolver.symbols, tofind)
fileLine := resolver.debuglineInfo.Find(tofind)
if fileLine == nil {
return &Resolved{
Raw: tofind_aslr,
Base: tofind,
Symbol: symbol,
File: "",
Line: 0,
}, nil
}
return &Resolved{
Raw: tofind_aslr,
Base: tofind,
Symbol: symbol,
File: fileLine.File,
Line: fileLine.Line,
}, nil
}
func NewResolver(mc *MachoContext, loadaddr uint64, addresses []string) *Resolver {
symbols := mc.CollectSymbols()
debuglineInfo := mc.DebugLineInfo()
imagebase := TryGetImageBase(mc, symbols)
aslr := loadaddr - imagebase
return &Resolver{
symbols,
debuglineInfo,
aslr,
addresses,
}
}