Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / blaze / include / symbols.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: symbols.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23////////////////////////////////////////////////////////////
24//
25// File: symbols.h
26//
27// Symbol table submodule
28//
29// Copyright (C) 2006 Sun Microsystems, Inc.
30// All rights reserved.
31//
32//
33// Symbol table support.
34//
35// 1. maps address range to a symbol,
36// lookup methods need to detect that address resides inside the range.
37// more then one symbol could correspond to a particular address -
38// a label inside a routine or structure inside another structure.
39//
40// 2. elf modules could be loaded at very low and very high virtual addresses;
41// the size of address space coverage impacts the algorithm choice.
42//
43// 3. needs to provide a resonable performance for both searches :
44// by symbols name and by address.
45//
46// 4. kernel modules could have static symbols with the same name;
47//
48
49
50#ifndef _SYMBOLS_H
51#define _SYMBOLS_H
52
53#include "types.h"
54
55
56/////////////////////////////////////////////////////////
57//
58// Symbol class
59//
60
61class Symbol;
62
63// For each symbol there is only one Symbol object,
64// but if that symbol cover a few pages - SymBase marker is used
65// for each page this symbol belongs to.
66// SymBase object points to original symbol object,
67// is is used to save some mem space when marking the range.
68//
69class SymBase
70{
71protected:
72 SymBase *m_origin; // prt to origin symbol
73
74 // symbols that have overlapped address range
75 // are kept in a link list
76 SymBase *m_link; // prt to symbol if range overlaps
77
78
79 // duplicate symbol reference for address range
80 SymBase *dup()
81 {
82 SymBase *s = new SymBase (this);
83 return s;
84 }
85
86 // attach symbol to list tail
87 void attach ( SymBase *sym )
88 {
89 SymBase* tail = this;
90 while(tail->m_link)
91 tail = tail->m_link;
92 tail->m_link = sym;
93 }
94
95
96 SymBase (SymBase *o=NULL) { m_origin = o; m_link = NULL;}
97
98 // base class better have a virtual destructor but
99 // virtual table takes additional mem space
100 ~SymBase() {}
101
102public:
103 SymBase* link() { return m_link; }
104
105};
106
107
108
109// Symbol class - maintain symbol information;
110// Each symbol is defined by name, starting address,
111// and size - number of bytes in address space covered by this symbol,
112// e.g. routine, data structure and etc.
113// Only container object could add a new symbol objects to the table.
114class Symbol : public SymBase
115{
116 friend class SymTable;
117
118public:
119
120 enum
121 {
122 NUCLEUS = 0,
123 NO_CONTEXT = ~uint32_t(1),
124 ANY_CONTEXT = ~uint32_t(0)
125 };
126
127private :
128
129 char* m_name; // symbol full name
130 char* m_sname; // symbol name
131
132 uint64_t m_vaddr; // virtual address for the the object
133 uint64_t m_size; // object size in bytes
134
135 Symbol *m_next; // ptr to the next symbol in the hash table
136
137 uint32_t m_context; // 0 - kernel, -2 - hypervisor, <contextID> for user
138
139 // private constructor - only container class can construct/destruct the symbol
140 Symbol (char* mname=NULL, char* sname=NULL, uint64_t vaddr=~uint64_t(0),
141 uint64_t size =0, uint32_t context = NO_CONTEXT);
142
143 // destructor
144 ~Symbol ();
145
146
147public: // member functions
148
149 char * name () { return m_name; }
150 uint64_t vaddr () { return m_vaddr; }
151 uint64_t size () { return m_size; }
152 Symbol* next () { return m_next; }
153 uint32_t context() { return m_context; }
154
155};
156
157//////////////////////////////////////////////////////////////
158//
159// Container class for all symbols
160//
161// - symbol addresses are mapped using nested address tables;
162// - number of used address bits control how much of address space symbol table
163// will cover, if number of address bits for all tables sum up to 64 -
164// cover all address space.
165// - table size also control how much "meta data" space you are willing to
166// spend for address mapping;
167// - for smaller number of table levels address search is faster but middle tables
168// are bigger - a lot of memory is waisted to provide a faster search
169// - if symbols are loaded in a relatively small address range -
170// it requires a small number of middle tables.
171// - the number of levels and size of tables on each level is fixed
172// after construction phase.
173
174// table indexes
175//----------------------------------------------
176// level 0 | level 1 |...|level n | offset n+1 |
177//----------------------------------------------
178//
179
180class SymTable
181{
182public:
183
184 enum
185 {
186 // hash table size - should be power of 2
187 SYM_TBL_SIZE = 1<<10,
188 MAX_LEVEL = 6
189 };
190
191
192private:
193
194 // hash table - quick search by name
195 Symbol *m_bucket [SYM_TBL_SIZE];
196
197 // address tables - quick search by address;
198 // total number of tables is m_lev+1
199 void** m_tbl;
200 uint32_t m_lev; // number of table levels minus one
201
202 // arrays for each table level
203 uint32_t m_width[MAX_LEVEL+1]; // index width (number of bits)
204 uint32_t m_size [MAX_LEVEL+1]; // table size
205 uint32_t m_sft [MAX_LEVEL+1]; // index shift amount
206 uint64_t m_mask [MAX_LEVEL+1]; // index mask
207
208 bool m_empty; // true if there is no symbols
209
210
211private: // internal methods
212
213 int sym_hash ( char *s)
214 {
215 uint64_t hash = 0;
216
217 for(int i=0; i<strlen(s); i++)
218 {
219 hash = ( hash << 5 ) ^ s[i] ^ hash;
220 }
221 return hash % SYM_TBL_SIZE;
222 }
223
224 // recursively delete all tables on deeper levels
225 void delete_tbl ( void ** tbl, uint32_t level);
226
227
228 // search symbol by specified address
229 // return symbol poiner or NULL if not found
230 SymBase* find ( uint64_t addr)
231 {
232 if ( this->is_empty() )
233 return NULL;
234
235 void ** tbl = m_tbl;
236 void ** ptr = NULL;
237
238
239 for ( int i=0; i<m_lev; i++)
240 {
241 ptr = tbl + ((addr>>m_sft[i]) & m_mask[i]);
242 void **next = (void **)(*ptr);
243 if (next == NULL)
244 {
245 return NULL;
246 }
247 tbl = next;
248 }
249
250 // get a pointer from the leaf table
251 return (SymBase *)tbl[(addr>>m_sft[m_lev]) & m_mask[m_lev]];
252 }
253
254 // get a pointer in multi level addr tables;
255 // nested tables are allocated if needed
256 void **alloc( uint64_t addr );
257
258 // recursively print symbols for all tables on deeper levels
259 int print_tbl
260 (
261 FILE *fp, // output to the stream
262 void ** tbl, // table pointer
263 uint32_t level, // table level
264 uint64_t &total, // symbol counter
265 uint32_t context // symbol context
266 );
267
268public:
269
270 // constructor/destructor
271 SymTable ( uint32_t levels = MAX_LEVEL+1, uint32_t *idx_width=NULL );
272 ~SymTable ();
273
274 // Member functions
275
276 // check if container is empty
277 bool is_empty () { return m_empty; }
278
279 // find() methods combines functionality of search and iterator
280 // - use it with start=NULL to find a head of the list;
281 // to traverse the list call find() method again using start
282 // pointing to the previous symbol.
283
284 // search for address of symbol specified by symbol name;
285 // return pointer to symbol if found; 0 otherwise;
286 //
287 // different modules could have static variables (symbols) with
288 // the same name - you will get a list of the symbols with
289 // same name that reside in different modules,
290 // you need to traverse the list to get the symbols;
291 Symbol * find
292 (
293 char* name, // symbol name
294 Symbol* start=NULL // start search from this one
295 );
296
297 // find symbol specified by address ;
298 // return 1 if found, 0 otherwise;
299 // if you make a search by address - it return a list of symbols
300 // that resides at that address. Symbols address ranges could overlap.
301 // You need to traverse that list and extract symbol names.
302 SymBase* find
303 (
304 uint64_t addr, // address used to lookup the symbol
305 SymBase* start // start from this symbol
306 );
307
308 // find and output address for all symbols specified by name;
309 // return 1 if found, 0 otherwise;
310 int fputs
311 (
312 char *name, // name used to lookup the symbol
313 uint32_t context, // symbol context
314 FILE *fp // output symbol name to stream if found
315 );
316
317
318 // find and output full symbol name by specified address ;
319 // return 1 if found, 0 otherwise;
320 int fputs
321 (
322 uint64_t addr, // address used to lookup the symbol
323 uint32_t context, // symbol context
324 FILE *fp // output symbol name to stream if found
325 );
326
327
328 // add a new symbol to the symbol table
329 // return 1 if added, 0 otherwise
330 int add
331 (
332 char * mname, // module name
333 char * name, // symbol name
334 uint64_t vaddr, // starting address
335 uint64_t size=0, // range covered
336 uint32_t context=Symbol::NUCLEUS // symbol context
337 );
338
339 // print all symbols
340 // from low to upper addresses
341 void print ( char *filename, uint32_t context );
342
343 // print all symbols without any order -
344 // hash table order
345 int hprint ( char *filename, uint32_t context );
346
347};
348
349
350
351
352
353
354
355
356
357
358#endif // _SYMBOLS_H