--- alink.c Thu Dec 22 23:33:14 2005 +++ alink.c Sun Dec 25 22:29:22 2005 @@ -1457,9 +1457,9 @@ loadelf(afile); break; case LIBHDR: - //loadlib(afile,filename[i]); + loadlib(afile,filename[i]); //loadmod(afile); - loadcoff(afile); + //loadcoff(afile); break; case THEADR: case LHEADR: --- alink.h Thu Dec 22 23:33:14 2005 +++ alink.h Sun Dec 25 22:29:22 2005 @@ -542,6 +542,12 @@ USHORT st_shndx; } ELF32SYM, *PELF32SYM; +typedef struct __elf32rel +{ + ULONG r_offset; + ULONG r_info; +} ELF32REL, *PELF32REL; + #define ET_NONE 0 #define ET_REL 1 #define ET_EXEC 2 --- coff.c Thu Dec 22 23:33:12 2005 +++ coff.c Sun Dec 25 22:29:22 2005 @@ -50,7 +50,7 @@ return; } - if((thiscpu<0x14c) || (thiscpu>0x14e) && (thiscpu != 0x1f0)) + if(thiscpu!=0x14c && thiscpu!=0x1f0) { printf("Unsupported CPU type for module (type %x)\n", thiscpu); exit(1); @@ -738,7 +738,7 @@ exit(1); } - if(buf[0] || buf[1] || (buf[2]!=0xff) || (buf[3]|=0xff)) + if(buf[0] || buf[1] || (buf[2]!=0xff) || (buf[3]!=0xff)) { printf("Invalid Import entry\n"); exit(1); @@ -747,7 +747,7 @@ thiscpu=buf[6]+256*buf[7]; printf("Import CPU=%04X\n",thiscpu); - if((thiscpu<0x14c) || (thiscpu>0x14e) || (thiscpu != 0x1f0)) + if(thiscpu!=0x14c && thiscpu!=0x1f0) { printf("Unsupported CPU type for module (type %x)\n", thiscpu); exit(1); --- elf.c Thu Dec 22 23:33:14 2005 +++ elf.c Sun Dec 25 22:30:30 2005 @@ -147,6 +147,8 @@ ELF32HDR elf32hdr; PELF32SHDR elf32shdr; ELF32SYM elf32sym; + PELF32REL rel; + UINT relcount; int *stringListOffsets; int stringOffset = 0; @@ -279,7 +281,7 @@ { sym[j+numSymbols].name = checkStrdup - (stringList + stringListOffsets[elf32shdr[j].sh_link] + + (stringList + stringListOffsets[elf32hdr.e_shtrndx] + elf32shdr[j].sh_name); sym[j+numSymbols].value = elf32shdr[j].sh_addr; sym[j+numSymbols].section = j + 1; @@ -297,7 +299,15 @@ } else if(elf32shdr[i].sh_type == SHT_REL) { - + relcount=elf32shdr[i].sh_size/sizeof(ELF32REL); + rel=(PELF32REL)checkMalloc(elf32shdr[i].sh_size); + fseek(objfile,fileStart+elf32shdr[i].sh_offset,SEEK_SET); + if(fread(rel,1,elf32shdr[i].sh_size,objfile) + !=elf32shdr[i].sh_size) + { + printf("Invalid ELF object file\n"); + exit(1); + } } } @@ -392,10 +402,15 @@ for(i=0;i= elf32shdr[i].sh_offset && + rel[j].r_offset < elf32shdr[i].sh_offset + elf32shdr[i].sh_size) + { + if (numrel++ == 0) + relofs = j; + } + } seglist=(PPSEG)checkRealloc(seglist,(segcount+1)*sizeof(PSEG)); seglist[segcount]=(PSEG)checkMalloc(sizeof(SEG)); @@ -460,7 +484,7 @@ seglist[segcount]->attr=SEG_PUBLIC|SEG_USE32; seglist[segcount]->winFlags=WINF_ALIGN_DWORD | WINF_READABLE; - seglist[segcount]->base=elf32shdr[i].sh_addr; + seglist[segcount]->base=elf32shdr[i].sh_offset; if( elf32shdr[i].sh_flags & SHF_WRITE ) seglist[segcount]->winFlags |= WINF_WRITEABLE; @@ -643,31 +667,25 @@ seglist[segcount]->datmask=NULL; } - if(numrel) fseek(objfile,fileStart+relofs,SEEK_SET); + relocs=(PPRELOC)checkRealloc(relocs,(fixcount+numrel)*sizeof(PRELOC)); for(j=0;jofs=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24); - relocs[fixcount]->ofs-=relshift; + relocs[fixcount]->ofs=rel[j+relofs].r_offset; + //relocs[fixcount]->ofs-=elf32shdr[i].sh_offset; /* get segment */ relocs[fixcount]->segnum=i+minseg; - relocs[fixcount]->disp=0; + relocs[fixcount]->disp=4; /* get relocation target external index */ - relocs[fixcount]->target=buf[4]+(buf[5]<<8)+(buf[6]<<16)+(buf[7]<<24); + relocs[fixcount]->target=rel[j+relofs].r_info >> 8; if(relocs[fixcount]->target>=numSymbols) { - printf("Invalid COFF object file, undefined symbol\n"); + printf("Invalid ELF object file, undefined symbol\n"); exit(1); } k=relocs[fixcount]->target; - relocs[fixcount]->ttype=REL_EXTONLY; /* assume external reloc */ + relocs[fixcount]->ttype=REL_EXTDISP; /* assume external reloc */ if(sym[k].extnum<0) { switch(sym[k].class) @@ -675,6 +693,7 @@ case COFF_SYM_EXTERNAL: /* global symbols declare an extern when used in relocs */ externs=(PEXTREC)checkRealloc(externs,(extcount+1)*sizeof(EXTREC)); + printf("EXT: %s\n", sym[k].name); externs[extcount].name=(char *)sym[k].name; externs[extcount].pubdef=NULL; externs[extcount].modnum=0; @@ -740,7 +759,8 @@ exit(1); } } - if(relocs[fixcount]->ttype==REL_EXTONLY) + if(relocs[fixcount]->ttype==REL_EXTONLY || + relocs[fixcount]->ttype==REL_EXTDISP) { /* set relocation target to external if sym is external */ relocs[fixcount]->target=sym[k].extnum; @@ -750,30 +770,14 @@ relocs[fixcount]->ftype=REL_SEGFRAME; relocs[fixcount]->frame=i+minseg; /* set relocation type */ - switch(buf[8]+(buf[9]<<8)) + switch (rel[j+relofs].r_info & 0xff) { - case COFF_FIX_DIR32: - relocs[fixcount]->rtype=FIX_OFS32; - break; - - case COFF_PPC_REL32: - relocs[fixcount]->rtype=FIX_SELF_OFS32; - break; - - case COFF_FIX_RVA32: - relocs[fixcount]->rtype=FIX_RVA32; - break; -/* - case 0x0a: - - break; - case 0x0b: - break; -*/ - case COFF_FIX_REL32: + case 2: relocs[fixcount]->rtype=FIX_SELF_OFS32; + relocs[fixcount]->disp=4; break; default: - printf("unsupported COFF relocation type %04X\n",buf[8]+(buf[9]<<8)); + printf("Unsupported ELF relocation type (%x)\n", rel[j+relofs].r_info & 0xff); exit(1); } fixcount++; @@ -791,7 +795,7 @@ { break; } - if(sym[i].section==0) + if(sym[i].section==1) { if(sym[i].value) { @@ -850,4 +854,5 @@ if(symbolPtr && numSymbols) free(sym); if(stringList) free(stringList); + if(relocs) free(relocs); } --- objload.c Thu Dec 22 23:33:12 2005 +++ objload.c Sun Dec 25 22:29:22 2005 @@ -1315,7 +1315,7 @@ printf("Error reading from file\n"); exit(1); } - p->blocksize=(buf[1]+256*buf[2]) & ~15; + p->blocksize=buf[1]+256*buf[2]; if(fread(buf,1,p->blocksize,libfile)<1) { printf("Error reading from file\n"); --- output.c Thu Dec 22 23:33:12 2005 +++ output.c Sun Dec 25 22:29:22 2005 @@ -2450,8 +2450,8 @@ headbuf[headerStart+PE_SIGNATURE+1]=0x45; /* E */ headbuf[headerStart+PE_SIGNATURE+2]=0x00; /* 0 */ headbuf[headerStart+PE_SIGNATURE+3]=0x00; /* 0 */ - headbuf[headerStart+PE_MACHINEID]=PE_POWERPC&0xff; - headbuf[headerStart+PE_MACHINEID+1]=(PE_POWERPC>>8)&0xff; + headbuf[headerStart+PE_MACHINEID]=PE_INTEL386&0xff; + headbuf[headerStart+PE_MACHINEID+1]=(PE_INTEL386>>8)&0xff; /* store time/date of creation */ k=(UINT)time(NULL); headbuf[headerStart+PE_DATESTAMP]=k&0xff;