Skip to content

Commit 7a9ff99

Browse files
Merge pull request #22 from Dil4rd/master
mips and mips64 support
2 parents a6758d1 + 5fee52e commit 7a9ff99

File tree

5 files changed

+228
-1
lines changed

5 files changed

+228
-1
lines changed

linux-user/mips/cpu_loop.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#include "internal.h"
2626
#include "fpu_helper.h"
2727

28+
/* MIPS_PATCH */
29+
#include "qemuafl/common.h"
30+
2831
# ifdef TARGET_ABI_MIPSO32
2932
# define MIPS_SYSCALL_NUMBER_UNUSED -1
3033
static const int8_t mips_syscall_args[] = {

qemuafl/api.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,26 @@
33

44
#include <stdint.h>
55

6+
#if defined(TARGET_MIPS64) || defined(TARGET_AARCH64) || defined(TARGET_X86_64)
7+
# define TARGET_LONG_BITS 64
8+
#else
9+
# define TARGET_LONG_BITS 32
10+
#endif
11+
12+
/* see include/exec/cpu-defs.h */
13+
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
14+
15+
#if TARGET_LONG_SIZE == 4
16+
typedef int32_t target_long;
17+
typedef uint32_t target_ulong;
18+
#elif TARGET_LONG_SIZE == 8
19+
typedef int64_t target_long;
20+
typedef uint64_t target_ulong;
21+
#else
22+
#error TARGET_LONG_SIZE undefined
23+
#endif
24+
25+
626
struct x86_regs {
727

828
uint32_t eax, ebx, ecx, edx, edi, esi, ebp;
@@ -137,4 +157,52 @@ struct arm64_regs {
137157

138158
};
139159

160+
/* MIPS_PATCH */
161+
#if defined(TARGET_MIPS) || defined(TARGET_MIPS64)
162+
163+
// check standalone usage
164+
// if smth in pers hook goes wrong, check constants below with target/mips/cpu.h
165+
#ifndef MIPS_CPU_H
166+
#include <stdbool.h>
167+
#include "../include/fpu/softfloat-types.h"
168+
169+
/* MSA Context */
170+
#define MSA_WRLEN (128)
171+
typedef union wr_t wr_t;
172+
union wr_t {
173+
int8_t b[MSA_WRLEN / 8];
174+
int16_t h[MSA_WRLEN / 16];
175+
int32_t w[MSA_WRLEN / 32];
176+
int64_t d[MSA_WRLEN / 64];
177+
};
178+
typedef union fpr_t fpr_t;
179+
union fpr_t {
180+
float64 fd; /* ieee double precision */
181+
float32 fs[2];/* ieee single precision */
182+
uint64_t d; /* binary double fixed-point */
183+
uint32_t w[2]; /* binary single fixed-point */
184+
/* FPU/MSA register mapping is not tested on big-endian hosts. */
185+
wr_t wr; /* vector data */
186+
};
187+
#define MIPS_DSP_ACC 4
188+
#endif
189+
190+
struct mips_regs {
191+
target_ulong r0, at, v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5, t6, t7, s0,
192+
s1, s2, s3, s4, s5, s6, s7, t8, t9, k0, k1, gp, sp, fp, ra;
193+
#if defined(TARGET_MIPS64)
194+
/*
195+
* For CPUs using 128-bit GPR registers, we put the lower halves in gpr[])
196+
* and the upper halves in gpr_hi[].
197+
*/
198+
uint64_t gpr_hi[32];
199+
#endif /* TARGET_MIPS64 */
200+
target_ulong HI[MIPS_DSP_ACC];
201+
target_ulong LO[MIPS_DSP_ACC];
202+
target_ulong ACX[MIPS_DSP_ACC];
203+
target_ulong PC;
204+
fpr_t fpr[32];
205+
};
206+
#endif
207+
140208
#endif

qemuafl/common.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
#define api_regs arm64_regs
5151
#elif defined(TARGET_ARM)
5252
#define api_regs arm_regs
53+
/* MIPS_PATCH */
54+
#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
55+
#define api_regs mips_regs
5356
#else
5457
struct generic_api_regs { int v; };
5558
#define api_regs generic_api_regs
@@ -134,7 +137,7 @@ void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1,
134137
abi_ulong afl_get_brk(void);
135138
abi_ulong afl_set_brk(abi_ulong new_brk);
136139

137-
#if defined(TARGET_X86_64) || defined(TARGET_I386) || defined(TARGET_AARCH64) || defined(TARGET_ARM)
140+
#if defined(TARGET_X86_64) || defined(TARGET_I386) || defined(TARGET_AARCH64) || defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_MIPS64)
138141
void afl_save_regs(struct api_regs* regs, CPUArchState* env);
139142
void afl_restore_regs(struct api_regs* regs, CPUArchState* env);
140143
#else

qemuafl/qasan-qemu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ extern __thread struct shadow_stack qasan_shadow_stack;
8383
#define BP_GET(env) ((env)->aarch64 ? (env)->xregs[29] : (env)->regs[11])
8484
#define SP_GET(env) ((env)->aarch64 ? (env)->xregs[31] : (env)->regs[13])
8585

86+
/* MIPS_PATCH */
87+
#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
88+
89+
#define PC_GET(env) ((env)->active_tc.PC)
90+
#define BP_GET(env) ((env)->active_tc.gpr[29])
91+
#define SP_GET(env) ((env)->active_tc.gpr[30])
92+
8693
#else
8794
#error "Target not supported by asan-giovese"
8895
#endif

target/mips/translate.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@
3939
#include "fpu_helper.h"
4040
#include "translate.h"
4141

42+
/* MIPS_PATCH */
43+
#include "qemuafl/cpu-translate.h"
44+
45+
/* MIPS_PATCH */
46+
#define AFL_QEMU_TARGET_MIPS_SNIPPET \
47+
if (is_persistent) { \
48+
if (ctx->base.pc_next == afl_persistent_addr) { \
49+
gen_helper_afl_persistent_routine(cpu_env); \
50+
\
51+
if (afl_persistent_ret_addr == 0 && !persistent_exits) { \
52+
tcg_gen_movi_tl(cpu_gpr[31], afl_persistent_addr); \
53+
} \
54+
\
55+
if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \
56+
\
57+
} else if (afl_persistent_ret_addr && \
58+
ctx->base.pc_next == afl_persistent_ret_addr) { \
59+
gen_goto_tb(ctx, 0, afl_persistent_addr); \
60+
} \
61+
}
62+
4263
enum {
4364
/* indirect opcode tables */
4465
OPC_SPECIAL = (0x00 << 26),
@@ -2274,6 +2295,128 @@ static const char * const mxuregnames[] = {
22742295
};
22752296
#endif
22762297

2298+
/* MIPS_PATCH */
2299+
void afl_save_regs(struct api_regs* r, CPUArchState *env) {
2300+
int i = 0;
2301+
int j = 0;
2302+
/* GP registers saving */
2303+
r->r0 = env->active_tc.gpr[0];
2304+
r->at = env->active_tc.gpr[1];
2305+
r->v0 = env->active_tc.gpr[2];
2306+
r->v1 = env->active_tc.gpr[3];
2307+
r->a0 = env->active_tc.gpr[4];
2308+
r->a1 = env->active_tc.gpr[5];
2309+
r->a2 = env->active_tc.gpr[6];
2310+
r->a3 = env->active_tc.gpr[7];
2311+
r->t0 = env->active_tc.gpr[8];
2312+
r->t1 = env->active_tc.gpr[9];
2313+
r->t2 = env->active_tc.gpr[10];
2314+
r->t3 = env->active_tc.gpr[11];
2315+
r->t4 = env->active_tc.gpr[12];
2316+
r->t5 = env->active_tc.gpr[13];
2317+
r->t6 = env->active_tc.gpr[14];
2318+
r->t7 = env->active_tc.gpr[15];
2319+
r->s0 = env->active_tc.gpr[16];
2320+
r->s1 = env->active_tc.gpr[17];
2321+
r->s2 = env->active_tc.gpr[18];
2322+
r->s3 = env->active_tc.gpr[19];
2323+
r->s4 = env->active_tc.gpr[20];
2324+
r->s5 = env->active_tc.gpr[21];
2325+
r->s6 = env->active_tc.gpr[22];
2326+
r->s7 = env->active_tc.gpr[23];
2327+
r->t8 = env->active_tc.gpr[24];
2328+
r->t9 = env->active_tc.gpr[25];
2329+
r->k0 = env->active_tc.gpr[26];
2330+
r->k1 = env->active_tc.gpr[27];
2331+
r->gp = env->active_tc.gpr[28];
2332+
r->sp = env->active_tc.gpr[29];
2333+
r->fp = env->active_tc.gpr[30];
2334+
r->ra = env->active_tc.gpr[31];
2335+
r->PC = env->active_tc.PC;
2336+
#if defined(TARGET_MIPS64)
2337+
memcpy(r->gpr_hi, env->active_tc.gpr_hi, sizeof(r->gpr_hi));
2338+
#endif
2339+
for (i = 0; i < MIPS_DSP_ACC; i++) {
2340+
r->HI[i] = env->active_tc.HI[i];
2341+
r->LO[i] = env->active_tc.LO[i];
2342+
}
2343+
/* FP registers saving */
2344+
for (i = 0; i < 32; i++) {
2345+
r->fpr[i].fd = env->active_fpu.fpr[i].fd;
2346+
for (j = 0; j < 2; j++) {
2347+
r->fpr[i].fs[j] = env->active_fpu.fpr[i].fs[j];
2348+
}
2349+
r->fpr[i].d = env->active_fpu.fpr[i].d;
2350+
for (j = 0; j < 2; j++) {
2351+
r->fpr[i].w[j] = env->active_fpu.fpr[i].w[j];
2352+
}
2353+
for (j = 0; j < MSA_WRLEN / 8; j++) {
2354+
r->fpr[i].wr.b[j] = env->active_fpu.fpr[i].wr.b[j];
2355+
}
2356+
}
2357+
}
2358+
2359+
/* MIPS_PATCH */
2360+
void afl_restore_regs(struct api_regs* r, CPUArchState *env) {
2361+
int i = 0;
2362+
int j = 0;
2363+
/* GP registers restoring */
2364+
env->active_tc.gpr[0] = r->r0;
2365+
env->active_tc.gpr[1] = r->at;
2366+
env->active_tc.gpr[2] = r->v0;
2367+
env->active_tc.gpr[3] = r->v1;
2368+
env->active_tc.gpr[4] = r->a0;
2369+
env->active_tc.gpr[5] = r->a1;
2370+
env->active_tc.gpr[6] = r->a2;
2371+
env->active_tc.gpr[7] = r->a3;
2372+
env->active_tc.gpr[8] = r->t0;
2373+
env->active_tc.gpr[9] = r->t1;
2374+
env->active_tc.gpr[10] = r->t2;
2375+
env->active_tc.gpr[11] = r->t3;
2376+
env->active_tc.gpr[12] = r->t4;
2377+
env->active_tc.gpr[13] = r->t5;
2378+
env->active_tc.gpr[14] = r->t6;
2379+
env->active_tc.gpr[15] = r->t7;
2380+
env->active_tc.gpr[16] = r->s0;
2381+
env->active_tc.gpr[17] = r->s1;
2382+
env->active_tc.gpr[18] = r->s2;
2383+
env->active_tc.gpr[19] = r->s3;
2384+
env->active_tc.gpr[20] = r->s4;
2385+
env->active_tc.gpr[21] = r->s5;
2386+
env->active_tc.gpr[22] = r->s6;
2387+
env->active_tc.gpr[23] = r->s7;
2388+
env->active_tc.gpr[24] = r->t8;
2389+
env->active_tc.gpr[25] = r->t9;
2390+
env->active_tc.gpr[26] = r->k0;
2391+
env->active_tc.gpr[27] = r->k1;
2392+
env->active_tc.gpr[28] = r->gp;
2393+
env->active_tc.gpr[29] = r->sp;
2394+
env->active_tc.gpr[30] = r->fp;
2395+
env->active_tc.gpr[31] = r->ra;
2396+
env->active_tc.PC = r->PC;
2397+
#if defined(TARGET_MIPS64)
2398+
memcpy(env->active_tc.gpr_hi, r->gpr_hi, sizeof(r->gpr_hi));
2399+
#endif
2400+
for (i = 0; i < MIPS_DSP_ACC; i++) {
2401+
env->active_tc.HI[i] = r->HI[i];
2402+
env->active_tc.LO[i] = r->LO[i];
2403+
}
2404+
/* FP registers restoring */
2405+
for (i = 0; i < 32; i++) {
2406+
env->active_fpu.fpr[i].fd = r->fpr[i].fd;
2407+
for (j = 0; j < 2; j++) {
2408+
env->active_fpu.fpr[i].fs[j] = r->fpr[i].fs[j];
2409+
}
2410+
env->active_fpu.fpr[i].d = r->fpr[i].d;
2411+
for (j = 0; j < 2; j++) {
2412+
env->active_fpu.fpr[i].w[j] = r->fpr[i].w[j];
2413+
}
2414+
for (j = 0; j < MSA_WRLEN / 8; j++) {
2415+
env->active_fpu.fpr[i].wr.b[j] = r->fpr[i].wr.b[j];
2416+
}
2417+
}
2418+
}
2419+
22772420
/* General purpose registers moves. */
22782421
void gen_load_gpr(TCGv t, int reg)
22792422
{
@@ -29090,6 +29233,9 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2909029233
int insn_bytes;
2909129234
int is_slot;
2909229235

29236+
/* MIPS_PATCH */
29237+
AFL_QEMU_TARGET_MIPS_SNIPPET
29238+
2909329239
is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
2909429240
if (ctx->insn_flags & ISA_NANOMIPS32) {
2909529241
ctx->opcode = translator_lduw(env, ctx->base.pc_next);

0 commit comments

Comments
 (0)