github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/debug/dwarf/entry.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 // DWARF debug information entry parser. 6 // An entry is a sequence of data items of a given format. 7 // The first word in the entry is an index into what DWARF 8 // calls the ``abbreviation table.'' An abbreviation is really 9 // just a type descriptor: it's an array of attribute tag/value format pairs. 10 11 package dwarf 12 13 import "errors" 14 15 // a single entry's description: a sequence of attributes 16 type abbrev struct { 17 tag Tag 18 children bool 19 field []afield 20 } 21 22 type afield struct { 23 attr Attr 24 fmt format 25 } 26 27 // a map from entry format ids to their descriptions 28 type abbrevTable map[uint32]abbrev 29 30 // ParseAbbrev returns the abbreviation table that starts at byte off 31 // in the .debug_abbrev section. 32 func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) { 33 if m, ok := d.abbrevCache[off]; ok { 34 return m, nil 35 } 36 37 data := d.abbrev 38 if off > uint32(len(data)) { 39 data = nil 40 } else { 41 data = data[off:] 42 } 43 b := makeBuf(d, unknownFormat{}, "abbrev", 0, data) 44 45 // Error handling is simplified by the buf getters 46 // returning an endless stream of 0s after an error. 47 m := make(abbrevTable) 48 for { 49 // Table ends with id == 0. 50 id := uint32(b.uint()) 51 if id == 0 { 52 break 53 } 54 55 // Walk over attributes, counting. 56 n := 0 57 b1 := b // Read from copy of b. 58 b1.uint() 59 b1.uint8() 60 for { 61 tag := b1.uint() 62 fmt := b1.uint() 63 if tag == 0 && fmt == 0 { 64 break 65 } 66 n++ 67 } 68 if b1.err != nil { 69 return nil, b1.err 70 } 71 72 // Walk over attributes again, this time writing them down. 73 var a abbrev 74 a.tag = Tag(b.uint()) 75 a.children = b.uint8() != 0 76 a.field = make([]afield, n) 77 for i := range a.field { 78 a.field[i].attr = Attr(b.uint()) 79 a.field[i].fmt = format(b.uint()) 80 } 81 b.uint() 82 b.uint() 83 84 m[id] = a 85 } 86 if b.err != nil { 87 return nil, b.err 88 } 89 d.abbrevCache[off] = m 90 return m, nil 91 } 92 93 // An entry is a sequence of attribute/value pairs. 94 type Entry struct { 95 Offset Offset // offset of Entry in DWARF info 96 Tag Tag // tag (kind of Entry) 97 Children bool // whether Entry is followed by children 98 Field []Field 99 } 100 101 // A Field is a single attribute/value pair in an Entry. 102 type Field struct { 103 Attr Attr 104 Val interface{} 105 } 106 107 // Val returns the value associated with attribute Attr in Entry, 108 // or nil if there is no such attribute. 109 // 110 // A common idiom is to merge the check for nil return with 111 // the check that the value has the expected dynamic type, as in: 112 // v, ok := e.Val(AttrSibling).(int64); 113 // 114 func (e *Entry) Val(a Attr) interface{} { 115 for _, f := range e.Field { 116 if f.Attr == a { 117 return f.Val 118 } 119 } 120 return nil 121 } 122 123 // An Offset represents the location of an Entry within the DWARF info. 124 // (See Reader.Seek.) 125 type Offset uint32 126 127 // Entry reads a single entry from buf, decoding 128 // according to the given abbreviation table. 129 func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { 130 off := b.off 131 id := uint32(b.uint()) 132 if id == 0 { 133 return &Entry{} 134 } 135 a, ok := atab[id] 136 if !ok { 137 b.error("unknown abbreviation table index") 138 return nil 139 } 140 e := &Entry{ 141 Offset: off, 142 Tag: a.tag, 143 Children: a.children, 144 Field: make([]Field, len(a.field)), 145 } 146 for i := range e.Field { 147 e.Field[i].Attr = a.field[i].attr 148 fmt := a.field[i].fmt 149 if fmt == formIndirect { 150 fmt = format(b.uint()) 151 } 152 var val interface{} 153 switch fmt { 154 default: 155 b.error("unknown entry attr format") 156 157 // address 158 case formAddr: 159 val = b.addr() 160 161 // block 162 case formDwarfBlock1: 163 val = b.bytes(int(b.uint8())) 164 case formDwarfBlock2: 165 val = b.bytes(int(b.uint16())) 166 case formDwarfBlock4: 167 val = b.bytes(int(b.uint32())) 168 case formDwarfBlock: 169 val = b.bytes(int(b.uint())) 170 171 // constant 172 case formData1: 173 val = int64(b.uint8()) 174 case formData2: 175 val = int64(b.uint16()) 176 case formData4: 177 val = int64(b.uint32()) 178 case formData8: 179 val = int64(b.uint64()) 180 case formSdata: 181 val = int64(b.int()) 182 case formUdata: 183 val = int64(b.uint()) 184 185 // flag 186 case formFlag: 187 val = b.uint8() == 1 188 case formFlagPresent: 189 // The attribute is implicitly indicated as present, and no value is 190 // encoded in the debugging information entry itself. 191 val = true 192 193 // reference to other entry 194 case formRefAddr: 195 vers := b.format.version() 196 if vers == 0 { 197 b.error("unknown version for DW_FORM_ref_addr") 198 } else if vers == 2 { 199 val = Offset(b.addr()) 200 } else { 201 is64, known := b.format.dwarf64() 202 if !known { 203 b.error("unknown size for DW_FORM_ref_addr") 204 } else if is64 { 205 val = Offset(b.uint64()) 206 } else { 207 val = Offset(b.uint32()) 208 } 209 } 210 case formRef1: 211 val = Offset(b.uint8()) + ubase 212 case formRef2: 213 val = Offset(b.uint16()) + ubase 214 case formRef4: 215 val = Offset(b.uint32()) + ubase 216 case formRef8: 217 val = Offset(b.uint64()) + ubase 218 case formRefUdata: 219 val = Offset(b.uint()) + ubase 220 221 // string 222 case formString: 223 val = b.string() 224 case formStrp: 225 off := b.uint32() // offset into .debug_str 226 if b.err != nil { 227 return nil 228 } 229 b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str) 230 b1.skip(int(off)) 231 val = b1.string() 232 if b1.err != nil { 233 b.err = b1.err 234 return nil 235 } 236 } 237 e.Field[i].Val = val 238 } 239 if b.err != nil { 240 return nil 241 } 242 return e 243 } 244 245 // A Reader allows reading Entry structures from a DWARF ``info'' section. 246 // The Entry structures are arranged in a tree. The Reader's Next function 247 // return successive entries from a pre-order traversal of the tree. 248 // If an entry has children, its Children field will be true, and the children 249 // follow, terminated by an Entry with Tag 0. 250 type Reader struct { 251 b buf 252 d *Data 253 err error 254 unit int 255 lastChildren bool // .Children of last entry returned by Next 256 lastSibling Offset // .Val(AttrSibling) of last entry returned by Next 257 } 258 259 // Reader returns a new Reader for Data. 260 // The reader is positioned at byte offset 0 in the DWARF ``info'' section. 261 func (d *Data) Reader() *Reader { 262 r := &Reader{d: d} 263 r.Seek(0) 264 return r 265 } 266 267 // Seek positions the Reader at offset off in the encoded entry stream. 268 // Offset 0 can be used to denote the first entry. 269 func (r *Reader) Seek(off Offset) { 270 d := r.d 271 r.err = nil 272 r.lastChildren = false 273 if off == 0 { 274 if len(d.unit) == 0 { 275 return 276 } 277 u := &d.unit[0] 278 r.unit = 0 279 r.b = makeBuf(r.d, u, "info", u.off, u.data) 280 return 281 } 282 283 // TODO(rsc): binary search (maybe a new package) 284 var i int 285 var u *unit 286 for i = range d.unit { 287 u = &d.unit[i] 288 if u.off <= off && off < u.off+Offset(len(u.data)) { 289 r.unit = i 290 r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) 291 return 292 } 293 } 294 r.err = errors.New("offset out of range") 295 } 296 297 // maybeNextUnit advances to the next unit if this one is finished. 298 func (r *Reader) maybeNextUnit() { 299 for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) { 300 r.unit++ 301 u := &r.d.unit[r.unit] 302 r.b = makeBuf(r.d, u, "info", u.off, u.data) 303 } 304 } 305 306 // Next reads the next entry from the encoded entry stream. 307 // It returns nil, nil when it reaches the end of the section. 308 // It returns an error if the current offset is invalid or the data at the 309 // offset cannot be decoded as a valid Entry. 310 func (r *Reader) Next() (*Entry, error) { 311 if r.err != nil { 312 return nil, r.err 313 } 314 r.maybeNextUnit() 315 if len(r.b.data) == 0 { 316 return nil, nil 317 } 318 u := &r.d.unit[r.unit] 319 e := r.b.entry(u.atable, u.base) 320 if r.b.err != nil { 321 r.err = r.b.err 322 return nil, r.err 323 } 324 if e != nil { 325 r.lastChildren = e.Children 326 if r.lastChildren { 327 r.lastSibling, _ = e.Val(AttrSibling).(Offset) 328 } 329 } else { 330 r.lastChildren = false 331 } 332 return e, nil 333 } 334 335 // SkipChildren skips over the child entries associated with 336 // the last Entry returned by Next. If that Entry did not have 337 // children or Next has not been called, SkipChildren is a no-op. 338 func (r *Reader) SkipChildren() { 339 if r.err != nil || !r.lastChildren { 340 return 341 } 342 343 // If the last entry had a sibling attribute, 344 // that attribute gives the offset of the next 345 // sibling, so we can avoid decoding the 346 // child subtrees. 347 if r.lastSibling >= r.b.off { 348 r.Seek(r.lastSibling) 349 return 350 } 351 352 for { 353 e, err := r.Next() 354 if err != nil || e == nil || e.Tag == 0 { 355 break 356 } 357 if e.Children { 358 r.SkipChildren() 359 } 360 } 361 }