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.
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
19 func testBuildID(t *testing.T) {
20 f, err := elf.Open("/proc/self/exe")
22 if os.IsNotExist(err) {
23 t.Skip("no /proc/self/exe")
25 t.Fatal("opening /proc/self/exe: ", err)
31 for i, s := range f.Sections {
32 if s.Type != elf.SHT_NOTE {
38 t.Logf("reading data of note section %d: %v", i, err)
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.
50 t.Logf("note section %d too short (%d < 12)", i, len(d))
54 namesz := f.ByteOrder.Uint32(d)
55 descsz := f.ByteOrder.Uint32(d[4:])
56 typ := f.ByteOrder.Uint32(d[8:])
58 an := (namesz + 3) &^ 3
59 ad := (descsz + 3) &^ 3
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)
66 // 3 == NT_GNU_BUILD_ID
67 if typ == 3 && namesz == 4 && bytes.Equal(d[12:16], []byte("GNU\000")) {
76 t.Errorf("found %d build ID notes", c)