82 lines
1.5 KiB
Go
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,
|
||
|
}
|
||
|
}
|