github.com/bir3/gocompiler@v0.9.2202/src/cmd/cgo/internal/test/buildid_linux.go (about) 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 }