1 """
2 The API describing what it means to be an envi compliant
3 symbol resolver.
4 """
5
6 import types
7
9
10 - def __init__(self, name, value, size=0, fname=None):
11 self.name = name
12 self.value = value
13 self.size = size
14 self.fname = fname
15
17 if not isinstance(other, Symbol):
18 return False
19 return long(self) == long(other)
20
22 t = type(value)
23 if t == types.NoneType:
24 return (True, False)
25 return (value, t(self.value))
26
28 return hash(long(self))
29
31 return long(self.value)
32
34 return int(self.value)
35
38
40 if self.fname != None:
41 return "%s.%s" % (self.fname, self.name)
42 return self.name
43
46
48
49 """
50 NOTE: Nothing should reach directly into a SymbolResolver!
51 """
52
53 - def __init__(self, width=4, casesens=True):
54 self.width = width
55 self.widthmask = (2**(width*8))-1
56 self.casesens = casesens
57
58 self.bucketsize = 4096
59 self.bucketmask = self.widthmask ^ (self.bucketsize-1)
60 self.buckets = {}
61 self.symnames = {}
62 self.symaddrs = {}
63
65 """
66 Delete a symbol from the resolver's namespace
67 """
68 symval = long(sym)
69 self.symaddrs.pop(symval, None)
70
71 bbase = symval & self.bucketmask
72 while bbase < symval:
73 bucket = self.buckets.get(bbase)
74 bucket.remove(sym)
75 bbase += self.bucketsize
76
77 subres = None
78 if sym.fname != None:
79 subres = self.symnames.get(sym.fname)
80
81
82 if subres != None:
83 subres.delSymbol(sym)
84
85
86 else:
87 symname = sym.name
88 if not self.casesens:
89 symname = symname.lower()
90 self.symnames.pop(symname, None)
91
93 """
94 Add a symbol to the resolver.
95 """
96
97
98
99 symval = long(sym)
100 self.symaddrs[symval] = sym
101
102 bbase = symval & self.bucketmask
103 while bbase < symval:
104 bucket = self.buckets.get(bbase)
105 if bucket == None:
106 bucket = []
107 self.buckets[bbase] = bucket
108 bucket.append(sym)
109 bbase += self.bucketsize
110
111 subres = None
112 if sym.fname != None:
113 subres = self.symnames.get(sym.fname)
114
115
116 if subres != None:
117 subres.addSymbol(sym)
118
119
120 else:
121 symname = sym.name
122 if not self.casesens:
123 symname = symname.lower()
124 self.symnames[symname] = sym
125
127 if not self.casesens:
128 name = name.lower()
129 return self.symnames.get(name)
130
132 """
133 Return a symbol object for the given virtual address.
134 """
135 va = va & self.widthmask
136 sym = self.symaddrs.get(va)
137
138 if sym != None:
139 return sym
140
141 if not exact:
142 b = va & self.bucketmask
143 best = 999999999
144 while sym == None:
145 bucket = self.buckets.get(b)
146 if bucket != None:
147 for s in bucket:
148 sva = long(s)
149 if sva > va:
150 continue
151 offset = va - sva
152 if offset < best:
153 best = offset
154 sym = s
155
156 if va - b > 8192:
157 break
158
159 b -= self.bucketsize
160
161
162
163 if isinstance(sym, SymbolResolver):
164 ssym = sym.getSymByAddr(va, exact=exact)
165 if ssym != None:
166 return ssym
167
168 return sym
169
171 """
172 Return a list of the symbols which are contained in this resolver.
173 """
174 return self.symaddrs.values()
175
177 """
178 May be used by symbol resolvers who know what type they are
179 resolving to store and retrieve "hints" with indexes.
180
181 Used specifically by opcode render methods to resolve
182 any memory dereference info for a given operand.
183
184 NOTE: These are mostly symbolic references to FRAME LOCAL
185 names....
186 """
187 return None
188
189
190
192 """
193 Used to represent functions.
194 """
196 return "%s.%s()" % (self.fname, self.name)
197
199 """
200 Used for file sections/segments.
201 """
203 return "%s[%s]" % (self.fname,self.name)
204
206 """
207 A file symbol is both a symbol resolver of it's own, and
208 a symbol.
209
210 File symbols are used to do heirarchal symbol lookups and don't
211 actually add anything but the name to their lookup (it is assumed
212 that the parent Resolver of the FileSymbol takes care of addr lookups.
213 """
214 - def __init__(self, fname, base, size, width=4):
217
219 """
220 File symbols may be dereferenced like python objects to resolve
221 symbols within them.
222 """
223 ret = self.getSymByName(name)
224 if ret == None:
225 raise AttributeError("%s has no symbol %s" % (self.name,name))
226 return ret
227
229 """
230 Allow dictionary style access for mangled incompatible names...
231 """
232 ret = self.getSymByName(name)
233 if ret == None:
234 raise KeyError("%s has no symbol %s" % (self.name,name))
235 return ret
236