func haveDynTag(file *elf.File, tag elf.DynTag) bool { if section := file.Section(".dynamic"); section != nil { reader := io.NewSectionReader(section, 0, int64(section.Size)) switch file.Machine { case elf.EM_X86_64: for { var entry elf.Dyn64 if err := binary.Read(reader, binary.LittleEndian, &entry); err != io.EOF { if elf.DynTag(entry.Tag) == tag { return true } } else { break } } case elf.EM_386: for { var entry elf.Dyn32 if err := binary.Read(reader, binary.LittleEndian, &entry); err != io.EOF { if elf.DynTag(entry.Tag) == tag { return true } } else { break } } } } return false }
func getSectionData(f *elf.File, name string) []byte { section := f.Section(name) if section == nil { log.Fatalf("failed getting section %s", name) } data, err := section.Data() if err != nil { log.Fatalf("failed getting section %s data: %s", name, err) } return data }
func processGoInformation(f *elf.File) { gosymtab := getSectionData(f, ".gosymtab") gopclntab := getSectionData(f, ".gopclntab") lineTable := gosym.NewLineTable(gopclntab, f.Section(".text").Addr) table, err := gosym.NewTable(gosymtab, lineTable) if err != nil { log.Fatalf("failed making table: %s", err) } printSyms(table.Syms) printFuncs(table.Funcs) printFiles(table.Files) }
func (dbp *Process) parseDebugLineInfo(exe *elf.File, wg *sync.WaitGroup) { defer wg.Done() if sec := exe.Section(".debug_line"); sec != nil { debugLine, err := exe.Section(".debug_line").Data() if err != nil { fmt.Println("could not get .debug_line section", err) os.Exit(1) } dbp.lineInfo = line.Parse(debugLine) } else { fmt.Println("could not find .debug_line section in binary") os.Exit(1) } }
func (dbp *Process) parseDebugFrame(exe *elf.File, wg *sync.WaitGroup) { defer wg.Done() if sec := exe.Section(".debug_frame"); sec != nil { debugFrame, err := exe.Section(".debug_frame").Data() if err != nil { fmt.Println("could not get .debug_frame section", err) os.Exit(1) } dbp.frameEntries = frame.Parse(debugFrame) } else { fmt.Println("could not find .debug_frame section in binary") os.Exit(1) } }
func dwzparser(dwzfile *elf.File, offset int64, debug_package string, debug_file string) string { if section := dwzfile.Section(".debug_str"); section != nil { reader := io.NewSectionReader(section, 0, int64(section.Size)) reader.Seek(offset, 1) bufreader := bufio.NewReader(reader) // http://golang.org/pkg/bufio/#Reader.ReadString str, err := bufreader.ReadString('\x00') if err != nil { log.Println(err, debug_package, debug_file) } return strings.TrimSuffix(str, "\x00") } panic("dwzparser ran into problems ;(") }
func (dbp *Process) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) { defer wg.Done() var ( symdat []byte pclndat []byte err error ) if sec := exe.Section(".gosymtab"); sec != nil { symdat, err = sec.Data() if err != nil { fmt.Println("could not get .gosymtab section", err) os.Exit(1) } } if sec := exe.Section(".gopclntab"); sec != nil { pclndat, err = sec.Data() if err != nil { fmt.Println("could not get .gopclntab section", err) os.Exit(1) } } pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr) tab, err := gosym.NewTable(symdat, pcln) if err != nil { fmt.Println("could not get initialize line table", err) os.Exit(1) } dbp.goSymTable = tab }
func elfGoSyms(f *elf.File) (*gosym.Table, os.Error) { text := f.Section(".text") symtab := f.Section(".gosymtab") pclntab := f.Section(".gopclntab") if text == nil || symtab == nil || pclntab == nil { return nil, nil } symdat, err := symtab.Data() if err != nil { return nil, err } pclndat, err := pclntab.Data() if err != nil { return nil, err } pcln := gosym.NewLineTable(pclndat, text.Addr) tab, err := gosym.NewTable(symdat, pcln) if err != nil { return nil, err } return tab, nil }
func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) { s := f.Section(".gosymtab") if s == nil { t.Skip("no .gosymtab section") } symdat, err := s.Data() if err != nil { f.Close() t.Fatalf("reading %s gosymtab: %v", file, err) } pclndat, err := f.Section(".gopclntab").Data() if err != nil { f.Close() t.Fatalf("reading %s gopclntab: %v", file, err) } pcln := NewLineTable(pclndat, f.Section(".text").Addr) tab, err := NewTable(symdat, pcln) if err != nil { f.Close() t.Fatalf("parsing %s gosymtab: %v", file, err) } return f, tab }
func blacklisted(file string, obj *elf.File) (bool, error) { lib := regexp.MustCompile(`^.*/lib([\w-]+)\.so[\d.]*$`) glcore := regexp.MustCompile(`libnvidia-e?glcore\.so`) gldispatch := regexp.MustCompile(`libGLdispatch\.so`) if m := lib.FindStringSubmatch(file); m != nil { switch m[1] { // Blacklist EGL/OpenGL libraries issued by other vendors case "EGL": fallthrough case "GLESv1_CM": fallthrough case "GLESv2": fallthrough case "GL": deps, err := obj.DynString(elf.DT_NEEDED) if err != nil { return false, err } for _, d := range deps { if glcore.MatchString(d) || gldispatch.MatchString(d) { return false, nil } } return true, nil // Blacklist TLS libraries using the old ABI (!= 2.3.99) case "nvidia-tls": const abi = 0x6300000003 s, err := obj.Section(".note.ABI-tag").Data() if err != nil { return false, err } return binary.LittleEndian.Uint64(s[24:]) != abi, nil } } return false, nil }