OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can be | |
4 * found in the LICENSE file. | |
5 */ | |
6 | |
7 /* | |
8 * ncdecode_st.c - Implements nested symbol tables. | |
9 * | |
10 * Note: We use linear lists | |
11 */ | |
12 | |
13 #ifndef NACL_TRUSTED_BUT_NOT_TCB | |
14 #error("This file is not meant for use in the TCB") | |
15 #endif | |
16 | |
17 #include <assert.h> | |
18 #include <stdlib.h> | |
19 #include <string.h> | |
20 | |
21 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_st.
h" | |
22 | |
23 #include "native_client/src/include/nacl_macros.h" | |
24 #include "native_client/src/include/portability.h" | |
25 #include "native_client/src/shared/platform/nacl_log.h" | |
26 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tab
legen.h" | |
27 | |
28 /* To turn on debugging of instruction decoding, change value of | |
29 * DEBUGGING to 1. | |
30 */ | |
31 #define DEBUGGING 0 | |
32 | |
33 #include "native_client/src/shared/utils/debugging.h" | |
34 | |
35 const char* NaClStValueKindName(NaClStValueKind kind) { | |
36 /* | |
37 * See https://code.google.com/p/nativeclient/issues/detail?id=3750 | |
38 */ | |
39 switch (kind) { | |
40 case nacl_byte: | |
41 return "nacl_byte"; | |
42 case nacl_text: | |
43 return "nacl_text"; | |
44 case nacl_int: | |
45 return "nacl_int"; | |
46 case nacl_defop: | |
47 return "nacl_defop"; | |
48 } | |
49 return "???"; /* better not be DCE'd */ | |
50 } | |
51 | |
52 void NaClStValueAssign( | |
53 NaClStValue* lhs, | |
54 NaClStValue* rhs) { | |
55 memcpy(lhs, rhs, sizeof(NaClStValue)); | |
56 } | |
57 | |
58 void NaClStValuePrint(struct Gio* g, NaClStValue* value) { | |
59 gprintf(g, "<%s : ", NaClStValueKindName(value->kind)); | |
60 switch (value->kind) { | |
61 case nacl_byte: | |
62 gprintf(g, "0x%02"NACL_PRIx8, value->value.byte_value); | |
63 break; | |
64 case nacl_int: | |
65 gprintf(g, "%d", value->value.int_value); | |
66 break; | |
67 case nacl_text: | |
68 gprintf(g, "'%s'", value->value.text_value); | |
69 break; | |
70 case nacl_defop: | |
71 gprintf(g, "<defop>"); | |
72 break; | |
73 default: | |
74 gprintf(g, "???"); | |
75 break; | |
76 } | |
77 gprintf(g, ">"); | |
78 } | |
79 | |
80 /* Element in the symbol table. */ | |
81 typedef struct NaClSymbolTablePair { | |
82 const char* name; /* The name of the symbol. */ | |
83 NaClStValue value; /* The value associated with the symbol. */ | |
84 } NaClSymbolTablePair; | |
85 | |
86 /* Simple implementation of a symbol table using an array of size capacity. */ | |
87 typedef struct NaClSymbolTable { | |
88 /* The calling context defines the outer scope for processing | |
89 * nested scopes. | |
90 */ | |
91 struct NaClSymbolTable* calling_context; | |
92 /* The current size of the symbol table. */ | |
93 size_t size; | |
94 /* The maximum size of the symbol table. */ | |
95 size_t capacity; | |
96 /* The array holding the contents of the symbol table. */ | |
97 NaClSymbolTablePair* values; | |
98 } NaClSymbolTable; | |
99 | |
100 NaClSymbolTable* NaClSymbolTableCreate( | |
101 size_t capacity, | |
102 NaClSymbolTable* calling_context) { | |
103 NaClSymbolTable* st = (NaClSymbolTable*) malloc(sizeof(NaClSymbolTable)); | |
104 assert(NULL != st); | |
105 st->calling_context = calling_context; | |
106 st->size = 0; | |
107 st->capacity = capacity; | |
108 st->values = (NaClSymbolTablePair*) | |
109 calloc(capacity, sizeof(NaClSymbolTablePair)); | |
110 assert(NULL != st->values); | |
111 DEBUG(NaClLog(LOG_INFO, | |
112 "NaClSymbolTableCreate(%"NACL_PRIdS") = %p\n", | |
113 capacity, (void*) st)); | |
114 return st; | |
115 } | |
116 | |
117 void NaClSymbolTableDestroy(NaClSymbolTable* st) { | |
118 DEBUG(NaClLog(LOG_INFO, "NaClSymbolTableDestroy(%p)\n", (void*) st)); | |
119 free(st); | |
120 } | |
121 | |
122 void NaClSymbolTablePut( | |
123 const char* name, | |
124 struct NaClStValue* value, | |
125 NaClSymbolTable* st) { | |
126 size_t i; | |
127 DEBUG(NaClLog(LOG_INFO, | |
128 "NaClSymbolTablePut('%s', ", name); | |
129 NaClStValuePrint(NaClLogGetGio(), value); | |
130 gprintf(NaClLogGetGio(), ", %p)\n", (void*) st)); | |
131 /* First see if already in the symbol table. */ | |
132 for (i = 0; i < st->size; ++i) { | |
133 if (0 == strcmp(name, st->values[i].name)) { | |
134 NaClStValueAssign(&(st->values[i].value), value); | |
135 return; | |
136 } | |
137 } | |
138 /* If reached, not in symbol table, add. */ | |
139 assert(st->size < st->capacity); | |
140 st->values[st->size].name = strdup(name); | |
141 assert(NULL != st->values[st->size].name); | |
142 NaClStValueAssign(&(st->values[st->size++].value), value); | |
143 } | |
144 | |
145 void NaClSymbolTablePutByte(const char* name, | |
146 uint8_t byte, | |
147 struct NaClSymbolTable* st) { | |
148 NaClStValue value; | |
149 value.kind = nacl_byte; | |
150 value.value.byte_value = byte; | |
151 NaClSymbolTablePut(name, &value, st); | |
152 } | |
153 | |
154 void NaClSymbolTablePutText(const char* name, | |
155 const char* text, | |
156 struct NaClSymbolTable* st) { | |
157 NaClStValue value; | |
158 value.kind = nacl_text; | |
159 value.value.text_value = text; | |
160 NaClSymbolTablePut(name, &value, st); | |
161 } | |
162 | |
163 void NaClSymbolTablePutInt(const char* name, | |
164 int ival, | |
165 struct NaClSymbolTable* st) { | |
166 NaClStValue value; | |
167 value.kind = nacl_int; | |
168 value.value.int_value = ival; | |
169 NaClSymbolTablePut(name, &value, st); | |
170 } | |
171 | |
172 struct NaClStValue* NaClSymbolTableGet( | |
173 const char* name, | |
174 struct NaClSymbolTable* st) { | |
175 size_t i; | |
176 NaClStValue* result; | |
177 DEBUG(NaClLog(LOG_INFO, | |
178 "-> NaClSymbolTableGet('%s', %p):\n", name, (void*) st)); | |
179 while (NULL != st) { | |
180 /* First see if already in the symbol table. */ | |
181 for (i = 0; i < st->size; ++i) { | |
182 if (0 == strcmp(name, st->values[i].name)) { | |
183 result = &(st->values[i].value); | |
184 DEBUG(NaClLog(LOG_INFO, "<- NaClSymbolTableGet = "); | |
185 NaClStValuePrint(NaClLogGetGio(), result); | |
186 gprintf(NaClLogGetGio(), ")\n")); | |
187 return result; | |
188 } | |
189 } | |
190 /* If reached, not in this symbol table. Try calling context. */ | |
191 st = st->calling_context; | |
192 } | |
193 /* If reached, not defined in any calling context. */ | |
194 DEBUG(NaClLog(LOG_INFO, "<- NaClSymbolTableGet = NULL\n")); | |
195 return NULL; | |
196 } | |
OLD | NEW |