-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelfreader.go
68 lines (60 loc) · 1.4 KB
/
elfreader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main
import (
"debug/elf"
"os"
"path/filepath"
)
func GetELFDependencies(args *Arguments, dlDirs []string) (retval []string) {
var (
onFile func(string)
deps map[string]bool = make(map[string]bool)
)
// gets called on every binary:
onFile = func(fp string) {
// no need to check dependencies?
if args.NoDeps {
deps[fp] = true
return
}
f, err := elf.Open(fp)
if err != nil {
// not an ELF? probaly just a data file:
fi, err := os.Stat(fp)
if err == nil && !fi.IsDir() {
deps[fp] = true
}
return
}
defer f.Close()
libs, err := f.ImportedLibraries()
if err != nil {
return
}
deps[fp] = true
// check rpath and runpath
rp1, _ := f.DynString(elf.DT_RPATH)
rp2, _ := f.DynString(elf.DT_RUNPATH)
// look for the lib in every location where dynamic linker would look:
for _, lib := range libs {
for _, dir := range append(append(rp1, rp2...), dlDirs...) {
// does this .so file exist? if so, recursively treat it
// as another binary:
so := filepath.Join(dir, lib)
fi, err := os.Stat(so)
if err == nil && !fi.IsDir() {
onFile(so)
}
}
}
}
// process command-line args (patterns/files):
for _, p := range GlobMany(args.Patterns, nil) {
onFile(p)
}
// convert map values to slice of strings:
retval = make([]string, 0, len(deps)/2)
for p, _ := range deps {
retval = append(retval, p)
}
return retval
}