mirror of
https://github.com/blacktop/ipsw.git
synced 2026-05-08 12:22:26 +00:00
196d77de6f
Add API endpoints and CLI support for discovering C++ classes and symbolication of kernelcaches, refactor Mach-O handling, and improve symbol collection. - API: add /kernel/cpp and /kernel/symbolicate routes, request param structs, response types, and openKernel helper. Use cpp scanner and signature parsing to return classes and symbol maps. - CLI: wire scanner LogStats flag, refactor kernel symbolicate command (schema writer helper, improved signature parsing, and symbol matching logic). Add tests for symbolicator schema and kernel symbol matching. - Signature pkg: add kernel C++ symbol extraction (pkg/signature/kernel_cpp.go) and SymbolicateMachO to symbolicate already-open Mach-Os; integrate C++ symbols into symbol map and update signature matching/logging behavior. - Internal: refactor in-memory DB lookups (findMachOByUUID, findSymbolByAddr) to reduce duplication. Improve symbols collection for kernel Mach-Os (collectKernelMachoSymbols, extra kernel symbols from signature/C++), add helpers to append symbols. - Kernelcache CPP: add LogStats option and conditional logging of scan stats. - Crashlog/ips: update wording to reflect kernel symbols are from kernel analysis and store KernelSymbols earlier in processing; parse signatures only when configured. Also add unit tests for new symbolication helpers and kernel C++ signature handling. Overall this consolidates kernel symbol discovery, improves reuse, and surfaces C++-derived symbols in symbol maps.
104 lines
2.4 KiB
Go
104 lines
2.4 KiB
Go
package signature
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/apex/log"
|
|
"github.com/blacktop/go-macho"
|
|
"github.com/blacktop/ipsw/pkg/kernelcache/cpp"
|
|
)
|
|
|
|
type kernelCPPSymbol struct {
|
|
addr uint64
|
|
name string
|
|
}
|
|
|
|
func (sm SymbolMap) addKernelCPPSymbols(kc *macho.File, quiet bool) (int, error) {
|
|
if kc == nil {
|
|
return 0, fmt.Errorf("nil kernelcache")
|
|
}
|
|
|
|
classes, err := cpp.NewScanner(kc, cpp.Config{}).Scan()
|
|
if err != nil {
|
|
return 0, fmt.Errorf("failed to discover C++ kernel symbols: %w", err)
|
|
}
|
|
|
|
added := sm.addKernelCPPClasses(classes)
|
|
if added > 0 && !quiet {
|
|
log.WithFields(log.Fields{
|
|
"classes": len(classes),
|
|
"added": added,
|
|
}).Info("Discovered C++ kernel symbols")
|
|
}
|
|
|
|
return added, nil
|
|
}
|
|
|
|
func (sm SymbolMap) addKernelCPPClasses(classes []cpp.Class) int {
|
|
added := 0
|
|
|
|
for _, class := range classes {
|
|
for _, symbol := range cppClassSymbols(class) {
|
|
if err := sm.Add(symbol.addr, symbol.name); err != nil {
|
|
log.WithError(err).WithFields(log.Fields{
|
|
"address": fmt.Sprintf("%#x", symbol.addr),
|
|
"symbol": symbol.name,
|
|
}).Debug("Skipping conflicting C++ kernel symbol")
|
|
continue
|
|
}
|
|
added++
|
|
}
|
|
}
|
|
|
|
return added
|
|
}
|
|
|
|
func cppClassSymbols(class cpp.Class) []kernelCPPSymbol {
|
|
if class.Name == "" {
|
|
return nil
|
|
}
|
|
|
|
symbols := make([]kernelCPPSymbol, 0, 4)
|
|
|
|
if class.Ctor != 0 {
|
|
symbols = appendKernelCPPSymbol(symbols, class.Ctor, cppConstructorSymbol(class.Name))
|
|
}
|
|
if class.MetaPtr != 0 {
|
|
symbols = appendKernelCPPSymbol(symbols, class.MetaPtr, cppMetaClassSymbol(class.Name))
|
|
}
|
|
if class.MetaVtableAddr != 0 {
|
|
symbols = appendKernelCPPSymbol(symbols, class.MetaVtableAddr, cppMetaVtableSymbol(class.Name))
|
|
}
|
|
if class.VtableAddr != 0 {
|
|
symbols = appendKernelCPPSymbol(symbols, class.VtableAddr, cppVtableSymbol(class.Name))
|
|
}
|
|
|
|
return symbols
|
|
}
|
|
|
|
func appendKernelCPPSymbol(symbols []kernelCPPSymbol, addr uint64, name string) []kernelCPPSymbol {
|
|
if addr == 0 || name == "" {
|
|
return symbols
|
|
}
|
|
return append(symbols, kernelCPPSymbol{
|
|
addr: addr,
|
|
name: name,
|
|
})
|
|
}
|
|
|
|
func cppConstructorSymbol(className string) string {
|
|
return fmt.Sprintf("%s::%s", className, className)
|
|
}
|
|
|
|
func cppMetaClassSymbol(className string) string {
|
|
return className + "::gMetaClass"
|
|
}
|
|
|
|
func cppVtableSymbol(className string) string {
|
|
return "vtable for " + className
|
|
}
|
|
|
|
func cppMetaVtableSymbol(className string) string {
|
|
return "vtable for " + className + "::MetaClass"
|
|
}
|