1 // skip 2 3 // Copyright 2015 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // This is built by issue10607.go with a -B option. 8 // Verify that we have one build-id note with the expected value. 9 10 package main 11 12 import ( 13 "bytes" 14 "debug/elf" 15 "fmt" 16 "os" 17 ) 18 19 func main() { 20 f, err := elf.Open("/proc/self/exe") 21 if err != nil { 22 if os.IsNotExist(err) { 23 return 24 } 25 fmt.Fprintln(os.Stderr, "opening /proc/self/exe:", err) 26 os.Exit(1) 27 } 28 29 c := 0 30 fail := false 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 fmt.Fprintln(os.Stderr, "reading data of note section %d: %v", i, err) 39 continue 40 } 41 42 for len(d) > 0 { 43 namesz := f.ByteOrder.Uint32(d) 44 descsz := f.ByteOrder.Uint32(d[4:]) 45 typ := f.ByteOrder.Uint32(d[8:]) 46 47 an := (namesz + 3) &^ 3 48 ad := (descsz + 3) &^ 3 49 50 if int(12+an+ad) > len(d) { 51 fmt.Fprintf(os.Stderr, "note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))\n", i, len(d), namesz, descsz) 52 break 53 } 54 55 // 3 == NT_GNU_BUILD_ID 56 if typ == 3 && namesz == 4 && bytes.Equal(d[12:16], []byte("GNU\000")) { 57 id := string(d[12+an:12+an+descsz]) 58 if id == "\x12\x34\x56\x78" { 59 c++ 60 } else { 61 fmt.Fprintf(os.Stderr, "wrong build ID data: %q\n", id) 62 fail = true 63 } 64 } 65 66 d = d[12+an+ad:] 67 } 68 } 69 70 if c == 0 { 71 fmt.Fprintln(os.Stderr, "no build-id note") 72 fail = true 73 } else if c > 1 { 74 fmt.Fprintln(os.Stderr, c, "build-id notes") 75 fail = true 76 } 77 78 if fail { 79 os.Exit(1) 80 } 81 } 82