int fct_lb(inst k, mem memory, registre* reg) { int tmp; uint32_t base = k.i.rs; uint32_t offset = k.i.imm; uint32_t addr = reg[base].val + (signed) offset; uint32_t value; if (addr<memory->start_mem) ERROR_MSG("La memoire commence en 0x%08x",memory->start_mem); if (addr>STOP_MEM) ERROR_MSG("La memoire termine en 0x%08x",STOP_MEM); tmp = find_word(memory, addr, &value); if (tmp==cmd_unknown) { printf("\n"); ERROR_MSG("L'adresse 0x%08x n'est pas allouee", addr); return cmd_unknown; } else { value = (signed) value; value = FLIP_ENDIANNESS(value); if (addr%4==0) reg[k.i.rt].val = value&0x000000ff; else if (addr%4==1) reg[k.i.rt].val=(value&0x0000ff00)>>8; else if (addr%4==2) reg[k.i.rt].val=(value&0x00ff0000)>>16; else if (addr%4==3) reg[k.i.rt].val=(value&0xff000000)>>24;
void print_segment_raw_content(segment* seg) { int k; int word =0; if (seg!=NULL && seg->size._32>0) { /* on vérifie que le segment n'est pas vide */ for(k=0; k<seg->size._32; k+=4) { /* on lit chaque donnée présente dans le segment à afficher */ if(k%16==0) printf("\n 0x%08x ",k); /* affiche l'adresse lue chaque multiple de 16 et retourne à la ligne à la fin d'un octet */ word = *((unsigned int *) (seg->content+k)); FLIP_ENDIANNESS(word); printf("%08x ", word); /* affiche chaque octet d'un segment */ } } }
void print_segment_raw_content(segment* seg) { //Affiche un segment donne int k; int word =0; if (seg!=NULL && seg->size._32>0) { for(k=0; k<seg->size._32; k+=4) { if(k%16==0) printf("\n 0x%08x ",k); word = *((unsigned int *) (seg->content+k)); FLIP_ENDIANNESS(word); printf("%08x ", word); } } }
/** * @param fp le fichier elf original * @param seg le segment a reloger * @param mem l'ensemble des segments * @param endianness le boutisme du programme * @param symtab la table des symbole du programme * @param symtab_libc la table des symbole de la libc (NULL si inutile) * @param fp_libc le fichier elf de la libc (NULL si inutile) * @brief Cette fonction effectue la relocation du segment passe en parametres * @brief l'ensemble des segments doit deja avoir ete charge en memoire. * * VOUS DEVEZ COMPLETER CETTE FONCTION POUR METTRE EN OEUVRE LA RELOCATION !! */ void reloc_segment(FILE* fp, segment seg, mem memory,unsigned int endianness,stab* symtable,stab* symtab_libc,FILE* fp_libc) { byte *ehdr = __elf_get_ehdr( fp ); uint32_t scnsz = 0; Elf32_Rel *rel = NULL; char* reloc_name = malloc(strlen(seg.name)+strlen(RELOC_PREFIX_STR)+1); scntab section_tab; scntab section_tab_libc; // on recompose le nom de la section memcpy(reloc_name,RELOC_PREFIX_STR,strlen(RELOC_PREFIX_STR)+1); strcat(reloc_name,seg.name); // on recupere le tableau de relocation et la table des sections rel = (Elf32_Rel *)elf_extract_scn_by_name( ehdr, fp, reloc_name, &scnsz, NULL ); elf_load_scntab(fp ,32, §ion_tab); if (symtab_libc!=NULL && fp_libc!=NULL) elf_load_scntab(fp_libc ,32, §ion_tab_libc); if (rel != NULL &&seg.content!=NULL && seg.size._32!=0) { if(verbose>0) { INFO_MSG("--------------Relocation of %s-------------------\n",seg.name) ; INFO_MSG("Number of symbol to relocate: %ld\n",scnsz/sizeof(*rel)) ; } //------------------------------------------------------ int i=0; uint sym; uint type; uint info; uint offset; //display : if(verbose>0) { //printf("scnsz=%d\n", scnsz); //print_scntab(section_tab); printf("Offset Info Type Sym.Value Sym.Name\n"); while(i<scnsz/sizeof(*rel)) { info=rel[i].r_info; offset=rel[i].r_offset; FLIP_ENDIANNESS(info) ; FLIP_ENDIANNESS(offset) ; sym=ELF32_R_SYM(info); type=ELF32_R_TYPE(info); if (type>32) { WARNING_MSG("Unknown type : %d",type); } else { printf("%08X %08X %-14s %08X %s\n",offset,info,MIPS32_REL[type],sym,(*symtable).sym[sym].name); i++; } } } i=0; //------------------------------------------------------ //Reloc : int A,V,P; //int segnum; uint32_t S; while(i<scnsz/sizeof(*rel)) { info=rel[i].r_info; offset=rel[i].r_offset; FLIP_ENDIANNESS(info) ; FLIP_ENDIANNESS(offset) ; sym=ELF32_R_SYM(info); type=ELF32_R_TYPE(info); //printf("Relocating symbol %d\n",i ); //segnum=seg_from_scnidx((*symtable).sym[sym].scnidx,(*symtable),memory); //if(segnum==-1){ // WARNING_MSG("Couldn't resolve scndix correspondance"); // break; //} //S=memory->seg[segnum].start._32+(*symtable).sym[sym].addr._32;//a verif //printf("sym=%d, symbtable size=%d\n", sym,(*symtable).size); if(addr_from_symnb(sym, (*symtable), memory,&S)==-1) { WARNING_MSG("Trying to resolve scndix correspondance in libcsymtab"); } P=seg.start._32+offset; memRead(P,1,&A); //printf("Relocation type %s\n",MIPS32_REL[type] ); switch (type) { case 2: V=S+A; //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P); memWrite(P,1,V); break; case 4: V=(A&0xFC00000)|((((A<<2)|((P&0xF0000000)+S))>>2)&0x3FFFFFF); //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P); memWrite(P,1,V); break; case 5: ; uint nexttype=rel[i+1].r_info; uint nextoffset=rel[i+1].r_offset; FLIP_ENDIANNESS(nexttype); FLIP_ENDIANNESS(nextoffset); nexttype=ELF32_R_TYPE(nexttype); if(nexttype!=6) { WARNING_MSG("R_MIPS_HI16 not followed by R_MIIPS_LO16 : %s",MIPS32_REL[nexttype]); } else { int P2=seg.start._32+nextoffset,A2; memRead(P2,1,&A2); int AHL; AHL=(A<<16)+(short)(A2); //printf("A2=%X short A2=%X\n",A2, (short)A2 ); //printf("AHL : %X\n",AHL ); //printf("Total=%X AHL+S=%X, (AHL+S)&0xFFFF=%X, diff=%X\n",((AHL+S-(short)(AHL+S))>>16),AHL+S,(AHL+S)&0xFFFF,AHL+S-(short)AHL+S) ; V=(A & 0xFFFF0000)|( ((AHL+S-(short)(AHL+S))>>16) &0xFFFF); //printf("V= %X,S=%X,A=%X,A2=%X,P=%X,P2=%X, AHL=%X\n",V,S,A,A2,P,P2,AHL); memWrite(P,1,V); } break; case 6: ; int previoustype=rel[i-1].r_info; int previousoffset=rel[i-1].r_offset; FLIP_ENDIANNESS(previoustype); FLIP_ENDIANNESS(previousoffset); previoustype=ELF32_R_TYPE(previoustype); if(previoustype!=5) { WARNING_MSG("R_MIPS_LO16 not preceded by R_MIPS_HI16 : %s",MIPS32_REL[previoustype]); } else { int32_t P2=seg.start._32+previousoffset,A2; memRead(P2,1,&A2); int32_t AHL=(A2<<16)+(short)(A); V=(A&0xFFFF0000)|((short)(AHL+S)&0xFFFF); //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P); memWrite(P,1,V); } break; default: if (type>32) { WARNING_MSG("Unknown type : %d, relocation impossible for element %d",type,i); } else { WARNING_MSG("Unknown type : %s(code : %d), relocation impossible for element %d",MIPS32_REL[type],type,i); } break; } i++; } //------------------------------------------------------ } del_scntab(section_tab); free( rel ); free( reloc_name ); free( ehdr ); }