Source file
misc/cgo/test/buildid_linux.go
1
2
3
4
5 package cgotest
6
7
8
9
10
11
12 import (
13 "bytes"
14 "debug/elf"
15 "os"
16 "testing"
17 )
18
19 func testBuildID(t *testing.T) {
20 f, err := elf.Open("/proc/self/exe")
21 if err != nil {
22 if os.IsNotExist(err) {
23 t.Skip("no /proc/self/exe")
24 }
25 t.Fatal("opening /proc/self/exe: ", err)
26 }
27 defer f.Close()
28
29 c := 0
30 sections:
31 for i, s := range f.Sections {
32 if s.Type != elf.SHT_NOTE {
33 continue
34 }
35
36 d, err := s.Data()
37 if err != nil {
38 t.Logf("reading data of note section %d: %v", i, err)
39 continue
40 }
41
42 for len(d) > 0 {
43
44
45
46
47
48
49 if len(d) < 12 {
50 t.Logf("note section %d too short (%d < 12)", i, len(d))
51 continue sections
52 }
53
54 namesz := f.ByteOrder.Uint32(d)
55 descsz := f.ByteOrder.Uint32(d[4:])
56 typ := f.ByteOrder.Uint32(d[8:])
57
58 an := (namesz + 3) &^ 3
59 ad := (descsz + 3) &^ 3
60
61 if int(12+an+ad) > len(d) {
62 t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
63 continue sections
64 }
65
66
67 if typ == 3 && namesz == 4 && bytes.Equal(d[12:16], []byte("GNU\000")) {
68 c++
69 }
70
71 d = d[12+an+ad:]
72 }
73 }
74
75 if c > 1 {
76 t.Errorf("found %d build ID notes", c)
77 }
78 }
79
View as plain text