00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EIP_LOCATION
00019 #define EIP_LOCATION cur_state.ip
00020 #endif
00021
00023 const RegisterDescriptor& findRegister(const std::string ®name, size_t nbits=0) {
00024 const RegisterDescriptor *reg = get_register_dictionary()->lookup(regname);
00025 if (!reg) {
00026 std::ostringstream ss;
00027 ss <<"Invalid register: \"" <<regname <<"\"";
00028 throw Exception(ss.str());
00029 }
00030 if (nbits>0 && reg->get_nbits()!=nbits) {
00031 std::ostringstream ss;
00032 ss <<"Invalid " <<nbits <<"-bit register: \"" <<regname <<"\" is "
00033 <<reg->get_nbits() <<" " <<(1==reg->get_nbits()?"byte":"bytes");
00034 throw Exception(ss.str());
00035 }
00036 return *reg;
00037 }
00038
00040 template<size_t Len>
00041 ValueType<Len> readRegister(const char *regname) {
00042 return readRegister<Len>(findRegister(regname, Len));
00043 }
00044
00046 template<size_t Len>
00047 void writeRegister(const char *regname, const ValueType<Len> &value) {
00048 writeRegister<Len>(findRegister(regname, Len), value);
00049 }
00050
00052 template<size_t Len>
00053 ValueType<Len> readRegister(const RegisterDescriptor ®) {
00054 switch (Len) {
00055 case 1:
00056
00057 if (reg.get_major()!=x86_regclass_flags)
00058 throw Exception("bit access only valid for FLAGS/EFLAGS register");
00059 if (reg.get_minor()!=0 || reg.get_offset()>=cur_state.n_flags)
00060 throw Exception("register not implemented in semantic policy");
00061 if (reg.get_nbits()!=1)
00062 throw Exception("semantic policy supports only single-bit flags");
00063 return unsignedExtend<1, Len>(cur_state.flag[reg.get_offset()]);
00064
00065 case 8:
00066
00067
00068 if (reg.get_major()!=x86_regclass_gpr)
00069 throw Exception("byte access only valid for general purpose registers");
00070 if (reg.get_minor()>=cur_state.n_gprs)
00071 throw Exception("register not implemented in semantic policy");
00072 assert(reg.get_nbits()==8);
00073 switch (reg.get_offset()) {
00074 case 0:
00075 return extract<0, Len>(cur_state.gpr[reg.get_minor()]);
00076 case 8:
00077 return extract<8, 8+Len>(cur_state.gpr[reg.get_minor()]);
00078 default:
00079 throw Exception("invalid one-byte access offset");
00080 }
00081
00082 case 16:
00083 if (reg.get_nbits()!=16)
00084 throw Exception("invalid 2-byte register");
00085 if (reg.get_offset()!=0)
00086 throw Exception("policy does not support non-zero offsets for word granularity register access");
00087 switch (reg.get_major()) {
00088 case x86_regclass_segment:
00089 if (reg.get_minor()>=cur_state.n_segregs)
00090 throw Exception("register not implemented in semantic policy");
00091 return unsignedExtend<16, Len>(cur_state.segreg[reg.get_minor()]);
00092 case x86_regclass_gpr:
00093 if (reg.get_minor()>=cur_state.n_gprs)
00094 throw Exception("register not implemented in semantic policy");
00095 return extract<0, Len>(cur_state.gpr[reg.get_minor()]);
00096 case x86_regclass_flags:
00097 if (reg.get_minor()!=0 || cur_state.n_flags<16)
00098 throw Exception("register not implemented in semantic policy");
00099 return unsignedExtend<16, Len>(concat(cur_state.flag[0],
00100 concat(cur_state.flag[1],
00101 concat(cur_state.flag[2],
00102 concat(cur_state.flag[3],
00103 concat(cur_state.flag[4],
00104 concat(cur_state.flag[5],
00105 concat(cur_state.flag[6],
00106 concat(cur_state.flag[7],
00107 concat(cur_state.flag[8],
00108 concat(cur_state.flag[9],
00109 concat(cur_state.flag[10],
00110 concat(cur_state.flag[11],
00111 concat(cur_state.flag[12],
00112 concat(cur_state.flag[13],
00113 concat(cur_state.flag[14],
00114 cur_state.flag[15]))))))))))))))));
00115 default:
00116 throw Exception("word access not valid for this register type");
00117 }
00118
00119 case 32:
00120 if (reg.get_offset()!=0)
00121 throw Exception("policy does not support non-zero offsets for double word granularity register access");
00122 switch (reg.get_major()) {
00123 case x86_regclass_gpr:
00124 if (reg.get_minor()>=cur_state.n_gprs)
00125 throw Exception("register not implemented in semantic policy");
00126 return unsignedExtend<32, Len>(cur_state.gpr[reg.get_minor()]);
00127 case x86_regclass_ip:
00128 if (reg.get_minor()!=0)
00129 throw Exception("register not implemented in semantic policy");
00130 return unsignedExtend<32, Len>(EIP_LOCATION);
00131 case x86_regclass_segment:
00132 if (reg.get_minor()>=cur_state.n_segregs || reg.get_nbits()!=16)
00133 throw Exception("register not implemented in semantic policy");
00134 return unsignedExtend<16, Len>(cur_state.segreg[reg.get_minor()]);
00135 case x86_regclass_flags: {
00136 if (reg.get_minor()!=0 || cur_state.n_flags<32)
00137 throw Exception("register not implemented in semantic policy");
00138 if (reg.get_nbits()!=32)
00139 throw Exception("register is not 32 bits");
00140 return unsignedExtend<32, Len>(concat(readRegister<16>("flags"),
00141 concat(cur_state.flag[16],
00142 concat(cur_state.flag[17],
00143 concat(cur_state.flag[18],
00144 concat(cur_state.flag[19],
00145 concat(cur_state.flag[20],
00146 concat(cur_state.flag[21],
00147 concat(cur_state.flag[22],
00148 concat(cur_state.flag[23],
00149 concat(cur_state.flag[24],
00150 concat(cur_state.flag[25],
00151 concat(cur_state.flag[26],
00152 concat(cur_state.flag[27],
00153 concat(cur_state.flag[28],
00154 concat(cur_state.flag[29],
00155 concat(cur_state.flag[30],
00156 cur_state.flag[31])))))))))))))))));
00157 }
00158 default:
00159 throw Exception("double word access not valid for this register type");
00160 }
00161
00162 default:
00163 throw Exception("invalid register access width");
00164 }
00165 }
00166
00168 template<size_t Len>
00169 void writeRegister(const RegisterDescriptor ®, const ValueType<Len> &value) {
00170 switch (Len) {
00171 case 1:
00172
00173 if (reg.get_major()!=x86_regclass_flags)
00174 throw Exception("bit access only valid for FLAGS/EFLAGS register");
00175 if (reg.get_minor()!=0 || reg.get_offset()>=cur_state.n_flags)
00176 throw Exception("register not implemented in semantic policy");
00177 if (reg.get_nbits()!=1)
00178 throw Exception("semantic policy supports only single-bit flags");
00179 cur_state.flag[reg.get_offset()] = unsignedExtend<Len, 1>(value);
00180 break;
00181
00182 case 8:
00183
00184 if (reg.get_major()!=x86_regclass_gpr)
00185 throw Exception("byte access only valid for general purpose registers.");
00186 if (reg.get_minor()>=cur_state.n_gprs)
00187 throw Exception("register not implemented in semantic policy");
00188 assert(reg.get_nbits()==8);
00189 switch (reg.get_offset()) {
00190 case 0:
00191 cur_state.gpr[reg.get_minor()] =
00192 concat(signExtend<Len, 8>(value), extract<8, 32>(cur_state.gpr[reg.get_minor()]));
00193 break;
00194 case 8:
00195 cur_state.gpr[reg.get_minor()] =
00196 concat(extract<0, 8>(cur_state.gpr[reg.get_minor()]),
00197 concat(unsignedExtend<Len, 8>(value),
00198 extract<16, 32>(cur_state.gpr[reg.get_minor()])));
00199 break;
00200 default:
00201 throw Exception("invalid byte access offset");
00202 }
00203 break;
00204
00205 case 16:
00206 if (reg.get_nbits()!=16)
00207 throw Exception("invalid 2-byte register");
00208 if (reg.get_offset()!=0)
00209 throw Exception("policy does not support non-zero offsets for word granularity register access");
00210 switch (reg.get_major()) {
00211 case x86_regclass_segment:
00212 if (reg.get_minor()>=cur_state.n_segregs)
00213 throw Exception("register not implemented in semantic policy");
00214 cur_state.segreg[reg.get_minor()] = unsignedExtend<Len, 16>(value);
00215 break;
00216 case x86_regclass_gpr:
00217 if (reg.get_minor()>=cur_state.n_gprs)
00218 throw Exception("register not implemented in semantic policy");
00219 cur_state.gpr[reg.get_minor()] =
00220 concat(unsignedExtend<Len, 16>(value),
00221 extract<16, 32>(cur_state.gpr[reg.get_minor()]));
00222 break;
00223 case x86_regclass_flags:
00224 if (reg.get_minor()!=0 || cur_state.n_flags<16)
00225 throw Exception("register not implemented in semantic policy");
00226 cur_state.flag[0] = extract<0, 1 >(value);
00227 cur_state.flag[1] = extract<1, 2 >(value);
00228 cur_state.flag[2] = extract<2, 3 >(value);
00229 cur_state.flag[3] = extract<3, 4 >(value);
00230 cur_state.flag[4] = extract<4, 5 >(value);
00231 cur_state.flag[5] = extract<5, 6 >(value);
00232 cur_state.flag[6] = extract<6, 7 >(value);
00233 cur_state.flag[7] = extract<7, 8 >(value);
00234 cur_state.flag[8] = extract<8, 9 >(value);
00235 cur_state.flag[9] = extract<9, 10>(value);
00236 cur_state.flag[10] = extract<10, 11>(value);
00237 cur_state.flag[11] = extract<11, 12>(value);
00238 cur_state.flag[12] = extract<12, 13>(value);
00239 cur_state.flag[13] = extract<13, 14>(value);
00240 cur_state.flag[14] = extract<14, 15>(value);
00241 cur_state.flag[15] = extract<15, 16>(value);
00242 break;
00243 default:
00244 throw Exception("word access not valid for this register type");
00245 }
00246 break;
00247
00248 case 32:
00249 if (reg.get_offset()!=0)
00250 throw Exception("policy does not support non-zero offsets for double word granularity register access");
00251 switch (reg.get_major()) {
00252 case x86_regclass_gpr:
00253 if (reg.get_minor()>=cur_state.n_gprs)
00254 throw Exception("register not implemented in semantic policy");
00255 cur_state.gpr[reg.get_minor()] = signExtend<Len, 32>(value);
00256 break;
00257 case x86_regclass_ip:
00258 if (reg.get_minor()!=0)
00259 throw Exception("register not implemented in semantic policy");
00260 EIP_LOCATION = unsignedExtend<Len, 32>(value);
00261 break;
00262 case x86_regclass_flags:
00263 if (reg.get_minor()!=0 || cur_state.n_flags<32)
00264 throw Exception("register not implemented in semantic policy");
00265 if (reg.get_nbits()!=32)
00266 throw Exception("register is not 32 bits");
00267 writeRegister<16>("flags", unsignedExtend<Len, 16>(value));
00268 cur_state.flag[16] = extract<16, 17>(value);
00269 cur_state.flag[17] = extract<17, 18>(value);
00270 cur_state.flag[18] = extract<18, 19>(value);
00271 cur_state.flag[19] = extract<19, 20>(value);
00272 cur_state.flag[20] = extract<20, 21>(value);
00273 cur_state.flag[21] = extract<21, 22>(value);
00274 cur_state.flag[22] = extract<22, 23>(value);
00275 cur_state.flag[23] = extract<23, 24>(value);
00276 cur_state.flag[24] = extract<24, 25>(value);
00277 cur_state.flag[25] = extract<25, 26>(value);
00278 cur_state.flag[26] = extract<26, 27>(value);
00279 cur_state.flag[27] = extract<27, 28>(value);
00280 cur_state.flag[28] = extract<28, 29>(value);
00281 cur_state.flag[29] = extract<29, 30>(value);
00282 cur_state.flag[30] = extract<30, 31>(value);
00283 cur_state.flag[31] = extract<31, 32>(value);
00284 break;
00285 default:
00286 throw Exception("double word access not valid for this register type");
00287 }
00288 break;
00289
00290 default:
00291 throw Exception("invalid register access width");
00292 }
00293 }
00294
00295 #undef EIP_LOCATION