Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / support / aschk / ashash.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: ashash.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
47 */
48
49#pragma ident "@(#)ashash.c 1.2 07/06/07 SMI"
50
51#include <stdio.h>
52#include <stdlib.h>
53#include <stdarg.h>
54#include <unistd.h>
55#include <fcntl.h>
56#include <errno.h>
57#include <string.h>
58
59#include "basics.h"
60#include "internal.h"
61#include "parser.h"
62
63
64static symbol_t *sym_listp, *sym_list_endp;
65
66typedef struct {
67 symbol_t *firstp;
68 int len;
69} hash_bucket_t;
70
71#define INVALID_HASH_KEY ((uint64_t)-1)
72
73#define HASH_SIZE_BITS 10
74#define HASH_SIZE (1<<HASH_SIZE_BITS)
75#define HASH_SIZE_MASK (HASH_SIZE -1)
76static hash_bucket_t *hashp;
77
78static symbol_t *hash_find_key(int idx, uint64_t key, char *namep);
79static void hash_key(char *nampep, uint64_t *keyp, int *idxp);
80
81
82
83void
84init_symbols(void)
85{
86 sym_listp = NULL;
87 sym_list_endp = NULL;
88
89 hashp = calloc(HASH_SIZE, sizeof (hash_bucket_t));
90 if (hashp == NULL) {
91 fprintf(stderr, "Failed allocating hash space : %s\n",
92 strerror(errno));
93 exit(1);
94 }
95}
96
97
98symbol_t *
99new_sym(sym_flags_t flags, char *namep, int offset, int size)
100{
101 symbol_t *symp;
102 char *namecopyp;
103
104 symp = malloc(sizeof (symbol_t));
105 if (symp == NULL) {
106 fprintf(stderr, "Failed allocating symbol space : %s\n",
107 strerror(errno));
108 exit(1);
109 }
110 namecopyp = strdup(namep);
111 if (namecopyp == NULL) {
112 fprintf(stderr, "Failed allocating symbol space : %s\n",
113 strerror(errno));
114 exit(1);
115 }
116
117 symp->flags = flags;
118 symp->namep = namecopyp;
119 symp->size = size;
120 symp->offset = offset;
121
122 symp->name_key = INVALID_HASH_KEY;
123 symp->hash_nextp = NULL;
124 symp->nextp = sym_list_endp;
125 if (sym_list_endp == NULL)
126 sym_listp = symp;
127 sym_list_endp = symp;
128
129 return (symp);
130}
131
132
133/*
134 * Returns false if failed to insert because
135 * of existing duplicate
136 */
137bool_t
138sym_hash_insert(symbol_t *symp)
139{
140 uint64_t key;
141 int idx;
142 symbol_t *otherp;
143
144 hash_key(symp->namep, &key, &idx);
145
146 otherp = hash_find_key(idx, key, symp->namep);
147 if (otherp != NULL)
148 return (false);
149
150 /*
151 * Insert new entry
152 */
153 symp->name_key = key;
154 symp->hash_nextp = hashp[idx].firstp;
155 hashp[idx].firstp = symp;
156 hashp[idx].len ++;
157
158 return (true);
159}
160
161
162symbol_t *
163hash_find(char *namep)
164{
165 uint64_t key;
166 int idx;
167
168 hash_key(namep, &key, &idx);
169
170 return (hash_find_key(idx, key, namep));
171}
172
173
174static symbol_t *
175hash_find_key(int idx, uint64_t key, char *namep)
176{
177 symbol_t *p;
178
179 for (p = hashp[idx].firstp; p != NULL; p = p->hash_nextp) {
180 if (p->name_key == key && strcmp(p->namep, namep) == 0)
181 return (p);
182 }
183 return (NULL);
184}
185
186
187/*
188 * can use any old hash ... this is not a particualrly good one,
189 * but OK for now.
190 */
191
192#define KEY_SHIFT 5
193
194static void
195hash_key(char *namep, uint64_t *keyp, int *idxp)
196{
197 char *sp;
198 uint64_t key;
199 uint64_t ch;
200
201 key = 0;
202 for (sp = namep; (ch = *sp) != '\0'; sp++) {
203 key = (key >> (64 - KEY_SHIFT)) ^ (key << KEY_SHIFT) ^ ch;
204 }
205
206 *keyp = key;
207 *idxp = key & HASH_SIZE_MASK;
208}