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