add old go tooling

This commit is contained in:
2023-05-31 16:17:03 +07:00
commit 54f1f3eb38
57 changed files with 5791 additions and 0 deletions

View File

@ -0,0 +1,48 @@
package addr2line
import (
"strconv"
. "ios-wrapper/pkg/ios/macho"
)
// Try to get Image base of a DWARF binary
// using __mh_execute_header symbol
func TryGetImageBase(mc *MachoContext, symbols []*Symbol) uint64 {
try := mc.ImageBase()
if try != 0 {
return try
}
for _, symbol := range symbols {
if symbol.Name() == "__mh_execute_header" {
return symbol.Address()
}
}
return 0
}
// find the symbol name from dysymtab
// the address given is somewhere in the function,
// assuming that the address is sorted, we find the last symbol
// has its address smaller than `tofind`
// I'm not sure this would work always, ;)
func FindSymbol(symbols []*Symbol, tofind uint64) string {
var lastSymbol string = ""
for _, symbol := range symbols {
if symbol.Address() > tofind {
return lastSymbol
} else {
lastSymbol = symbol.Name()
}
}
return ""
}
func ParseAddressString(s string) (uint64, error) {
s_, err := strconv.ParseInt(s, 0, 64)
v := uint64(s_)
if err != nil {
return 0, err
}
return v, nil
}

View File

@ -0,0 +1,81 @@
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,
}
}