Home | History | Annotate | Download | only in fixedbugs
      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.Fprintf(os.Stderr, "reading data of note section %d: %v\n", 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