| 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 |