func hasDynTag(f *elf.File, tag elf.DynTag) bool { ds := f.SectionByType(elf.SHT_DYNAMIC) if ds == nil { return false } d, err := ds.Data() if err != nil { return false } for len(d) > 0 { var t elf.DynTag switch f.Class { case elf.ELFCLASS32: t = elf.DynTag(f.ByteOrder.Uint32(d[0:4])) d = d[8:] case elf.ELFCLASS64: t = elf.DynTag(f.ByteOrder.Uint64(d[0:8])) d = d[16:] } if t == tag { return true } } return false }
func hasDynTag(t *testing.T, f *elf.File, tag elf.DynTag) bool { ds := f.SectionByType(elf.SHT_DYNAMIC) if ds == nil { t.Error("no SHT_DYNAMIC section") return false } d, err := ds.Data() if err != nil { t.Errorf("can't read SHT_DYNAMIC contents: %v", err) return false } for len(d) > 0 { var t elf.DynTag switch f.Class { case elf.ELFCLASS32: t = elf.DynTag(f.ByteOrder.Uint32(d[:4])) d = d[8:] case elf.ELFCLASS64: t = elf.DynTag(f.ByteOrder.Uint64(d[:8])) d = d[16:] } if t == tag { return true } } return false }
func Soname(data []byte) (so string, ok bool) { e, err := elf.NewFile(bytes.NewReader(data)) if err != nil { return so, false } section := e.Section(".dynamic") if section == nil { // not a dynamic binary. return so, false } // e.stringtable(section.Link) dynstr, _ := e.Sections[section.Link].Data() switch e.Class { case elf.ELFCLASS64: n := section.Size / 16 // 2*sizeof(uintptr) values := make([]elf.Dyn64, n) binary.Read(section.Open(), binary.LittleEndian, values) for _, v := range values { if elf.DynTag(v.Tag) == elf.DT_SONAME { return getstring(dynstr, int(v.Val)), true } } case elf.ELFCLASS32: n := section.Size / 8 values := make([]elf.Dyn32, n) binary.Read(section.Open(), binary.LittleEndian, values) for _, v := range values { if elf.DynTag(v.Tag) == elf.DT_SONAME { return getstring(dynstr, int(v.Val)), true } } } return "", false }
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 Depends(data []byte) (needed []string, err error) { e, err := elf.NewFile(bytes.NewReader(data)) if err != nil { return nil, err } section := e.Section(".dynamic") if section == nil { // not a dynamic binary. return nil, nil } // e.stringtable(section.Link) dynstr, _ := e.Sections[section.Link].Data() switch e.Class { case elf.ELFCLASS64: n := section.Size / 16 // 2*sizeof(uintptr) values := make([]elf.Dyn64, n) binary.Read(section.Open(), binary.LittleEndian, values) for _, v := range values { if elf.DynTag(v.Tag) == elf.DT_NEEDED { so := getstring(dynstr, int(v.Val)) needed = append(needed, so) } } case elf.ELFCLASS32: n := section.Size / 8 values := make([]elf.Dyn32, n) binary.Read(section.Open(), binary.LittleEndian, values) for _, v := range values { if elf.DynTag(v.Tag) == elf.DT_NEEDED { so := getstring(dynstr, int(v.Val)) needed = append(needed, so) } } } return needed, nil }