/** * remove all jobs matching the name.. */ int del_cronjob(p_cronjob job){ p_linkedlist item = ll_create(job, sizeof(t_cronjob)); p_linkedlist remove = ll_find(cronlist, item, jobequal); while(remove != 0) { cronlist = ll_remove(cronlist,remove); ll_destroy(remove); remove = ll_find(cronlist, item, jobequal); } ll_destroy(item); }
/* Find and execute hook. */ int tracy_execute_hook(struct tracy *t, char *syscall, struct tracy_event *e) { struct tracy_ll_item *item; int hash; union { void *pvoid; tracy_hook_func pfunc; } _hax; if (TRACY_PRINT_SYSCALLS(t)) printf(_y("%04d System call: %s (%ld) Pre: %d")"\n", e->child->pid, get_syscall_name_abi(e->syscall_num, e->abi), e->syscall_num, e->child->pre_syscall); hash = hash_syscall(syscall, e->abi); item = ll_find(t->hooks, hash); if (item) { /* printf("Executing hook for: %s\n", syscall); */ /* ANSI C has some disadvantages too ... */ _hax.pvoid = item->data; return _hax.pfunc(e); } if (t->defhook) return t->defhook(e); return TRACY_HOOK_NOHOOK; }
static int hook_close(struct tracy_event *e) { int rc = TRACY_HOOK_CONTINUE; struct multiboot_child_data *mbc = e->child->custom; if (e->child->pre_syscall) { int fd = (int)e->args.a0; struct tracy_ll_item *item = ll_find(mbc->files, fd); if (item) { struct fd_info *fdi = item->data; ERROR("close(%d|%s)\n", fd, fdi->filename); // TODO detect format if (fs_was_format(fdi)) { DEBUG("FORMAT DETECTED!\n"); struct fstab_rec *fstabrec = get_fstab_rec(fdi->filename); if (fstabrec) { INFO("format path %s...\n", fstabrec->replacement_device); char buf[PATH_MAX]; snprintf(buf, sizeof(buf), "%s/*", fstabrec->replacement_device); format_path(buf); } } free_fdinfo(fdi); ll_del(mbc->files, fd); } } return rc; }
/* * * Simple hooking into system calls. Calls are passed by name to keep them * platform independent. * * * XXX: This is not true^, we can just use SYS_foo too. (Although SYS_clone does * not exist on say, BSD) * */ int tracy_set_hook(struct tracy *t, char *syscall, long abi, tracy_hook_func func) { struct tracy_ll_item *item; int hash; union { void *pvoid; tracy_hook_func pfunc; } _hax; /* XXX: Do this for each abi in abi_mask */ hash = hash_syscall(syscall, abi); item = ll_find(t->hooks, hash); _hax.pfunc = func; if (!item) { if (ll_add(t->hooks, hash, _hax.pvoid)) { /* XXX: Add debug/print here */ return -1; } } else { /* XXX: Add debug/print here */ return -1; } return 0; }
int ht_find(struct hash_table *ht, void *key, void *value){ unsigned int hash; int ret; hash = ht->hash(key, ht->keysz) % ht->size; if(ht->table[hash] == NULL){ /* Nothing at this index */ return -1; } ret = ll_find(ht->table[hash], key, value); if(ret) return -1; return 0; }
static int hook_dup(struct tracy_event *e) { int rc = TRACY_HOOK_CONTINUE; struct multiboot_child_data *mbc = e->child->custom; if (e->child->pre_syscall) { int fd = (int)e->args.a0; struct tracy_ll_item *item = ll_find(mbc->files, fd); if (item) { struct fd_info *fdi = item->data; mbc->tmp = strdup(fdi->filename); } } else { // we need to handle write for this fd if (mbc->tmp) { int fd = (int)e->args.return_code; DEBUG("dup(%s) = %d\n", mbc->tmp, fd); if (fd >= 0) { struct fd_info *fdi = make_fdinfo(e->child, fd, mbc->tmp); if (fdi) ll_add(mbc->files, fd, make_fdinfo(e->child, fd, mbc->tmp)); else { ERROR("Couldn't make fdinfo for %s!\n", mbc->tmp); free(mbc->tmp); } } // dup failed else free(mbc->tmp); mbc->tmp = NULL; } } return rc; }
int all(struct tracy_event *e) { struct tracy_ll_item *i; long syscall; if(e->child->pre_syscall) return TRACY_HOOK_CONTINUE; syscall = e->syscall_num; i = ll_find(ll, syscall); if (i) { i->data = (void*)((long)(i->data) + 1); } else { ll_add(ll, syscall, (void*)1); } return TRACY_HOOK_CONTINUE; }
static int hook_fcntl(struct tracy_event *e) { int rc = TRACY_HOOK_CONTINUE; struct multiboot_child_data *mbc = e->child->custom; if (e->child->pre_syscall) { int fd = (int)e->args.a0; struct tracy_ll_item *item = ll_find(mbc->files, fd); if (item) { struct fd_info *fdi = item->data; // TODO handle switiching access mode ERROR("fcntl(%d|%s)\n", fd, fdi->filename); rc = TRACY_HOOK_ABORT; } } return rc; }
void lie_transfo_opcodes(linkedlist* opcodes,linkedlist* transformations) { cellule* co=ll_front(opcodes); while(co!=NULL) { Opcode* o=(Opcode*)co->valeur; if(o->letype==CALLOPCODE) { cellule* lct=ll_find(transformations,o->operandes.opcall.nomtransfo,cmp_char_transfo); Transformation* lt=(Transformation*)lct->valeur; o->operandes.opcall.transfo=lt; } else if(o->letype==CONDITIONIF) { lie_transfo_opcodes(&o->operandes.opif.codeif,transformations); } else if(o->letype==CONDITIONIFELSE) { lie_transfo_opcodes(&o->operandes.opif.codeif,transformations); lie_transfo_opcodes(&o->operandes.opif.codeelse,transformations); } co=ll_next(opcodes,co); } }
static proxy_t *proxy_find(struct tracy_event *e, int fd) { struct tracy_ll_item *p = ll_find(cproxy(e->child->custom)->ll, fd); return (p != NULL) ? (proxy_t *) p->data : NULL; }
int asm_sous_opcode(FILE* f,SousOpcode* s,Regle* r,linkedlist* arguments,linkedlist* lockeds) { switch(s->letype) { case ARG: { int reg=registre_libre(f); cellule* p=ll_find(arguments,s->operandes.nom,compare_char_arg); if(p!=NULL) { int pos=ll_indice(arguments,p); fprintf(f,"\tmov %s,[esi+%d+8] ; %s\n",registres_noms[reg],(ll_size(arguments)-1-pos)*4,s->operandes.nom); s->argtype=((Argument*)p->valeur)->type; return reg; } p=ll_find(lockeds,s->operandes.nom,compare_lockeds); if(p!=NULL) { fprintf(f,"\tmov %s,[ebp+locked_%s]\n",registres_noms[reg],s->operandes.nom); return reg; } fprintf(stderr,"[FATAL] Identificateur inconnu : %s\n",s->operandes.nom); } case UREG: case REG: { int reg=registre_libre(f); fprintf(f,"\tmov %s,%s\n",registres_noms[reg],asm_registres[s->operandes.valeur]); return reg; } case VAREXT: { int reg=registre_libre(f); fprintf(f,"\tmov %s,%s\n",registres_noms[reg],s->operandes.nom); return reg; } case RNDI: { int reg; if(r->randint_used[s->operandes.valeur]>1) { reg=registre_libre(f); fprintf(f,"\tmov %s,[esi-%d-4] ; RNDINT%d\n",registres_noms[reg],position_rnd(s->operandes.valeur,r->randint_used)*4,s->operandes.valeur); } else { reg=registre_libre_different(f,REAX); registre_force(f,REAX); fprintf(f,"\txor eax,eax\n\tdec eax\n"); fprintf(f,"\tcall poly_rand_int\n"); fprintf(f,"\tmov %s,%s ; RNDINT%d\n",registres_noms[reg],registres_noms[REAX],s->operandes.valeur); libere_registre(f,REAX); } return reg; } case RNDR: { int reg; if(r->randreg_used[s->operandes.valeur]>0) { reg=registre_libre(f); fprintf(f,"\tmov %s,[esi-%d-4] ; FREEREG%d\n",registres_noms[reg],(r->nb_randint+position_rnd(s->operandes.valeur,r->randreg_used))*4,s->operandes.valeur); } else { reg=registre_libre_different(f,REAX); registre_force(f,REAX); fprintf(f,"\tcall choix_registre\n"); fprintf(f,"\tmov %s,%s ; FREEREG%d\n",registres_noms[reg],registres_noms[REAX],s->operandes.valeur); libere_registre(f,REAX); } return reg; } case URNDR: { int reg; if(r->urandreg_used[s->operandes.valeur]>0) { reg=registre_libre(f); fprintf(f,"\tmov %s,[esi-%d-4] ; RNDREG%d\n",registres_noms[reg],(r->nb_randint+r->nb_randreg+r->nb_randmem+r->nb_lab+position_rnd(s->operandes.valeur,r->urandreg_used))*4,s->operandes.valeur); } else { reg=registre_libre_different(f,REAX); registre_force(f,REAX); fprintf(f,"\tcall choix_uregistre\n"); fprintf(f,"\tmov %s,%s ; RNDREG%d\n",registres_noms[reg],registres_noms[REAX],s->operandes.valeur); libere_registre(f,REAX); } return reg; } case RNDM: { int reg; if(r->randmem_used[s->operandes.valeur]>0) { reg=registre_libre(f); fprintf(f,"\tmov %s,[esi-%d-4] ; FREEMEM%d\n",registres_noms[reg],(r->nb_randint+r->nb_randreg+position_rnd(s->operandes.valeur,r->randmem_used))*4,s->operandes.valeur); } else { reg=registre_libre_different(f,REBX); registre_force(f,REBX); fprintf(f,"\tcall choix_memoire\n"); fprintf(f,"\tmov %s,%s ; FREEMEM%d\n",registres_noms[reg],registres_noms[REAX],s->operandes.valeur); libere_registre(f,REBX); } return reg; } case LAB: { int reg=registre_libre(f); fprintf(f,"\tmov %s,[esi-%d-4] ; LABEL%d\n",registres_noms[reg],(r->nb_randint+r->nb_randreg+r->nb_randmem+position_rnd(s->operandes.valeur,r->lab_used))*4,s->operandes.valeur); fprintf(f,"\tmov %s,[%s]\n",registres_noms[reg],registres_noms[reg]); return reg; } case CONSTANTE: { int reg=registre_libre(f); fprintf(f,"\tmov %s,%d\n",registres_noms[reg],s->operandes.valeur); return reg; } case ET: case OU: case OUEX: case SOUSTRACTION: case ADDITION: { char op[4]; switch(s->letype) { case ET: strcpy(op,"and"); break; case OU: strcpy(op,"or"); break; case OUEX: strcpy(op,"xor"); break; case ADDITION: strcpy(op,"add"); break; case SOUSTRACTION: strcpy(op,"sub"); break; } SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; int r1,r2; if(s1->letype==CONSTANTE && s->letype!=SOUSTRACTION) { r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\t%s %s,%d\n",op,registres_noms[r2],s1->operandes.valeur); return r2; } else if(s2->letype==CONSTANTE) { r1=asm_sous_opcode(f,s1,r,arguments,lockeds); fprintf(f,"\t%s %s,%d\n",op,registres_noms[r1],s2->operandes.valeur); return r1; } else { r1=asm_sous_opcode(f,s1,r,arguments,lockeds); r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\t%s %s,%s\n",op,registres_noms[r1],registres_noms[r2]); libere_registre(f,r2); return r1; } } case MULTIPLICATION: { SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; int r1=asm_sous_opcode(f,s1,r,arguments,lockeds); int r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\timul %s,%s\n",registres_noms[r1],registres_noms[r2]); libere_registre(f,r2); return r1; } case DIVISION: { SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; int r1=asm_sous_opcode(f,s1,r,arguments,lockeds); int r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\tidiv %s,%s\n",registres_noms[r1],registres_noms[r2]); libere_registre(f,r2); return r1; } case DECDROIT: case DECGAUCHE: { char op[4]; int r1,r2; if(s->letype==DECDROIT) strcpy(op,"shr"); else strcpy(op,"shl"); SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; if(s2->letype==CONSTANTE) { r1=asm_sous_opcode(f,s1,r,arguments,lockeds); fprintf(f,"\t%s %s,%d\n",op,registres_noms[r1],s2->operandes.valeur); return r1; } else { int reg=registre_libre_different(f,RECX); registre_force(f,RECX); r1=asm_sous_opcode(f,s1,r,arguments,lockeds); fprintf(f,"\tmov %s,%s\n",registres_noms[reg],registres_noms[r1]); r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\tmov ecx,%s\n",registres_noms[r2]); fprintf(f,"\tshl %s,cl\n",registres_noms[reg],registres_noms[r1]); libere_registre(f,r2); libere_registre(f,r1); libere_registre(f,RECX); return reg; } } case INDIRECTION: { SousOpcode* s1=s->operandes.sousopcode; int r1=asm_sous_opcode(f,s1,r,arguments,lockeds); if(r1!=REBX) { registre_force(f,REBX); fprintf(f,"\tmov ebx,%s\n",registres_noms[r1]); } fprintf(f,"\tcall contenu_memoire\n"); if(r1!=REBX) { fprintf(f,"\tmov %s,ebx\n"); libere_registre(f,REBX); } return r1; } case MOD: { SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; int r2=registre_libre_different2(f,REAX,REDX); registre_force(f,REAX); registre_force(f,REDX); int r1=asm_sous_opcode(f,s1,r,arguments,lockeds); if(r1!=REAX) fprintf(f,"\tmov eax,%s\n",registres_noms[r1]); fprintf(f,"\txor edx,edx\n"); libere_registre(f,r1); r1=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\tdiv %s\n",registres_noms[r1]); if(r2!=REDX) fprintf(f,"\tmov %s,edx\n",registres_noms[r2]); libere_registre(f,r1); libere_registre(f,REDX); libere_registre(f,REAX); return r2; } case NEGATION: { SousOpcode* s1=s->operandes.sousopcode; int r1=asm_sous_opcode(f,s1,r,arguments,lockeds); fprintf(f,"\tnot %s\n",registres_noms[r1]); return r1; } case JA: case JB: case JAE: case JBE: case JE: case JNE: { SousOpcode* s1=s->operandes.couple.gauche; SousOpcode* s2=s->operandes.couple.droit; int r1,r2; int l1=get_label(),l2=get_label(); if(s1->letype==CONSTANTE || s1->letype==UREG) { r2=asm_sous_opcode(f,s2,r,arguments,lockeds); if(s1->letype==CONSTANTE) fprintf(f,"\tcmp %s,%d\n",registres_noms[r2],s1->operandes.valeur); else fprintf(f,"\tcmp %s,%s\n",registres_noms[r2],asm_registres[s1->operandes.valeur]); r1=r2; } else if(s2->letype==CONSTANTE || s2->letype==UREG) { r1=asm_sous_opcode(f,s1,r,arguments,lockeds); if(s2->letype==CONSTANTE) fprintf(f,"\tcmp %s,%d\n",registres_noms[r1],s2->operandes.valeur); else fprintf(f,"\tcmp %s,%s\n",registres_noms[r1],asm_registres[s2->operandes.valeur]); } else { r1=asm_sous_opcode(f,s1,r,arguments,lockeds); r2=asm_sous_opcode(f,s2,r,arguments,lockeds); fprintf(f,"\tcmp %s,%s\n",registres_noms[r1],registres_noms[r2]); libere_registre(f,r2); } switch(s->letype) { case JA: fprintf(f,"\tjg goto_%d\n",l1); break; case JAE: fprintf(f,"\tjge goto_%d\n",l1); break; case JB: fprintf(f,"\tjl goto_%d\n",l1); break; case JBE: fprintf(f,"\tjle goto_%d\n",l1); break; case JE: fprintf(f,"\tje goto_%d\n",l1); break; case JNE: fprintf(f,"\tjne goto_%d\n",l1); break; } fprintf(f,"\txor %s,%s\n",registres_noms[r1],registres_noms[r1]); fprintf(f,"\tjmp goto_%d\n",l2); fprintf(f,"goto_%d:\n",l1); fprintf(f,"\txor %s,%s\n",registres_noms[r1],registres_noms[r1]); fprintf(f,"\tinc %s\n",registres_noms[r1]); fprintf(f,"goto_%d:\n",l2); return r1; } } return registre_libre(f); }
void asm_opcode(FILE* f,Opcode* o,Regle* r,linkedlist* arguments,linkedlist* lockeds) { switch(o->letype) { case ASMOPCODE: { int l=get_label(); fprintf(f,"\tcmp byte ptr [ebp+poly_passe],NB_PASSES/2\n"); fprintf(f,"\tjbe goto_%d ; pas d'asm a la première passe car labels faux\n",l); fprintf(f,"; ASM code from line %d\n",o->ligne); /* A changer : on remplace le nom des arguments par leur position dans la pile */ char* txt=o->operandes.opasm.asmtxt; int indice=0; cellule* a=ll_front(arguments); while(a!=NULL) { char rplc[20]; Argument* arg=(Argument*)a->valeur; snprintf(rplc,25,"[esi+%d+8]",(ll_size(arguments)-1-indice)*4); txt=strmyreplace(txt,(const char*)arg->nom,(const char*) rplc); a=ll_next(arguments,a); indice++; } indice=0; a=ll_front(lockeds); while(a!=NULL) { char rplc[250]; Locked* lo=(Locked*) a->valeur; snprintf(rplc,250,"[ebp+locked_%s]",lo->id); txt=strmyreplace(txt,(const char*)lo->id,(const char*) rplc); a=ll_next(lockeds,a); indice++; } o->operandes.opasm.asmtxt=txt; fprintf(f,"%s",txt); fprintf(f,"goto_%d: ; END of asm code\n",l); break; } case CALLOPCODE: { if(nb_calls_restants(r,o)>0) { fprintf(f,"\tmov eax,%d\n",nb_calls_restants(r,o)); fprintf(f,"\tcall optimise_taille_code_genere\n"); fprintf(f,"\tpush eax\n"); } if(o->operandes.opcall.transfo->regledefaut->minimum_taille>0) fprintf(f,"\tadd edx,%d ; taille minimale de la transformation %s\n",o->operandes.opcall.transfo->regledefaut->minimum_taille,o->operandes.opcall.transfo->nom); cellule* cs=ll_front(&o->operandes.opcall.arguments); while(cs!=NULL) { SousOpcode* s=(SousOpcode*)cs->valeur; int reg=asm_sous_opcode(f,s,r,arguments,lockeds); if(libere_registre(f,reg)) { fprintf(f,"\txchg %s,dword ptr [esp]\n",registres_noms[reg]); } else { fprintf(f,"\tpush %s\n",registres_noms[reg]); } cs=ll_next(&o->operandes.opcall.arguments,cs); } fprintf(f,"\tcall asm_%s\n",o->operandes.opcall.transfo->nom); if(nb_calls_restants(r,o)>0) { fprintf(f,"\tpop eax\n"); fprintf(f,"\tadd edx,eax\n"); } break; } case LABELOPCODE: { fprintf(f,"\tmov eax,edi\n"); fprintf(f,"\tsub eax,[ebp+poly_va_buffer]\n"); fprintf(f,"\tadd eax,[ebp+poly_va_code]\n"); fprintf(f,"\tmov ebx,[esi-%d-4] ; LABEL%d\n",(r->nb_randint+r->nb_randreg+r->nb_randmem+position_rnd(o->operandes.oplabel.num,r->lab_used))*4,o->operandes.oplabel.num); fprintf(f,"\tmov [ebx],eax\n"); break; } case LOCKOPCODE: { int reg=asm_sous_opcode(f,o->operandes.oplock.ss,r,arguments,lockeds ); if(o->operandes.oplock.ss->letype==REG || o->operandes.oplock.ss->letype==RNDR || o->operandes.oplock.ss->letype==ARG && o->operandes.oplock.ss->argtype==ATYPE_REGISTRE) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall lock_registre\n"); } else if(o->operandes.oplock.ss->letype==RNDM || o->operandes.oplock.ss->letype==ARG && o->operandes.oplock.ss->argtype==ATYPE_ADRESSE) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall lock_memoire\n"); } else if(o->operandes.oplock.ss->letype==UREG || o->operandes.oplock.ss->letype==URNDR ) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall lock_uregistre\n"); } if(o->operandes.oplock.id!=NULL) { fprintf(f,"\tmov [ebp+locked_%s],%s ; LOCKED\n",o->operandes.oplock.id,registres_noms[reg]); } libere_registre(f,reg); break; } case FREEOPCODE: { if(o->operandes.oplock.id!=NULL) { cellule* p=ll_find(lockeds,o->operandes.oplock.id,compare_lockeds); if(p!=NULL) { Locked* l=(Locked*)p->valeur; if(l->ss->letype==RNDR ||l->ss->letype==REG || l->ss->letype==ARG && l->ss->argtype==ATYPE_REGISTRE) { fprintf(f,"\tmov eax,[ebp+locked_%s] ; FREEDREG %s\n",l->id,l->id); fprintf(f,"\tcall free_registre\n"); } else if(l->ss->letype==RNDM || l->ss->letype==ARG && l->ss->argtype==ATYPE_ADRESSE) { fprintf(f,"\tmov eax,[ebp+locked_%s] ; FREEDMEM %s\n",l->id,l->id); fprintf(f,"\tcall free_memoire\n"); } else if(l->ss->letype==URNDR||l->ss->letype==UREG) { fprintf(f,"\tmov eax,[ebp+locked_%s] ; FREEDUREG %s\n",l->id,l->id); fprintf(f,"\tcall free_uregistre\n"); } } } else { int reg=asm_sous_opcode(f,o->operandes.oplock.ss,r,arguments,lockeds ); if(o->operandes.oplock.ss->letype==REG || o->operandes.oplock.ss->letype==RNDR ) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall free_registre\n"); } else if(o->operandes.oplock.ss->letype==RNDM) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall free_memoire\n"); } else if(o->operandes.oplock.ss->letype==UREG || o->operandes.oplock.ss->letype==URNDR ) { fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); fprintf(f,"\tcall free_uregistre\n"); } libere_registre(f,reg); } break; } case INITMEMOPCODE: { registre_force(f,REBX); int reg=asm_sous_opcode(f,o->operandes.opegal.valeur,r,arguments,lockeds); fprintf(f,"\tmov ebx,%s\n",registres_noms[reg]); libere_registre(f,reg); registre_force(f,REAX); reg=asm_sous_opcode(f,o->operandes.opegal.dest,r,arguments,lockeds); fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); libere_registre(f,reg); fprintf(f,"\tcall set_memoire\n"); libere_registre(f,REAX); libere_registre(f,REBX); break; } case CHANGEMEMOPCODE: { registre_force(f,REBX); int reg=asm_sous_opcode(f,o->operandes.opegal.valeur,r,arguments,lockeds); fprintf(f,"\tmov ebx,%s\n",registres_noms[reg]); libere_registre(f,reg); registre_force(f,REAX); reg=asm_sous_opcode(f,o->operandes.opegal.dest,r,arguments,lockeds); fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); libere_registre(f,reg); fprintf(f,"\tcall change_memoire\n"); libere_registre(f,REAX); libere_registre(f,REBX); break; } case WRITE: { if(o->operandes.opwrite.valeur->letype==CONSTANTE) { fprintf(f,"\tmov eax,%d\n",o->operandes.opwrite.valeur->operandes.valeur); } else { int reg=asm_sous_opcode(f,o->operandes.opwrite.valeur,r,arguments,lockeds); if(reg!=REG_EAX) fprintf(f,"\tmov eax,%s\n",registres_noms[reg]); libere_registre(f,reg); } switch(o->operandes.opwrite.nboctets) { case 1: fprintf(f,"\tstosb\n"); break; case 2: fprintf(f,"\tstosw\n"); break; case 4: fprintf(f,"\tstosd\n"); break; } break; } case CONDITIONIF: { int lfin=get_label(); int taille_if=minimum_taille(&o->operandes.opif.codeif,50000,0); fprintf(f,"\tadd edx,%d\n",taille_if); int reg=asm_sous_opcode(f,o->operandes.opif.condition,r,arguments,lockeds); fprintf(f,"\ttest %s,%s\n",registres_noms[reg],registres_noms[reg]); libere_registre(f,reg); fprintf(f,"\tjz goto_%d\n",lfin); fprintf(f,"\tsub edx,%d\n",taille_if); cellule* co=ll_front(&o->operandes.opif.codeif); while(co!=NULL) { Opcode* o2=(Opcode*)co->valeur; asm_opcode(f,o2,r,arguments,lockeds); co=ll_next(&o->operandes.opif.codeif,co); } fprintf(f,"goto_%d:\n",lfin); break; } case CONDITIONIFELSE: { int lelse=get_label(),lfin=get_label(); int taille_if=minimum_taille(&o->operandes.opif.codeif,50000,0); int taille_else=minimum_taille(&o->operandes.opif.codeelse,50000,0); int taille_max=taille_if>taille_else?taille_if:taille_else; int reg=asm_sous_opcode(f,o->operandes.opif.condition,r,arguments,lockeds); fprintf(f,"\ttest %s,%s\n",registres_noms[reg],registres_noms[reg]); libere_registre(f,reg); fprintf(f,"\tjz goto_%d\n",lelse); if(taille_if<taille_max) fprintf(f,"\tadd edx,%d\n",taille_max-taille_if); cellule* co=ll_front(&o->operandes.opif.codeif); while(co!=NULL) { Opcode* o2=(Opcode*)co->valeur; asm_opcode(f,o2,r,arguments,lockeds); co=ll_next(&o->operandes.opif.codeif,co); } fprintf(f,"\tjmp goto_%d\n",lfin); fprintf(f,"goto_%d:\n",lelse); if(taille_else<taille_max) fprintf(f,"\tadd edx,%d\n",taille_max-taille_else); co=ll_front(&o->operandes.opif.codeelse); while(co!=NULL) { Opcode* o2=(Opcode*)co->valeur; asm_opcode(f,o2,r,arguments,lockeds); co=ll_next(&o->operandes.opif.codeelse,co); } fprintf(f,"goto_%d:\n",lfin); break; } } }