Index: src/trusted/validator_ragel/test_dfa.c |
=================================================================== |
--- src/trusted/validator_ragel/test_dfa.c (revision 7794) |
+++ src/trusted/validator_ragel/test_dfa.c (working copy) |
@@ -1,215 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-/* Generate all possible instructions that a decoder can decode. |
- * Group the instruction stream into files for processing them in parallel. |
- */ |
-#include <assert.h> |
-#include <stdio.h> |
-#include <stdlib.h> |
-#include <sys/types.h> |
-#include <sys/stat.h> |
-#include <unistd.h> |
- |
-#include "test_dfa.h" |
- |
- |
-const int kInstsPerFile = 1000000; |
-const uint16_t kInvalidState = UINT16_MAX; |
- |
-/* The list of error codes. */ |
-const int kErrArgc = 1; |
-const int kErrCannotStat = 2; |
-const int kErrNotADir = 3; |
-const int kErrChortBuf = 4; |
-const int kErrOpenOutput = 5; |
- |
-static void InitStates() { |
- int i, t; |
- |
- for (i = 0; i < NumStates(); i++) { |
- for (t = 0; t < 256; t++) { |
- states[i].transitions[t] = kInvalidState; |
- } |
- } |
-} |
- |
-/* Adds an edge with a range of bytes. For use in definitions generated by the |
- * DFA parser. */ |
-void AddRange(int state_idx, |
- uint8_t byte_begin, |
- uint8_t byte_end, |
- uint16_t target) { |
- int i; |
- |
- assert(0 <= state_idx && state_idx < NumStates()); |
- for (i = byte_begin; i <= byte_end; i++) { |
- states[state_idx].transitions[i] = target; |
- } |
-} |
- |
-/* The global instruction bytes that are updated as we traverse the graph. */ |
-enum {kMaxInstLength = 15}; |
-uint8_t inst_bytes[kMaxInstLength]; |
-int inst_len = 0; |
- |
-static bool AllTransitionsEqual(struct state st) { |
- int i; |
- |
- for (i = 0; i < 256; i++) { |
- if (st.transitions[i] != st.transitions[0]) { |
- return false; |
- } |
- } |
- return true; |
-} |
- |
-enum {kMaxFileNameLength = 500}; |
- |
-struct output_state { |
- uint64_t insts_done; |
- uint32_t file_count; |
- FILE* asmfile; |
- char fname[kMaxFileNameLength]; |
- const char* output_dir; |
-}; |
- |
-static void OutputSetFilename(struct output_state *out) { |
- int amount; |
- amount = snprintf(out->fname, |
- kMaxFileNameLength, |
- "%s/_test_dfa_insts_%05d.s", |
- out->output_dir, |
- out->file_count); |
- if (kMaxFileNameLength <= amount || amount < 0) { |
- fprintf(stderr, "error: buffer too short to contain a file name\n"); |
- exit(kErrChortBuf); |
- } |
-} |
- |
-static void OutputOpenCurrent(struct output_state *out) { |
- out->asmfile = fopen(out->fname, "w"); |
- if (out->asmfile == NULL) { |
- perror("fopen"); |
- exit(kErrOpenOutput); |
- } |
- fprintf(out->asmfile, " .text\n"); |
-} |
- |
-static void OutputInit(struct output_state *out, const char* output_dir) { |
- out->output_dir = output_dir; |
- out->insts_done = 0; |
- out->file_count = 0; |
- OutputSetFilename(out); |
- OutputOpenCurrent(out); |
-} |
- |
-void OutputCloseCurrent(struct output_state *out) { |
- fclose(out->asmfile); |
- printf("%s\n", out->fname); |
- fflush(stdout); |
-} |
- |
-/* Writes one instruction to the current output file. Start the new file if the |
- * current one exceeds the maximum number of instructions. */ |
-static void OutputWriteInstruction(struct output_state *out) { |
- int i; |
- |
- assert(inst_len); |
- if ((out->insts_done != 0) && |
- (out->insts_done % kInstsPerFile == 0)) { |
- OutputCloseCurrent(out); |
- out->file_count++; |
- OutputSetFilename(out); |
- OutputOpenCurrent(out); |
- } |
- fprintf(out->asmfile, " .byte 0x%.2x", inst_bytes[0]); |
- for (i = 1; i < inst_len; i++) { |
- fprintf(out->asmfile, ",0x%.2x", inst_bytes[i]); |
- } |
- fprintf(out->asmfile, "\n"); |
- out->insts_done++; |
-} |
- |
-static struct output_state g_output; |
- |
-/* The main loop to traverse all possible paths from the begin state, record |
- * transition bytes and output the whole instruction as soon as we reach a final |
- * state. If we are in a multibyte field that the decoder should not care |
- * about, we generate 0x01, 0x23, 0x45, ... as the field bytes. */ |
-static void TraverseStates(uint16_t entry, bool in_anyfield) { |
- int i; |
- uint8_t prev_byte; |
- struct state st = states[entry]; |
- uint16_t st2; |
- |
- if (st.is_final) { |
- OutputWriteInstruction(&g_output); |
- /* Some final states have outgoing transitions, so we have to continue |
- iterating through them. */ |
- } |
- if (!in_anyfield) { |
- if (st.anyfield_begin) { |
- /* We are in the state that starts anyfield. If it is a one-byte field, |
- then recursive call is not anyfield. */ |
- inst_bytes[inst_len++] = 0x01; |
- if (st.anyfield_end) { |
- TraverseStates(st.transitions[0], false); |
- } else { |
- TraverseStates(st.transitions[0], true); |
- } |
- inst_len--; |
- } else { |
- /* Traverse all available transitions in the node. */ |
- for (i = 0; i < 256; i++) { |
- st2 = st.transitions[i]; |
- if (st2 != kInvalidState) { |
- assert(st2 < NumStates()); |
- inst_bytes[inst_len++] = i; |
- TraverseStates(st2, false); |
- inst_len--; |
- } |
- } |
- } |
- } else { |
- /* Continue anyfield traversal. */ |
- assert(AllTransitionsEqual(st)); |
- prev_byte = inst_bytes[inst_len - 1]; |
- inst_bytes[inst_len++] = prev_byte + 0x22; |
- if (st.anyfield_end) { |
- TraverseStates(st.transitions[0], false); |
- } else { |
- TraverseStates(st.transitions[0], true); |
- } |
- inst_len--; |
- } |
-} |
- |
-int main(int argc, char* argv[]) { |
- struct stat st; |
- char* output_dir; |
- |
- if (argc != 2) { |
- fprintf(stderr, "usage: %s outdir\n", argv[0]); |
- return kErrArgc; |
- } |
- output_dir = argv[1]; |
- if (stat(output_dir, &st) == -1) { |
- fprintf(stderr, "error: could not stat %s\n", output_dir); |
- return kErrCannotStat; |
- } |
- if (!S_ISDIR(st.st_mode)) { |
- fprintf(stderr, "error: not a directory: %s\n", output_dir); |
- return kErrNotADir; |
- } |
- |
- InitStates(); |
- InitTransitions(); |
- OutputInit(&g_output, output_dir); |
- TraverseStates(start_state, false); |
- OutputCloseCurrent(&g_output); |
- return 0; |
-} |