github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/debug/dwarf/open.go (about) 1 // Copyright 2009 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 dwarf provides access to DWARF debugging information loaded from 6 // executable files, as defined in the DWARF 2.0 Standard at 7 // http://dwarfstd.org/doc/dwarf-2.0.0.pdf 8 package dwarf 9 10 import "encoding/binary" 11 12 // Data represents the DWARF debugging information 13 // loaded from an executable file (for example, an ELF or Mach-O executable). 14 type Data struct { 15 // raw data 16 abbrev []byte 17 aranges []byte 18 frame []byte 19 info []byte 20 line []byte 21 pubnames []byte 22 ranges []byte 23 str []byte 24 25 // parsed data 26 abbrevCache map[uint64]abbrevTable 27 order binary.ByteOrder 28 typeCache map[Offset]Type 29 typeSigs map[uint64]*typeUnit 30 unit []unit 31 } 32 33 // New returns a new Data object initialized from the given parameters. 34 // Rather than calling this function directly, clients should typically use 35 // the DWARF method of the File type of the appropriate package debug/elf, 36 // debug/macho, or debug/pe. 37 // 38 // The []byte arguments are the data from the corresponding debug section 39 // in the object file; for example, for an ELF object, abbrev is the contents of 40 // the ".debug_abbrev" section. 41 func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) { 42 d := &Data{ 43 abbrev: abbrev, 44 aranges: aranges, 45 frame: frame, 46 info: info, 47 line: line, 48 pubnames: pubnames, 49 ranges: ranges, 50 str: str, 51 abbrevCache: make(map[uint64]abbrevTable), 52 typeCache: make(map[Offset]Type), 53 typeSigs: make(map[uint64]*typeUnit), 54 } 55 56 // Sniff .debug_info to figure out byte order. 57 // 32-bit DWARF: 4 byte length, 2 byte version. 58 // 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version. 59 if len(d.info) < 6 { 60 return nil, DecodeError{"info", Offset(len(d.info)), "too short"} 61 } 62 offset := 4 63 if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff { 64 if len(d.info) < 14 { 65 return nil, DecodeError{"info", Offset(len(d.info)), "too short"} 66 } 67 offset = 12 68 } 69 // Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5). 70 x, y := d.info[offset], d.info[offset+1] 71 switch { 72 case x == 0 && y == 0: 73 return nil, DecodeError{"info", 4, "unsupported version 0"} 74 case x == 0: 75 d.order = binary.BigEndian 76 case y == 0: 77 d.order = binary.LittleEndian 78 default: 79 return nil, DecodeError{"info", 4, "cannot determine byte order"} 80 } 81 82 u, err := d.parseUnits() 83 if err != nil { 84 return nil, err 85 } 86 d.unit = u 87 return d, nil 88 } 89 90 // AddTypes will add one .debug_types section to the DWARF data. A 91 // typical object with DWARF version 4 debug info will have multiple 92 // .debug_types sections. The name is used for error reporting only, 93 // and serves to distinguish one .debug_types section from another. 94 func (d *Data) AddTypes(name string, types []byte) error { 95 return d.parseTypes(name, types) 96 }