OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [test/] [layers/] [EffectiveAddressLayerFactory.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
package ao486.test.layers;
28
 
29
import ao486.test.TestUnit;
30
import java.util.HashMap;
31
import java.util.LinkedList;
32
import java.util.Random;
33
 
34
public class EffectiveAddressLayerFactory {
35
 
36
    public static enum modregrm_reg_t {
37
        SET,
38
        RANDOM
39
    }
40
 
41
    private static long update_target(long target, long val) {
42
        target -= val;
43
        target &= 0xFFFFFFFFL;
44
        return target;
45
    }
46
 
47
    public static byte[] prepare(long value_from_mod_rm,
48
                                int value_from_reg, modregrm_reg_t reg_type,
49
                                int length,
50
                                boolean a32,
51
                                LinkedList<Layer> layers,
52
                                final Random random,
53
                                TestUnit test,
54
                                boolean only_mem, boolean only_reg) throws Exception
55
    {
56
        int mod     = (only_reg)? 3 : random.nextInt(only_mem? 3 : 4);
57
        int rm      = random.nextInt(8);
58
 
59
        int scale   = random.nextInt(4);
60
        int index   = random.nextInt(8);
61
        int base    = random.nextInt(8);
62
 
63
System.out.printf("mod: %x\n", mod);
64
System.out.printf("rm:  %x\n", rm);
65
 
66
    boolean from_ss =
67
            (a32 && (mod == 1 || mod == 2) && rm == 5) ||
68
            (a32 && mod != 3 && rm == 4 && base == 4)  ||
69
            (a32 && (mod == 1 || mod == 2) && rm == 4 && base == 5) ||
70
            (!a32 && mod == 0 && (rm == 2 || rm == 3)) ||
71
            (!a32 && (mod == 1 || mod == 2) && (rm == 2 || rm == 3 || rm == 6));
72
 
73
        String segment = from_ss? "ss" : "ds";
74
 
75
        int     length_allowed  = length;
76
        boolean is_sib          = false;
77
        boolean is_memory       = true;
78
 
79
        int     disp_length = 0;
80
        long    disp = 0;
81
 
82
        long seg_base = 0;
83
        long target   = 0;
84
        long target_final = 0;
85
 
86
        final HashMap<String, Long> map = new HashMap<>();
87
        while(true) {
88
 
89
            if(mod == 3) {
90
                is_memory = false;
91
 
92
                if(length == 4) {
93
                    if(rm == 0) map.put("eax", value_from_mod_rm);
94
                    if(rm == 1) map.put("ecx", value_from_mod_rm);
95
                    if(rm == 2) map.put("edx", value_from_mod_rm);
96
                    if(rm == 3) map.put("ebx", value_from_mod_rm);
97
                    if(rm == 4) map.put("esp", value_from_mod_rm);
98
                    if(rm == 5) map.put("ebp", value_from_mod_rm);
99
                    if(rm == 6) map.put("esi", value_from_mod_rm);
100
                    if(rm == 7) map.put("edi", value_from_mod_rm);
101
                }
102
                else if(length == 2) {
103
                    if(rm == 0) map.put("ax", value_from_mod_rm & 0xFFFF);
104
                    if(rm == 1) map.put("cx", value_from_mod_rm & 0xFFFF);
105
                    if(rm == 2) map.put("dx", value_from_mod_rm & 0xFFFF);
106
                    if(rm == 3) map.put("bx", value_from_mod_rm & 0xFFFF);
107
                    if(rm == 4) map.put("sp", value_from_mod_rm & 0xFFFF);
108
                    if(rm == 5) map.put("bp", value_from_mod_rm & 0xFFFF);
109
                    if(rm == 6) map.put("si", value_from_mod_rm & 0xFFFF);
110
                    if(rm == 7) map.put("di", value_from_mod_rm & 0xFFFF);
111
                }
112
                else if(length == 1) {
113
                    if(rm == 0) map.put("al", value_from_mod_rm & 0xFF);
114
                    if(rm == 1) map.put("cl", value_from_mod_rm & 0xFF);
115
                    if(rm == 2) map.put("dl", value_from_mod_rm & 0xFF);
116
                    if(rm == 3) map.put("bl", value_from_mod_rm & 0xFF);
117
                    if(rm == 4) map.put("ah", value_from_mod_rm & 0xFF);
118
                    if(rm == 5) map.put("ch", value_from_mod_rm & 0xFF);
119
                    if(rm == 6) map.put("dh", value_from_mod_rm & 0xFF);
120
                    if(rm == 7) map.put("bh", value_from_mod_rm & 0xFF);
121
                }
122
                break;
123
            }
124
System.out.println("segment: " + segment);
125
            long seg_limit = Layer.norm(test.getInput(segment + "_limit"));
126
            seg_base  = Layer.norm(test.getInput(segment + "_base"));
127
            if(seg_limit < length) length_allowed = (int)(length - seg_limit);
128
            target =
129
                    (seg_limit == 0)?       0 :
130
                    (seg_limit < length)?   random.nextInt((int)seg_limit) :
131
                                            random.nextInt((int)(seg_limit - length +1));
132
 
133
            if(!a32) {
134
                target &= 0xFFFF;
135
            }
136
            target_final = target;
137
 
138
System.out.printf("target: %x, length: %d, final loc: %08x\n", target_final, length, seg_base + target);
139
            boolean target_ok = true;
140
            for(int i=0; i<length; i++) {
141
                if(test.is_memory_not_random((int)(seg_base + target + i))) target_ok = false;
142
            }
143
            if(target_ok == false) continue;
144
 
145
            if(!a32) {
146
                if(mod == 1) {
147
                    long disp8 = random.nextInt(256);
148
                    map.put("disp8", disp8);
149
                    if((disp8 >> 7) == 1) disp8 |= 0xFF00;
150
                    target = update_target(target, disp8);
151
                }
152
                if(mod == 2) {
153
                    long disp16 = random.nextInt(65536);
154
                    map.put("disp16", disp16);
155
                    target = update_target(target, disp16);
156
                }
157
 
158
                if((mod == 0 || mod == 1 || mod == 2) && rm == 0) {
159
                    long si = Layer.norm(random.nextInt(65536));
160
                    map.put("si", si);
161
                    target = update_target(target, si);
162
                    map.put("bx", target);
163
                }
164
                if((mod == 0 || mod == 1 || mod == 2) && rm == 1) {
165
                    long di = Layer.norm(random.nextInt(65536));
166
                    map.put("di", di);
167
                    target = update_target(target, di);
168
                    map.put("bx", target);
169
                }
170
                if((mod == 0 || mod == 1 || mod == 2) && rm == 2) {
171
                    long si = Layer.norm(random.nextInt(65536));
172
                    map.put("si", si);
173
                    target = update_target(target, si);
174
                    map.put("bp", target);
175
                }
176
                if((mod == 0 || mod == 1 || mod == 2) && rm == 3) {
177
                    long di = Layer.norm(random.nextInt(65536));
178
                    map.put("di", di);
179
                    target = update_target(target, di);
180
                    map.put("bp", target);
181
                }
182
                if((mod == 0 || mod == 1 || mod == 2) && rm == 4) {
183
                    map.put("si", target);
184
                }
185
                if((mod == 0 || mod == 1 || mod == 2) && rm == 5) {
186
                    map.put("di", target);
187
                }
188
                if(mod == 0 && rm == 6) {
189
                    map.put("disp16", target);
190
                }
191
                if((mod == 1 || mod == 2) && rm == 6) {
192
                    map.put("bp", target);
193
                }
194
                if((mod == 0 || mod == 1 || mod == 2) && rm == 7) {
195
                    map.put("bx", target);
196
                }
197
            }
198
 
199
            if(a32) {
200
                if(mod == 1 && rm != 4) {
201
                    long disp8 = random.nextInt(256);
202
                    map.put("disp8", disp8);
203
                    if((disp8 >> 7) == 1) disp8 |= 0xFFFFFF00;
204
                    target = update_target(target, disp8);
205
System.out.printf("disp8: %x\n", disp8);
206
                }
207
                if(mod == 2 && rm != 4) {
208
                    long disp32 = Layer.norm(random.nextInt());
209
                    map.put("disp32", disp32);
210
                    target = update_target(target, disp32);
211
                }
212
 
213
                if((mod == 0 || mod == 1 || mod == 2) && rm == 0) {
214
                    map.put("eax", target);
215
                }
216
                if((mod == 0 || mod == 1 || mod == 2) && rm == 1) {
217
                    map.put("ecx", target);
218
                }
219
                if((mod == 0 || mod == 1 || mod == 2) && rm == 2) {
220
                    map.put("edx", target);
221
                }
222
                if((mod == 0 || mod == 1 || mod == 2) && rm == 3) {
223
                    map.put("ebx", target);
224
                }
225
                if(mod == 0 && rm == 5) {
226
                    map.put("disp32", target);
227
                }
228
                if((mod == 1 || mod == 2) && rm == 5) {
229
                    map.put("ebp", target);
230
                }
231
                if((mod == 0 || mod == 1 || mod == 2) && rm == 6) {
232
                    map.put("esi", target);
233
                }
234
                if((mod == 0 || mod == 1 || mod == 2) && rm == 7) {
235
                    map.put("edi", target);
236
                }
237
 
238
                if(rm == 4) {
239
                    is_sib = true;
240
 
241
                    HashMap<String, Integer> sib_map = new HashMap<>();
242
 
243
                    sib_map.put("eax", 0);
244
                    sib_map.put("ecx", 0);
245
                    sib_map.put("edx", 0);
246
                    sib_map.put("ebx", 0);
247
                    sib_map.put("esp", 0);
248
                    sib_map.put("ebp", 0);
249
                    sib_map.put("esi", 0);
250
                    sib_map.put("edi", 0);
251
 
252
                    if(base == 0) sib_map.put("eax", sib_map.get("eax") + 1);
253
                    if(base == 1) sib_map.put("ecx", sib_map.get("ecx") + 1);
254
                    if(base == 2) sib_map.put("edx", sib_map.get("edx") + 1);
255
                    if(base == 3) sib_map.put("ebx", sib_map.get("ebx") + 1);
256
                    if(base == 4) sib_map.put("esp", sib_map.get("esp") + 1);
257
                    if(base == 5 && (mod == 1 || mod == 2)) sib_map.put("ebp", sib_map.get("ebp") + 1);
258
                    if(base == 6) sib_map.put("esi", sib_map.get("esi") + 1);
259
                    if(base == 7) sib_map.put("edi", sib_map.get("edi") + 1);
260
 
261
                    if(mod == 0 && base == 5)   sib_map.put("disp32", 1);
262
                    if(mod == 1)                sib_map.put("disp8",  1);
263
                    if(mod == 2)                sib_map.put("disp32", 1);
264
 
265
                    int count = (scale == 0)? 1 :
266
                                (scale == 1)? 2 :
267
                                (scale == 2)? 4 :
268
                                              8;
269
                    if(index == 0) sib_map.put("eax", sib_map.get("eax") + count);
270
                    if(index == 1) sib_map.put("ecx", sib_map.get("ecx") + count);
271
                    if(index == 2) sib_map.put("edx", sib_map.get("edx") + count);
272
                    if(index == 3) sib_map.put("ebx", sib_map.get("ebx") + count);
273
                    if(index == 5) sib_map.put("ebp", sib_map.get("ebp") + count);
274
                    if(index == 6) sib_map.put("esi", sib_map.get("esi") + count);
275
                    if(index == 7) sib_map.put("edi", sib_map.get("edi") + count);
276
 
277
                    //-----
278
 
279
                    if(sib_map.containsKey("disp8")) {
280
                        long disp8 = random.nextInt(256);
281
                        map.put("disp8", disp8);
282
                        if((disp8 >> 7) == 1) disp8 |= 0xFFFFFF00;
283
                        target = update_target(target, disp8);
284
 
285
                        sib_map.remove("disp8");
286
                    }
287
 
288
                    String found = null;
289
                    for(String s : sib_map.keySet()) {
290
                        if(sib_map.get(s) == 1) {
291
                            found = s;
292
                            break;
293
                        }
294
                    }
295
 
296
                    while(found != null) {
297
                        String key = sib_map.keySet().toArray(new String[0])[random.nextInt(sib_map.keySet().size())];
298
                        if(sib_map.get(key) != 1) continue;
299
                        found = key;
300
                        sib_map.remove(found);
301
                        break;
302
                    }
303
 
304
                    if(found != null) {
305
                        for(String s : sib_map.keySet()) {
306
                            int coeff = sib_map.get(s);
307
 
308
                            if(coeff > 0) {
309
                                long val32 = Layer.norm(random.nextInt());
310
                                while((val32 % coeff) != 0) val32--;
311
                                map.put(s, val32/coeff);
312
                                target = update_target(target, val32);
313
                            }
314
                        }
315
                        map.put(found, target);
316
                    }
317
                    else {
318
                        while(true) {
319
                            boolean removed = false;
320
                            for(String s : sib_map.keySet()) {
321
                                if(sib_map.get(s) == 0) {
322
                                    sib_map.remove(s);
323
                                    removed = true;
324
                                    break;
325
                                }
326
                            }
327
                            if(removed == false) break;
328
                        }
329
 
330
                        if(sib_map.size() != 1) throw new Exception("Internal test error");
331
 
332
                        int coeff = 0;
333
                        String key = null;
334
                        for(String s : sib_map.keySet()) {
335
                            coeff = sib_map.get(s);
336
                            key = s;
337
                            break;
338
                        }
339
 
340
                        if((target % coeff) != 0) continue;
341
 
342
                        map.put(key, target/coeff);
343
                    }
344
                }
345
            }
346
            break;
347
        }
348
        if(map.containsKey("eax")) layers.addFirst(new Layer(random) { long eax() { return map.get("eax").longValue() & 0xFFFFFFFFL; } });
349
        if(map.containsKey("ecx")) layers.addFirst(new Layer(random) { long ecx() { return map.get("ecx").longValue() & 0xFFFFFFFFL; } });
350
        if(map.containsKey("edx")) layers.addFirst(new Layer(random) { long edx() { return map.get("edx").longValue() & 0xFFFFFFFFL; } });
351
        if(map.containsKey("ebx")) layers.addFirst(new Layer(random) { long ebx() { return map.get("ebx").longValue() & 0xFFFFFFFFL; } });
352
        if(map.containsKey("esp")) layers.addFirst(new Layer(random) { long esp() { return map.get("esp").longValue() & 0xFFFFFFFFL; } });
353
        if(map.containsKey("ebp")) layers.addFirst(new Layer(random) { long ebp() { return map.get("ebp").longValue() & 0xFFFFFFFFL; } });
354
        if(map.containsKey("esi")) layers.addFirst(new Layer(random) { long esi() { return map.get("esi").longValue() & 0xFFFFFFFFL; } });
355
        if(map.containsKey("edi")) layers.addFirst(new Layer(random) { long edi() { return map.get("edi").longValue() & 0xFFFFFFFFL; } });
356
 
357
        if(map.containsKey("ax")) layers.addFirst(new Layer(random) { long eax() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("ax").intValue()) & 0xFFFF); } });
