OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 server |
| 6 |
| 7 import ( |
| 8 "fmt" |
| 9 "regexp" |
| 10 |
| 11 "code.google.com/p/ogle/debug/dwarf" |
| 12 ) |
| 13 |
| 14 func (s *Server) lookupRE(re *regexp.Regexp) (result []string, err error) { |
| 15 r := s.dwarfData.Reader() |
| 16 for { |
| 17 entry, err := r.Next() |
| 18 if err != nil { |
| 19 return nil, err |
| 20 } |
| 21 if entry == nil { |
| 22 // TODO: why don't we get an error here. |
| 23 break |
| 24 } |
| 25 if entry.Tag != dwarf.TagSubprogram { |
| 26 continue |
| 27 } |
| 28 nameAttr := lookupAttr(entry, dwarf.AttrName) |
| 29 if nameAttr == nil { |
| 30 // TODO: this shouldn't be possible. |
| 31 continue |
| 32 } |
| 33 name, ok := nameAttr.(string) |
| 34 if !ok || !re.MatchString(name) { |
| 35 continue |
| 36 } |
| 37 result = append(result, name) |
| 38 } |
| 39 return result, nil |
| 40 } |
| 41 |
| 42 func (s *Server) lookupSym(name string) (uint64, error) { |
| 43 r := s.dwarfData.Reader() |
| 44 for { |
| 45 entry, err := r.Next() |
| 46 if err != nil { |
| 47 return 0, err |
| 48 } |
| 49 if entry == nil { |
| 50 // TODO: why don't we get an error here. |
| 51 break |
| 52 } |
| 53 if entry.Tag != dwarf.TagSubprogram { |
| 54 continue |
| 55 } |
| 56 nameAttr := lookupAttr(entry, dwarf.AttrName) |
| 57 if nameAttr == nil { |
| 58 // TODO: this shouldn't be possible. |
| 59 continue |
| 60 } |
| 61 if nameAttr.(string) != name { |
| 62 continue |
| 63 } |
| 64 addrAttr := lookupAttr(entry, dwarf.AttrLowpc) |
| 65 if addrAttr == nil { |
| 66 return 0, fmt.Errorf("symbol %q has no LowPC attribute",
name) |
| 67 } |
| 68 addr, ok := addrAttr.(uint64) |
| 69 if !ok { |
| 70 return 0, fmt.Errorf("symbol %q has non-uint64 LowPC att
ribute", name) |
| 71 } |
| 72 return addr, nil |
| 73 } |
| 74 return 0, fmt.Errorf("symbol %q not found", name) |
| 75 } |
| 76 |
| 77 func (s *Server) lookupPC(pc uint64) (string, error) { |
| 78 r := s.dwarfData.Reader() |
| 79 for { |
| 80 entry, err := r.Next() |
| 81 if err != nil { |
| 82 return "", err |
| 83 } |
| 84 if entry == nil { |
| 85 // TODO: why don't we get an error here. |
| 86 break |
| 87 } |
| 88 if entry.Tag != dwarf.TagSubprogram { |
| 89 continue |
| 90 } |
| 91 lowpc, lok := lookupAttr(entry, dwarf.AttrLowpc).(uint64) |
| 92 highpc, hok := lookupAttr(entry, dwarf.AttrHighpc).(uint64) |
| 93 if !lok || !hok || pc < lowpc || highpc <= pc { |
| 94 continue |
| 95 } |
| 96 nameAttr := lookupAttr(entry, dwarf.AttrName) |
| 97 if nameAttr == nil { |
| 98 // TODO: this shouldn't be possible. |
| 99 continue |
| 100 } |
| 101 name, ok := nameAttr.(string) |
| 102 if !ok { |
| 103 return "", fmt.Errorf("name for PC %#x is not a string",
pc) |
| 104 } |
| 105 return name, nil |
| 106 } |
| 107 return "", fmt.Errorf("PC %#x not found", pc) |
| 108 } |
| 109 |
| 110 func lookupAttr(e *dwarf.Entry, a dwarf.Attr) interface{} { |
| 111 for _, f := range e.Field { |
| 112 if f.Attr == a { |
| 113 return f.Val |
| 114 } |
| 115 } |
| 116 return nil |
| 117 } |
| 118 |
| 119 func evalLocation(v []uint8) string { |
| 120 if len(v) == 0 { |
| 121 return "<nil>" |
| 122 } |
| 123 if v[0] != 0x9C { // DW_OP_call_frame_cfa |
| 124 return "UNK0" |
| 125 } |
| 126 if len(v) == 1 { |
| 127 return "0" |
| 128 } |
| 129 v = v[1:] |
| 130 if v[0] != 0x11 { // DW_OP_consts |
| 131 return "UNK1" |
| 132 } |
| 133 return fmt.Sprintf("%x", sleb128(v[1:])) |
| 134 } |
| 135 |
| 136 func uleb128(v []uint8) (u uint64) { |
| 137 var shift uint |
| 138 for _, x := range v { |
| 139 u |= (uint64(x) & 0x7F) << shift |
| 140 shift += 7 |
| 141 if x&0x80 == 0 { |
| 142 break |
| 143 } |
| 144 } |
| 145 return u |
| 146 } |
| 147 |
| 148 func sleb128(v []uint8) (s int64) { |
| 149 var shift uint |
| 150 var sign int64 = -1 |
| 151 for _, x := range v { |
| 152 s |= (int64(x) & 0x7F) << shift |
| 153 shift += 7 |
| 154 sign <<= 7 |
| 155 if x&0x80 == 0 { |
| 156 if x&0x40 != 0 { |
| 157 s |= sign |
| 158 } |
| 159 break |
| 160 } |
| 161 } |
| 162 // Sign extend? |
| 163 return s |
| 164 } |
OLD | NEW |