func findEntry(f *macho.File, bits int) (uint64, error) { var entry uint64 for _, l := range f.Loads { var cmd macho.LoadCmd data := l.Raw() binary.Read(bytes.NewReader(data), f.ByteOrder, &cmd) if cmd == macho.LoadCmdUnixThread { // LC_UNIXTHREAD if bits == 64 { ip := 144 entry = f.ByteOrder.Uint64(data[ip : ip+8]) } else { ip := 56 entry = uint64(f.ByteOrder.Uint32(data[ip : ip+4])) } return entry, nil } else if cmd == machoLoadCmdMain { // [8:16] == entry - __TEXT, data[16:24] == stack size __TEXT := f.Segment("__TEXT") if __TEXT == nil { return 0, errors.New("Found LC_MAIN but did not find __TEXT segment.") } entry = f.ByteOrder.Uint64(data[8:16]) + __TEXT.Addr return entry, nil } } return 0, errors.New("Could not find entry point.") }
//============================================================================ // main : Entry point. //---------------------------------------------------------------------------- func main() { var dwarfData *dwarf.Data var theFile *macho.File var theErr os.Error var relativeAddress uint64 var runtimeAddress uint64 var loadAddress uint64 var segmentAddress uint64 var pathMacho string var pathDsym string // Parse our arguments flag.Uint64Var(&runtimeAddress, "raddr", 0, "") flag.Uint64Var(&loadAddress, "laddr", 0, "") flag.StringVar(&pathMacho, "macho", "", "") flag.StringVar(&pathDsym, "dsym", "", "") flag.Parse() if runtimeAddress == 0 || loadAddress == 0 || pathMacho == "" || pathDsym == "" { printHelp() } // Find the text segment address theFile, theErr = macho.Open(pathMacho) if theErr != nil { fatalError("Can't open Mach-O file: " + theErr.String()) } segmentAddress = theFile.Segment("__TEXT").Addr theFile.Close() // Calculate the target address relativeAddress = runtimeAddress - loadAddress gTargetAddress = segmentAddress + relativeAddress // Find the target theFile, theErr = macho.Open(pathDsym) if theErr != nil { fatalError("Can't open .dsym file: " + theErr.String()) } dwarfData, theErr = theFile.DWARF() if theErr != nil { fatalError("Can't find DWARF info: " + theErr.String()) } processChildren(dwarfData.Reader(), 0, false) theFile.Close() }