func openPlan9(r *os.File) (rawFile, error) { f, err := plan9obj.NewFile(r) if err != nil { return nil, err } return &plan9File{f}, nil }
func size(name string) error { f, err := os.Open(name) if err != nil { return err } defer f.Close() p, err := plan9obj.NewFile(f) if err != nil { return fmt.Errorf("%v: %v", name, err) } textsz := uint32(0) if s := p.Section("text"); s != nil { textsz += s.Size } datasz := uint32(0) if s := p.Section("data"); s != nil { datasz += s.Size } fmt.Printf("%dt + %dd + %db = %d\t%s\n", textsz, datasz, p.Bss, textsz+datasz+p.Bss, name) return nil }
func plan9Symbols(f *os.File) []Sym { p, err := plan9obj.NewFile(f) if err != nil { errorf("parsing %s: %v", f.Name(), err) return nil } plan9Syms, err := p.Symbols() if err != nil { errorf("parsing %s: %v", f.Name(), err) return nil } // Build sorted list of addresses of all symbols. // We infer the size of a symbol by looking at where the next symbol begins. var addrs []uint64 for _, s := range plan9Syms { addrs = append(addrs, s.Value) } sort.Sort(uint64s(addrs)) var syms []Sym for _, s := range plan9Syms { sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)} i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value }) if i < len(addrs) { sym.Size = int64(addrs[i] - s.Value) } syms = append(syms, sym) } return syms }
func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte, err error) { if obj, err := elf.NewFile(f); err == nil { if sect := obj.Section(".text"); sect != nil { textStart = sect.Addr textData, _ = sect.Data() } if sect := obj.Section(".gosymtab"); sect != nil { if symtab, err = sect.Data(); err != nil { return 0, nil, nil, nil, err } } if sect := obj.Section(".gopclntab"); sect != nil { if pclntab, err = sect.Data(); err != nil { return 0, nil, nil, nil, err } } return textStart, textData, symtab, pclntab, nil } if obj, err := macho.NewFile(f); err == nil { if sect := obj.Section("__text"); sect != nil { textStart = sect.Addr textData, _ = sect.Data() } if sect := obj.Section("__gosymtab"); sect != nil { if symtab, err = sect.Data(); err != nil { return 0, nil, nil, nil, err } } if sect := obj.Section("__gopclntab"); sect != nil { if pclntab, err = sect.Data(); err != nil { return 0, nil, nil, nil, err } } return textStart, textData, symtab, pclntab, nil } if obj, err := pe.NewFile(f); err == nil { var imageBase uint64 switch oh := obj.OptionalHeader.(type) { case *pe.OptionalHeader32: imageBase = uint64(oh.ImageBase) case *pe.OptionalHeader64: imageBase = oh.ImageBase default: return 0, nil, nil, nil, fmt.Errorf("pe file format not recognized") } if sect := obj.Section(".text"); sect != nil { textStart = imageBase + uint64(sect.VirtualAddress) textData, _ = sect.Data() } if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil { return 0, nil, nil, nil, err } if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil { return 0, nil, nil, nil, err } return textStart, textData, symtab, pclntab, nil } if obj, err := plan9obj.NewFile(f); err == nil { sym, err := findPlan9Symbol(obj, "text") if err != nil { return 0, nil, nil, nil, err } textStart = sym.Value if sect := obj.Section("text"); sect != nil { textData, _ = sect.Data() } if pclntab, err = loadPlan9Table(obj, "pclntab", "epclntab"); err != nil { return 0, nil, nil, nil, err } if symtab, err = loadPlan9Table(obj, "symtab", "esymtab"); err != nil { return 0, nil, nil, nil, err } return textStart, textData, symtab, pclntab, nil } return 0, nil, nil, nil, fmt.Errorf("unrecognized binary format") }