1 : /*
2 : * Copyright (c) 2012 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 : #include "native_client/src/trusted/validator_arm/inst_classes_inline.h"
8 :
9 : // Implementations of instruction classes, for those not completely defined in
10 : // in the header.
11 :
12 : namespace nacl_arm_dec {
13 :
14 : // ClassDecoder
15 0 : RegisterList ClassDecoder::defs(Instruction i) const {
16 : UNREFERENCED_PARAMETER(i);
17 0 : return RegisterList::Everything();
18 0 : }
19 :
20 0 : RegisterList ClassDecoder::uses(Instruction i) const {
21 : UNREFERENCED_PARAMETER(i);
22 0 : return RegisterList();
23 0 : }
24 :
25 : bool ClassDecoder::base_address_register_writeback_small_immediate(
26 0 : Instruction i) const {
27 : UNREFERENCED_PARAMETER(i);
28 0 : return false;
29 0 : }
30 :
31 0 : Register ClassDecoder::base_address_register(Instruction i) const {
32 : UNREFERENCED_PARAMETER(i);
33 0 : return Register::None();
34 0 : }
35 :
36 0 : bool ClassDecoder::is_literal_load(Instruction i) const {
37 : UNREFERENCED_PARAMETER(i);
38 0 : return false;
39 0 : }
40 :
41 0 : Register ClassDecoder::branch_target_register(Instruction i) const {
42 : UNREFERENCED_PARAMETER(i);
43 0 : return Register::None();
44 0 : }
45 :
46 0 : bool ClassDecoder::is_relative_branch(Instruction i) const {
47 : UNREFERENCED_PARAMETER(i);
48 0 : return false;
49 0 : }
50 :
51 0 : int32_t ClassDecoder::branch_target_offset(Instruction i) const {
52 : UNREFERENCED_PARAMETER(i);
53 0 : return 0;
54 0 : }
55 :
56 0 : bool ClassDecoder::is_literal_pool_head(Instruction i) const {
57 : UNREFERENCED_PARAMETER(i);
58 0 : return false;
59 0 : }
60 :
61 0 : bool ClassDecoder::clears_bits(Instruction i, uint32_t mask) const {
62 : UNREFERENCED_PARAMETER(i);
63 : UNREFERENCED_PARAMETER(mask);
64 0 : return false;
65 0 : }
66 :
67 : bool ClassDecoder::sets_Z_if_bits_clear(Instruction i,
68 : Register r,
69 0 : uint32_t mask) const {
70 : UNREFERENCED_PARAMETER(i);
71 : UNREFERENCED_PARAMETER(r);
72 : UNREFERENCED_PARAMETER(mask);
73 0 : return false;
74 0 : }
75 :
76 0 : bool ClassDecoder::is_load_thread_address_pointer(Instruction i) const {
77 : UNREFERENCED_PARAMETER(i);
78 0 : return false;
79 0 : }
80 :
81 : Instruction ClassDecoder::
82 0 : dynamic_code_replacement_sentinel(Instruction i) const {
83 0 : return i;
84 0 : }
85 :
86 : ViolationSet ClassDecoder::get_violations(
87 : const nacl_arm_val::DecodedInstruction& first,
88 : const nacl_arm_val::DecodedInstruction& second,
89 : const nacl_arm_val::SfiValidator& sfi,
90 : nacl_arm_val::AddressSet* branches,
91 : nacl_arm_val::AddressSet* critical,
92 0 : uint32_t* next_inst_addr) const {
93 : UNREFERENCED_PARAMETER(next_inst_addr);
94 0 : ViolationSet violations = kNoViolations;
95 :
96 : // Start by checking safety.
97 0 : if (second.safety() != nacl_arm_dec::MAY_BE_SAFE)
98 0 : violations = SafetyViolationBit(second.safety());
99 :
100 : // Skip adding get_loadstore_violations, assuming the code generator adds them
101 : // whenever field 'base' is defined for a class decoder in armv7.table.
102 :
103 : // Skip get_branch_mask_violations, assuming the code generator adds them
104 : // whenever field 'target' is defined for a class decoder in armv7.table.
105 :
106 : violations = ViolationUnion(
107 : violations,
108 0 : get_data_register_update_violations(first, second, sfi, critical));
109 :
110 : // Skip get_call_position_violations, assuming the code generator adds them
111 : // whenever fields 'target' or 'relative' is defined for a class decoder
112 : // in armv7.table.
113 :
114 : violations = ViolationUnion(
115 0 : violations, get_read_only_violations(second, sfi));
116 : violations = ViolationUnion(
117 0 : violations, get_read_thread_local_pointer_violations(second));
118 : violations = ViolationUnion(
119 0 : violations, get_pc_writes_violations(second, sfi, branches));
120 :
121 : // Skip processing constant pool heads, assuming the code generator adds them
122 : // whenever field 'is_literal_pool_head' is defined for a class decoder
123 : // in armv7.table.
124 :
125 0 : return violations;
126 0 : }
127 :
128 : void ClassDecoder::generate_diagnostics(
129 : ViolationSet violations,
130 : const nacl_arm_val::DecodedInstruction& first,
131 : const nacl_arm_val::DecodedInstruction& second,
132 : const nacl_arm_val::SfiValidator& sfi,
133 0 : nacl_arm_val::ProblemSink* out) const {
134 :
135 0 : if (ContainsSafetyViolations(violations)) {
136 : // Note: We assume that safety levels end with MAY_BE_SAFE, as stated
137 : // for enum type SafetyLevel.
138 0 : uint32_t addr = second.addr();
139 0 : for (uint32_t safety = 0; safety != MAY_BE_SAFE; ++safety) {
140 0 : Violation violation = static_cast<Violation>(safety);
141 0 : if (ContainsViolation(violations, violation)) {
142 0 : switch (static_cast<int>(violation)) {
143 : case nacl_arm_dec::UNINITIALIZED_VIOLATION:
144 : default:
145 : out->ReportProblemDiagnostic(
146 : violation, addr,
147 0 : "Unknown error occurred decoding this instruction.");
148 0 : break;
149 : case nacl_arm_dec::UNKNOWN_VIOLATION:
150 : out->ReportProblemDiagnostic(
151 : violation, addr,
152 : "The value assigned to registers by this instruction "
153 0 : "is unknown.");
154 0 : break;
155 : case nacl_arm_dec::UNDEFINED_VIOLATION:
156 : out->ReportProblemDiagnostic(
157 : violation, addr,
158 : "Instruction is undefined according to the ARMv7"
159 0 : " ISA specifications.");
160 0 : break;
161 : case nacl_arm_dec::NOT_IMPLEMENTED_VIOLATION:
162 : // This instruction is not recognized by the decoder functions.
163 : out->ReportProblemDiagnostic(
164 : violation, addr,
165 0 : "Instruction not understood by Native Client.");
166 0 : break;
167 : case nacl_arm_dec::UNPREDICTABLE_VIOLATION:
168 : out->ReportProblemDiagnostic(
169 : violation, addr,
170 0 : "Instruction has unpredictable effects at runtime.");
171 0 : break;
172 : case nacl_arm_dec::DEPRECATED_VIOLATION:
173 : out->ReportProblemDiagnostic(
174 : violation, addr,
175 0 : "Instruction is deprecated in ARMv7.");
176 0 : break;
177 : case nacl_arm_dec::FORBIDDEN_VIOLATION:
178 : out->ReportProblemDiagnostic(
179 : violation, addr,
180 0 : "Instruction not allowed by Native Client.");
181 0 : break;
182 : case nacl_arm_dec::FORBIDDEN_OPERANDS_VIOLATION:
183 : out->ReportProblemDiagnostic(
184 : violation, addr,
185 0 : "Instruction has operand(s) forbidden by Native Client.");
186 0 : break;
187 : case nacl_arm_dec::DECODER_ERROR_VIOLATION:
188 : out->ReportProblemDiagnostic(
189 : violation, addr,
190 0 : "Instruction decoded incorrectly by NativeClient.");
191 : break;
192 : };
193 : }
194 0 : }
195 : }
196 :
197 0 : generate_loadstore_diagnostics(violations, first, second, sfi, out);
198 0 : generate_branch_mask_diagnostics(violations, first, second, sfi, out);
199 : generate_data_register_update_diagnostics(violations, first, second,
200 0 : sfi, out);
201 0 : generate_call_position_diagnostics(violations, second, sfi, out);
202 0 : generate_read_only_diagnostics(violations, second, sfi, out);
203 0 : generate_read_thread_local_pointer_diagnostics(violations, second, sfi, out);
204 0 : generate_pc_writes_diagnostics(violations, second, sfi, out);
205 0 : }
206 :
207 : } // namespace nacl_arm_dec
|