github.com/bir3/gocompiler@v0.9.2202/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 /* 6 Package dwarf provides access to DWARF debugging information loaded from 7 executable files, as defined in the DWARF 2.0 Standard at 8 http://dwarfstd.org/doc/dwarf-2.0.0.pdf. 9 10 # Security 11 12 This package is not designed to be hardened against adversarial inputs, and is 13 outside the scope of https://go.dev/security/policy. In particular, only basic 14 validation is done when parsing object files. As such, care should be taken when 15 parsing untrusted inputs, as parsing malformed files may consume significant 16 resources, or cause panics. 17 */ 18 package dwarf 19 20 import ( 21 "encoding/binary" 22 "errors" 23 ) 24 25 // Data represents the DWARF debugging information 26 // loaded from an executable file (for example, an ELF or Mach-O executable). 27 type Data struct { 28 // raw data 29 abbrev []byte 30 aranges []byte 31 frame []byte 32 info []byte 33 line []byte 34 pubnames []byte 35 ranges []byte 36 str []byte 37 38 // New sections added in DWARF 5. 39 addr []byte 40 lineStr []byte 41 strOffsets []byte 42 rngLists []byte 43 44 // parsed data 45 abbrevCache map[uint64]abbrevTable 46 bigEndian bool 47 order binary.ByteOrder 48 typeCache map[Offset]Type 49 typeSigs map[uint64]*typeUnit 50 unit []unit 51 } 52 53 var errSegmentSelector = errors.New("non-zero segment_selector size not supported") 54 55 // New returns a new [Data] object initialized from the given parameters. 56 // Rather than calling this function directly, clients should typically use 57 // the DWARF method of the File type of the appropriate package [debug/elf], 58 // [debug/macho], or [debug/pe]. 59 // 60 // The []byte arguments are the data from the corresponding debug section 61 // in the object file; for example, for an ELF object, abbrev is the contents of 62 // the ".debug_abbrev" section. 63 func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) { 64 d := &Data{ 65 abbrev: abbrev, 66 aranges: aranges, 67 frame: frame, 68 info: info, 69 line: line, 70 pubnames: pubnames, 71 ranges: ranges, 72 str: str, 73 abbrevCache: make(map[uint64]abbrevTable), 74 typeCache: make(map[Offset]Type), 75 typeSigs: make(map[uint64]*typeUnit), 76 } 77 78 // Sniff .debug_info to figure out byte order. 79 // 32-bit DWARF: 4 byte length, 2 byte version. 80 // 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version. 81 if len(d.info) < 6 { 82 return nil, DecodeError{"info", Offset(len(d.info)), "too short"} 83 } 84 offset := 4 85 if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff { 86 if len(d.info) < 14 { 87 return nil, DecodeError{"info", Offset(len(d.info)), "too short"} 88 } 89 offset = 12 90 } 91 // Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5). 92 x, y := d.info[offset], d.info[offset+1] 93 switch { 94 case x == 0 && y == 0: 95 return nil, DecodeError{"info", 4, "unsupported version 0"} 96 case x == 0: 97 d.bigEndian = true 98 d.order = binary.BigEndian 99 case y == 0: 100 d.bigEndian = false 101 d.order = binary.LittleEndian 102 default: 103 return nil, DecodeError{"info", 4, "cannot determine byte order"} 104 } 105 106 u, err := d.parseUnits() 107 if err != nil { 108 return nil, err 109 } 110 d.unit = u 111 return d, nil 112 } 113 114 // AddTypes will add one .debug_types section to the DWARF data. A 115 // typical object with DWARF version 4 debug info will have multiple 116 // .debug_types sections. The name is used for error reporting only, 117 // and serves to distinguish one .debug_types section from another. 118 func (d *Data) AddTypes(name string, types []byte) error { 119 return d.parseTypes(name, types) 120 } 121 122 // AddSection adds another DWARF section by name. The name should be a 123 // DWARF section name such as ".debug_addr", ".debug_str_offsets", and 124 // so forth. This approach is used for new DWARF sections added in 125 // DWARF 5 and later. 126 func (d *Data) AddSection(name string, contents []byte) error { 127 var err error 128 switch name { 129 case ".debug_addr": 130 d.addr = contents 131 case ".debug_line_str": 132 d.lineStr = contents 133 case ".debug_str_offsets": 134 d.strOffsets = contents 135 case ".debug_rnglists": 136 d.rngLists = contents 137 } 138 // Just ignore names that we don't yet support. 139 return err 140 }