]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/cgo/internal/test/buildid_linux.go
misc/cgo: move registerCgoTests tests to cmd/cgo/internal
[gostls13.git] / src / cmd / cgo / internal / test / buildid_linux.go
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package cgotest
6
7 // Test that we have no more than one build ID.  In the past we used
8 // to generate a separate build ID for each package using cgo, and the
9 // linker concatenated them all.  We don't want that--we only want
10 // one.
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                         // ELF standards differ as to the sizes in
45                         // note sections.  Both the GNU linker and
46                         // gold always generate 32-bit sizes, so that
47                         // is what we assume here.
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                         // 3 == NT_GNU_BUILD_ID
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 }