358
        if(map.containsKey("cx")) layers.addFirst(new Layer(random) { long ecx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("cx").intValue()) & 0xFFFF); } });
359
        if(map.containsKey("dx")) layers.addFirst(new Layer(random) { long edx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("dx").intValue()) & 0xFFFF); } });
360
        if(map.containsKey("bx")) layers.addFirst(new Layer(random) { long ebx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("bx").intValue()) & 0xFFFF); } });
361
        if(map.containsKey("sp")) layers.addFirst(new Layer(random) { long esp() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("sp").intValue()) & 0xFFFF); } });
362
        if(map.containsKey("bp")) layers.addFirst(new Layer(random) { long ebp() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("bp").intValue()) & 0xFFFF); } });
363
        if(map.containsKey("si")) layers.addFirst(new Layer(random) { long esi() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("si").intValue()) & 0xFFFF); } });
364
        if(map.containsKey("di")) layers.addFirst(new Layer(random) { long edi() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("di").intValue()) & 0xFFFF); } });
365
 
366
        if(map.containsKey("al")) layers.addFirst(new Layer(random) { long eax() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("al").intValue()) & 0xFF); } });
367
        if(map.containsKey("ah")) layers.addFirst(new Layer(random) { long eax() { return random.nextInt(256) | (((int)Layer.norm(map.get("ah").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
368
        if(map.containsKey("bl")) layers.addFirst(new Layer(random) { long ebx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("bl").intValue()) & 0xFF); } });
369
        if(map.containsKey("bh")) layers.addFirst(new Layer(random) { long ebx() { return random.nextInt(256) | (((int)Layer.norm(map.get("bh").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
370
        if(map.containsKey("cl")) layers.addFirst(new Layer(random) { long ecx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("cl").intValue()) & 0xFF); } });
371
        if(map.containsKey("ch")) layers.addFirst(new Layer(random) { long ecx() { return random.nextInt(256) | (((int)Layer.norm(map.get("ch").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
372
        if(map.containsKey("dl")) layers.addFirst(new Layer(random) { long edx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("dl").intValue()) & 0xFF); } });
373
        if(map.containsKey("dh")) layers.addFirst(new Layer(random) { long edx() { return random.nextInt(256) | (((int)Layer.norm(map.get("dh").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
374
 
375
        if(is_memory) {
376
System.out.printf("value_from_mod_rm: %x\n", value_from_mod_rm);
377
            target_map.clear();
378
            for(int i=0; i<length_allowed; i++) {
379
                target_map.put(seg_base+target_final+i, (byte)((value_from_mod_rm >> (i*8)) & 0xFF));
380
            }
381
            layers.addFirst(new Layer(random) {
382
                public boolean is_memory_not_random(long address) { return target_map.containsKey(address); }
383
 
384
                public Byte get_memory(long address) {
385
                    return (target_map.containsKey(address) == false)? null : target_map.get(address);
386
                }
387
            });
388
        }
389
 
390
 
391
        // prepare modregrm bytes
392
        if(map.containsKey("disp8")) {
393
            if(disp_length != 0) throw new Exception("Internal test error");
394
            disp = map.get("disp8");
395
            disp_length = 1;
396
        }
397
        if(map.containsKey("disp16")) {
398
            if(disp_length != 0) throw new Exception("Internal test error");
399
            disp = map.get("disp16");
400
            disp_length = 2;
401
        }
402
        if(map.containsKey("disp32")) {
403
            if(disp_length != 0) throw new Exception("Internal test error");
404
            disp = map.get("disp32");
405
            disp_length = 4;
406
        }
407
 
408
        int reg = (reg_type == modregrm_reg_t.SET)? value_from_reg : random.nextInt(8);
409
 
410
        LinkedList<Byte> modregrm_bytes = new LinkedList<>();
411
 
412
        modregrm_bytes.add((byte)( ((mod & 0x3) << 6) | ((reg & 0x7) << 3) | ((rm & 0x7) << 0) ));
413
 
414
System.out.printf("modregrm: %x\n", modregrm_bytes.get(0));
415
System.out.printf("len: %d - %d\n", length_allowed, length);
416
System.out.printf("seg_base: %x\n", seg_base);
417
 
418
        if(is_sib)              modregrm_bytes.add((byte)( ((scale & 0x3) << 6) | ((index & 0x7) << 3) | ((base & 0x7) << 0) ));
419
        if(disp_length == 1)    modregrm_bytes.add((byte)(disp & 0xFF));
420
        if(disp_length == 2) {
421
            modregrm_bytes.add((byte)(disp & 0xFF));
422
            modregrm_bytes.add((byte)((disp >> 8) & 0xFF));
423
        }
424
        if(disp_length == 4) {
425
            modregrm_bytes.add((byte)(disp & 0xFF));
426
            modregrm_bytes.add((byte)((disp >> 8) & 0xFF));
427
            modregrm_bytes.add((byte)((disp >> 16) & 0xFF));
428
            modregrm_bytes.add((byte)((disp >> 24) & 0xFF));
429
        }
430
 
431
        byte bytes[] = new byte[modregrm_bytes.size()];
432
        for(int i=0; i<bytes.length; i++) bytes[i] = modregrm_bytes.get(i);
433
 
434
        return bytes;
435
    }
436
    static HashMap<Long, Byte> target_map = new HashMap<>();
437
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.