mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-01-15 00:56:39 +00:00
dd21cff146
Remove .C suffix on non-executable binary files.
288 lines
6.5 KiB
HolyC
Executable file
288 lines
6.5 KiB
HolyC
Executable file
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_GLOBAL_VAR)
|
|
i = tmpex(CHashGlobalVar *)->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, count, 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
|
|
{
|
|
count = i;
|
|
for (j = 0; j < count; 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);
|
|
}
|
|
count = i;
|
|
for (j = 0; j < count; 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);
|
|
}
|
|
count = i;
|
|
for (j = 0; j < count; 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
CZXE *Load(U8 *filename, I64 ld_flags=0, CZXE *zxe_addr=INVALID_PTR)
|
|
{//Load a .ZXE file module into memory.
|
|
//zxe_addr==INVALID_PTR means don't care what load address.
|
|
U8 *fbuf, *module_base, *absname;
|
|
I64 size, module_align, misalignment;
|
|
CZXE *zxe;
|
|
|
|
fbuf = ExtDefault(filename, "ZXE");
|
|
if (!(zxe = FileRead(fbuf, &size)))
|
|
{
|
|
Free(fbuf);
|
|
return NULL;
|
|
}
|
|
|
|
//See $LK,"Patch Table Generation",A="FF:::/Compiler/CMain.ZC,IET_ABS_ADDR"$
|
|
module_align = 1 << zxe->module_align_bits;
|
|
if (!module_align || zxe->signature != ZXE_SIGNATURE_VAL)
|
|
{
|
|
Free(zxe);
|
|
Free(fbuf);
|
|
throw('ZXEModul');
|
|
}
|
|
|
|
if (zxe_addr == INVALID_PTR)
|
|
{
|
|
if (zxe->org == INVALID_PTR)
|
|
{
|
|
misalignment = module_align - sizeof(CZXE);
|
|
if (misalignment < 0)
|
|
misalignment &= module_align - 1;
|
|
if (Fs->code_heap != Fs->data_heap)
|
|
{
|
|
if (module_align < 16)
|
|
module_align = 16;
|
|
zxe_addr = MAllocAligned(size, module_align, Fs->code_heap, misalignment);
|
|
}
|
|
else if (module_align > 8)
|
|
zxe_addr = MAllocAligned(size, module_align,, misalignment);
|
|
else
|
|
{//Less than 2Gig system memory
|
|
zxe_addr = zxe;
|
|
goto lo_skip; //File is already in code heap area, don't copy.
|
|
}
|
|
}
|
|
else
|
|
zxe_addr = zxe->org;
|
|
}
|
|
MemCopy(zxe_addr, zxe, size);
|
|
Free(zxe);
|
|
|
|
lo_skip:
|
|
module_base = zxe_addr(U8 *) + sizeof(CZXE);
|
|
|
|
absname = FileNameAbs(fbuf);
|
|
Free(fbuf);
|
|
fbuf = StrNew(absname);
|
|
|
|
FileExtRemove(fbuf);
|
|
if (fbuf[1] == ':' && StrLen(fbuf) > 2)
|
|
HashGenericAdd(fbuf + 2, HTT_MODULE | HTF_PUBLIC, zxe_addr);
|
|
|
|
LoadPass1(zxe_addr(U8 *) + zxe_addr->patch_table_offset, module_base, ld_flags);
|
|
if (!(ld_flags & LDF_JUST_LOAD))
|
|
LoadPass2(zxe_addr(U8 *) + zxe_addr->patch_table_offset, module_base, ld_flags);
|
|
|
|
Free(absname);
|
|
Free(fbuf);
|
|
|
|
return zxe_addr;
|
|
}
|
|
|
|
U0 LoadKernel()
|
|
{
|
|
HashGenericAdd(KERNEL_MODULE_NAME, HTT_MODULE | HTF_PUBLIC, mem_boot_base - sizeof(CZXE));
|
|
|
|
//Abs patches done here $LK,"CPatchTableAbsAddr",A="FF:::/Kernel/KStart32.ZC,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);
|
|
}
|