OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package gosym implements access to the Go symbol | 5 // Package gosym implements access to the Go symbol |
6 // and line number tables embedded in Go binaries generated | 6 // and line number tables embedded in Go binaries generated |
7 // by the gc compilers. | 7 // by the gc compilers. |
8 package gosym | 8 package gosym |
9 | 9 |
10 // The table format is a variant of the format used in Plan 9's a.out | 10 // The table format is a variant of the format used in Plan 9's a.out |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 name []byte | 122 name []byte |
123 } | 123 } |
124 | 124 |
125 var ( | 125 var ( |
126 littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00} | 126 littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00} |
127 bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00} | 127 bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00} |
128 oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} | 128 oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} |
129 ) | 129 ) |
130 | 130 |
131 func walksymtab(data []byte, fn func(sym) error) error { | 131 func walksymtab(data []byte, fn func(sym) error) error { |
| 132 if len(data) == 0 { // missing symtab is okay |
| 133 return nil |
| 134 } |
132 var order binary.ByteOrder = binary.BigEndian | 135 var order binary.ByteOrder = binary.BigEndian |
133 newTable := false | 136 newTable := false |
134 switch { | 137 switch { |
135 case bytes.HasPrefix(data, oldLittleEndianSymtab): | 138 case bytes.HasPrefix(data, oldLittleEndianSymtab): |
136 // Same as Go 1.0, but little endian. | 139 // Same as Go 1.0, but little endian. |
137 // Format was used during interim development between Go 1.0 and
Go 1.1. | 140 // Format was used during interim development between Go 1.0 and
Go 1.1. |
138 // Should not be widespread, but easy to support. | 141 // Should not be widespread, but easy to support. |
139 data = data[6:] | 142 data = data[6:] |
140 order = binary.LittleEndian | 143 order = binary.LittleEndian |
141 case bytes.HasPrefix(data, bigEndianSymtab): | 144 case bytes.HasPrefix(data, bigEndianSymtab): |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 fn.Params[n] = s | 451 fn.Params[n] = s |
449 case 'a': | 452 case 'a': |
450 n := len(fn.Locals) | 453 n := len(fn.Locals) |
451 fn.Locals = fn.Locals[0 : n+1] | 454 fn.Locals = fn.Locals[0 : n+1] |
452 fn.Locals[n] = s | 455 fn.Locals[n] = s |
453 } | 456 } |
454 } | 457 } |
455 i = end - 1 // loop will i++ | 458 i = end - 1 // loop will i++ |
456 } | 459 } |
457 } | 460 } |
| 461 |
| 462 if t.go12line != nil && nf == 0 { |
| 463 t.Funcs = t.go12line.go12Funcs() |
| 464 } |
458 if obj != nil { | 465 if obj != nil { |
459 obj.Funcs = t.Funcs[lastf:] | 466 obj.Funcs = t.Funcs[lastf:] |
460 } | 467 } |
461 return &t, nil | 468 return &t, nil |
462 } | 469 } |
463 | 470 |
464 // PCToFunc returns the function containing the program counter pc, | 471 // PCToFunc returns the function containing the program counter pc, |
465 // or nil if there is no such function. | 472 // or nil if there is no such function. |
466 func (t *Table) PCToFunc(pc uint64) *Func { | 473 func (t *Table) PCToFunc(pc uint64) *Func { |
467 funcs := t.Funcs | 474 funcs := t.Funcs |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 701 } |
695 | 702 |
696 func (e *DecodingError) Error() string { | 703 func (e *DecodingError) Error() string { |
697 msg := e.msg | 704 msg := e.msg |
698 if e.val != nil { | 705 if e.val != nil { |
699 msg += fmt.Sprintf(" '%v'", e.val) | 706 msg += fmt.Sprintf(" '%v'", e.val) |
700 } | 707 } |
701 msg += fmt.Sprintf(" at byte %#x", e.off) | 708 msg += fmt.Sprintf(" at byte %#x", e.off) |
702 return msg | 709 return msg |
703 } | 710 } |
OLD | NEW |