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 : * Defines an instruction (decoder) iterator that processes code segments.
9 : */
10 :
11 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
12 :
13 : #include <stdio.h>
14 : #include <stdlib.h>
15 :
16 : #include "native_client/src/shared/platform/nacl_log.h"
17 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h"
18 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h"
19 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
20 : #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
21 :
22 : /* To turn on debugging of instruction decoding, change value of
23 : * DEBUGGING to 1.
24 : */
25 : #define DEBUGGING 0
26 :
27 : #include "native_client/src/shared/utils/debugging.h"
28 :
29 : #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.c"
30 :
31 0 : static void NaClInstIterLogError(const char* error_message) {
32 0 : NaClLog(LOG_ERROR, "*ERROR* %s\n", error_message);
33 0 : }
34 :
35 0 : void NaClInstIterFatal(const char* error_message) {
36 0 : NaClInstIterLogError(error_message);
37 0 : exit(1);
38 : }
39 :
40 : /* Default handler for errors found while parsing the memory segment.*/
41 : static void NaClInstIterReportRemainingMemoryError(
42 : NCRemainingMemoryError error,
43 0 : struct NCRemainingMemory* memory) {
44 0 : NaClInstIterLogError(NCRemainingMemoryErrorMessage(error));
45 0 : }
46 :
47 : NaClInstIter* NaClInstIterCreateWithLookback(
48 : const struct NaClDecodeTables* decoder_tables,
49 : NaClSegment* segment,
50 2 : size_t lookback_size) {
51 : NaClInstIter* iter;
52 : /* Guarantee we don't wrap around while computing buffer index updates. */
53 2 : assert(((lookback_size + 1) * 2 + 1) > lookback_size);
54 2 : iter = (NaClInstIter*) malloc(sizeof(NaClInstIter));
55 2 : if (NULL != iter) {
56 2 : iter->segment = segment;
57 2 : NCRemainingMemoryInit(segment->mbase, segment->size, &iter->memory);
58 2 : iter->memory.error_fn = NaClInstIterReportRemainingMemoryError;
59 2 : iter->index = 0;
60 2 : iter->inst_count = 0;
61 2 : iter->buffer_size = lookback_size + 1;
62 2 : iter->buffer_index = 0;
63 : iter->buffer = (NaClInstState*)
64 2 : calloc(iter->buffer_size, sizeof iter->buffer[0]);
65 2 : if (NULL == iter->buffer) {
66 0 : free(iter);
67 0 : iter = NULL;
68 0 : } else {
69 : size_t i;
70 2 : for (i = 0; i < iter->buffer_size; ++i) {
71 2 : iter->buffer[i].inst = NULL;
72 2 : NCInstBytesInitMemory(&iter->buffer[i].bytes, &iter->memory);
73 2 : }
74 : }
75 : }
76 2 : iter->decoder_tables = (struct NaClDecodeTables*) decoder_tables;
77 2 : return iter;
78 2 : }
79 :
80 : NaClInstIter* NaClInstIterCreate(
81 : const struct NaClDecodeTables* decoder_tables,
82 2 : NaClSegment* segment) {
83 2 : return NaClInstIterCreateWithLookback(decoder_tables, segment, 0);
84 2 : }
85 :
86 2 : void NaClInstIterDestroy(NaClInstIter* iter) {
87 2 : if (NULL != iter) {
88 2 : free(iter->buffer);
89 2 : free(iter);
90 : }
91 2 : }
92 :
93 1 : NaClInstState* NaClInstIterGetUndecodedState(NaClInstIter* iter) {
94 1 : return NaClInstIterGetUndecodedStateInline(iter);
95 1 : }
96 :
97 1 : NaClInstState* NaClInstIterGetState(NaClInstIter* iter) {
98 1 : return NaClInstIterGetStateInline(iter);
99 1 : }
100 :
101 0 : Bool NaClInstIterHasLookbackState(NaClInstIter* iter, size_t distance) {
102 0 : return NaClInstIterHasLookbackStateInline(iter, distance);
103 0 : }
104 :
105 : NaClInstState* NaClInstIterGetLookbackState(NaClInstIter* iter,
106 0 : size_t distance) {
107 0 : return NaClInstIterGetLookbackStateInline(iter, distance);
108 0 : }
109 :
110 1 : Bool NaClInstIterHasNext(NaClInstIter* iter) {
111 1 : return NaClInstIterHasNextInline(iter);
112 1 : }
113 :
114 1 : void NaClInstIterAdvance(NaClInstIter* iter) {
115 1 : NaClInstIterAdvanceInline(iter);
116 1 : }
117 :
118 0 : uint8_t* NaClInstIterGetInstMemory(NaClInstIter* iter) {
119 0 : return NaClInstIterGetInstMemoryInline(iter);
120 0 : }
|