Source file src/cmd/cgo/internal/testplugin/testdata/checkdwarf/main.go

     1  // Copyright 2018 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  // Usage:
     6  //
     7  //  checkdwarf <exe> <suffix>
     8  //
     9  // Opens <exe>, which must be an executable or a library and checks that
    10  // there is an entry in .debug_info whose name ends in <suffix>
    11  
    12  package main
    13  
    14  import (
    15  	"debug/dwarf"
    16  	"debug/elf"
    17  	"debug/macho"
    18  	"debug/pe"
    19  	"fmt"
    20  	"os"
    21  	"strings"
    22  )
    23  
    24  func usage() {
    25  	fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n")
    26  }
    27  
    28  type dwarfer interface {
    29  	DWARF() (*dwarf.Data, error)
    30  }
    31  
    32  func openElf(path string) dwarfer {
    33  	exe, err := elf.Open(path)
    34  	if err != nil {
    35  		return nil
    36  	}
    37  	return exe
    38  }
    39  
    40  func openMacho(path string) dwarfer {
    41  	exe, err := macho.Open(path)
    42  	if err != nil {
    43  		return nil
    44  	}
    45  	return exe
    46  }
    47  
    48  func openPE(path string) dwarfer {
    49  	exe, err := pe.Open(path)
    50  	if err != nil {
    51  		return nil
    52  	}
    53  	return exe
    54  }
    55  
    56  func main() {
    57  	if len(os.Args) != 3 {
    58  		usage()
    59  	}
    60  
    61  	exePath := os.Args[1]
    62  	dieSuffix := os.Args[2]
    63  
    64  	var exe dwarfer
    65  
    66  	for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} {
    67  		exe = openfn(exePath)
    68  		if exe != nil {
    69  			break
    70  		}
    71  	}
    72  
    73  	if exe == nil {
    74  		fmt.Fprintf(os.Stderr, "could not open %s\n", exePath)
    75  		os.Exit(1)
    76  	}
    77  
    78  	data, err := exe.DWARF()
    79  	if err != nil {
    80  		fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err)
    81  		os.Exit(1)
    82  	}
    83  
    84  	rdr := data.Reader()
    85  	for {
    86  		e, err := rdr.Next()
    87  		if err != nil {
    88  			fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err)
    89  			os.Exit(1)
    90  		}
    91  		if e == nil {
    92  			break
    93  		}
    94  		name, hasname := e.Val(dwarf.AttrName).(string)
    95  		if !hasname {
    96  			continue
    97  		}
    98  		if strings.HasSuffix(name, dieSuffix) {
    99  			// found
   100  			os.Exit(0)
   101  		}
   102  	}
   103  
   104  	fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix)
   105  	os.Exit(1)
   106  }
   107  

View as plain text