U0 LoadOneImport(U8 **_src,U8 *module_base,I64 ld_flags) { U8 *src=*_src,*ptr2,*st_ptr; I64 i,etype; CHashExport *tmpex=NULL; CHashImport *tmpiss; Bool first=TRUE; while (etype=*src++) { i=*src(U32 *)++; st_ptr=src; src+=StrLen(st_ptr)+1; if (*st_ptr) { if (!first) { *_src=st_ptr-5; return; } else { first=FALSE; if (!(tmpex=HashFind(st_ptr, Fs->hash_table,HTG_ALL-HTT_IMPORT_SYS_SYM))) { if (!(ld_flags & LDF_SILENT)) "Unresolved Reference:%s\n",st_ptr; tmpiss=CAlloc(sizeof(CHashImport)); tmpiss->str=StrNew(st_ptr); tmpiss->type=HTT_IMPORT_SYS_SYM; tmpiss->module_header_entry=st_ptr-5; tmpiss->module_base=module_base; HashAdd(tmpiss,Fs->hash_table); } } } if (tmpex) { ptr2=module_base+i; if (tmpex->type & HTT_FUN) i=tmpex(CHashFun *)->exe_addr; else if (tmpex->type & HTT_GLBL_VAR) i=tmpex(CHashGlblVar *)->data_addr; else i=tmpex->val; switch (etype) { case IET_REL_I8: *ptr2(U8 *) =i-ptr2-1; break; case IET_IMM_U8: *ptr2(U8 *) =i; break; case IET_REL_I16: *ptr2(U16 *)=i-ptr2-2; break; case IET_IMM_U16: *ptr2(U16 *)=i; break; case IET_REL_I32: *ptr2(U32 *)=i-ptr2-4; break; case IET_IMM_U32: *ptr2(U32 *)=i; break; case IET_REL_I64: *ptr2(I64 *)=i-ptr2-8; break; case IET_IMM_I64: *ptr2(I64 *)=i; break; } } } *_src=src-1; } U0 SysSymImportsResolve(U8 *st_ptr,I64 ld_flags) { CHashImport *tmpiss; U8 *ptr; while (tmpiss=HashSingleTableFind(st_ptr, Fs->hash_table,HTT_IMPORT_SYS_SYM)) { ptr=tmpiss->module_header_entry; LoadOneImport(&ptr,tmpiss->module_base,ld_flags); tmpiss->type=HTT_INVALID; } } U0 LoadPass1(U8 *src,U8 *module_base,I64 ld_flags) { U8 *ptr2,*ptr3,*st_ptr; I64 i,j,cnt,etype; CHashExport *tmpex=NULL; while (etype=*src++) { i=*src(U32 *)++; st_ptr=src; src+=StrLen(st_ptr)+1; switch (etype) { case IET_REL32_EXPORT: case IET_IMM32_EXPORT: case IET_REL64_EXPORT: case IET_IMM64_EXPORT: tmpex=CAlloc(sizeof(CHashExport)); tmpex->str=StrNew(st_ptr); tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM; if (etype==IET_IMM32_EXPORT||etype==IET_IMM64_EXPORT) tmpex->val=i; else tmpex->val=i+module_base; HashAdd(tmpex,Fs->hash_table); SysSymImportsResolve(st_ptr,ld_flags); break; case IET_REL_I0...IET_IMM_I64: src=st_ptr-5; LoadOneImport(&src,module_base,ld_flags); break; case IET_ABS_ADDR: if (ld_flags & LDF_NO_ABSS) src+=i*sizeof(U32); else { cnt=i; for (j=0; j<cnt; j++) { ptr2=module_base+*src(U32 *)++; *ptr2(U32 *)+=module_base; } } break; start: case IET_CODE_HEAP: ptr3=MAlloc(*src(I32 *)++,Fs->code_heap); break; case IET_ZEROED_CODE_HEAP: ptr3=CAlloc(*src(I32 *)++,Fs->code_heap); break; end: if (*st_ptr) { tmpex=CAlloc(sizeof(CHashExport)); tmpex->str=StrNew(st_ptr); tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM; tmpex->val=ptr3; HashAdd(tmpex,Fs->hash_table); } cnt=i; for (j=0; j<cnt; j++) { ptr2=module_base+*src(U32 *)++; *ptr2(I32 *)+=ptr3; } break; start: case IET_DATA_HEAP: ptr3=MAlloc(*src(I64 *)++); break; case IET_ZEROED_DATA_HEAP: ptr3=CAlloc(*src(I64 *)++); break; end: if (*st_ptr) { tmpex=CAlloc(sizeof(CHashExport)); tmpex->str=StrNew(st_ptr); tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM; tmpex->val=ptr3; HashAdd(tmpex,Fs->hash_table); } cnt=i; for (j=0; j<cnt; j++) { ptr2=module_base+*src(U32 *)++; *ptr2(I64 *)+=ptr3; } break; } } } U0 LoadPass2(U8 *src,U8 *module_base,I64) { U8 *st_ptr; I64 i,etype; while (etype=*src++) { i=*src(U32 *)++; st_ptr=src; src+=StrLen(st_ptr)+1; switch (etype) { case IET_MAIN: Call(i+module_base); break; case IET_ABS_ADDR: src+=sizeof(U32)*i; break; case IET_CODE_HEAP: case IET_ZEROED_CODE_HEAP: src+=4+sizeof(U32)*i; break; case IET_DATA_HEAP: case IET_ZEROED_DATA_HEAP: src+=8+sizeof(U32)*i; break; } } } CBinFile *Load(U8 *filename,I64 ld_flags=0,CBinFile *bfh_addr=INVALID_PTR) {//Load a .BIN file module into memory. //bfh_addr==INVALID_PTR means don't care what load addr. U8 *fbuf,*module_base,*absname; I64 size,module_align,misalignment; CBinFile *bfh; fbuf=ExtDft(filename,"BIN.Z"); if (!(bfh=FileRead(fbuf,&size))) { Free(fbuf); return NULL; } //See Patch Table Generation module_align=1<<bfh->module_align_bits; if (!module_align || bfh->bin_signature!=BIN_SIGNATURE_VAL) { Free(bfh); Free(fbuf); throw('BinModul'); } if (bfh_addr==INVALID_PTR) { if (bfh->org==INVALID_PTR) { misalignment=module_align-sizeof(CBinFile); if (misalignment<0) misalignment&=module_align-1; if (Fs->code_heap!=Fs->data_heap) { if (module_align<16) module_align=16; bfh_addr=MAllocAligned(size,module_align,Fs->code_heap,misalignment); } else if (module_align>8) bfh_addr=MAllocAligned(size,module_align,,misalignment); else //Less than 2Gig system memory { bfh_addr=bfh; goto lo_skip; //File is already in code heap area, don't copy. } } else bfh_addr=bfh->org; } MemCpy(bfh_addr,bfh,size); Free(bfh); lo_skip: module_base=bfh_addr(U8 *)+sizeof(CBinFile); absname=FileNameAbs(fbuf); Free(fbuf); fbuf=StrNew(absname); FileExtRem(fbuf); if (fbuf[1]==':' && StrLen(fbuf)>2) HashGenericAdd(fbuf+2,HTT_MODULE|HTF_PUBLIC,bfh_addr); LoadPass1(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags); if (!(ld_flags&LDF_JUST_LOAD)) LoadPass2(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags); Free(absname); Free(fbuf); return bfh_addr; } U0 LoadKernel() { HashGenericAdd(KERNEL_MODULE_NAME,HTT_MODULE|HTF_PUBLIC, mem_boot_base-sizeof(CBinFile)); //Abs patches done here CPatchTableAbsAddr. LoadPass1(sys_boot_patch_table_base,mem_boot_base,LDF_NO_ABSS|LDF_SILENT); //No main routines // LoadPass2(sys_boot_patch_table_base,mem_boot_base,0); }