Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1050 → Rev 1051

/shark/trunk/config/libdep.mk
493,3 → 493,17
LINK_LIB += -lmodules
LINK_DEP += $(LIB_PATH)/libmodules.a
endif
 
# DYNALINK (added by Lex N. 14:08 9-7-06)
# ----------------------------------------------------------------
ifeq ($(findstring __DYNALINK__, $(USELIB)), __DYNALINK__)
 
INCL += -I$(BASE)/ports/dynalink
 
# DYNALINK
ifeq ($(LIB_PATH)/libdynalink.a,$(wildcard $(LIB_PATH)/libdynalink.a))
LINK_LIB += -ldynalink
LINK_DEP += $(LIB_PATH)/libdynalink.a
endif
 
endif
/shark/trunk/config/config.mk
69,7 → 69,12
ASM_INC = $(INCL) $(OTHERINCL) -I$(OSLIB)
ASM_MAC = $(CFG_OPT)
 
# added for dynalink [lex]
ifndef DYNALINK
LINK_OPT = -Bstatic -Ttext $(MEM_START) -s -nostartfiles -nostdlib -L$(LIB_PATH) -L$(OSLIB_PATH)
else
LINK_OPT = -Bstatic
endif
 
C_OPT = $(C_DEF) $(C_WARN) $(C_INC) $(C_MAC) $(C_FLAGS)
C_OUTPUT = -o $*.o
/shark/trunk/ports/dynalink/dynalink.h
0,0 → 1,61
////////////////////////////////////////////////////////////////////////
// dynalink.h
//
// DynaLink for S.H.A.R.K
// Dynamic ELF object linker.
//
// Original code written by Luca Abeni.
// Adapted by Lex Nahumury 19-7-2006.
//
// This is free software; see GPL.txt
////////////////////////////////////////////////////////////////////////
#ifndef _DYNALINK_H_
#define _DYNALINK_H_
 
#define MAX_DYNA_MOD 64
 
struct mods_struct
{
void *mod_start;
void *mod_end;
char *string;
DWORD reserved;
};
 
 
struct app_module_info
{
unsigned int start; // the memory used goes from bytes 'mod_start'
unsigned int end; // to 'mod_end-1' inclusive
unsigned int size; // size in bytes
unsigned int dyn_entry; // main_module_entry() start address
char* name; // file name
};
 
struct dat_module_info
{
unsigned int start; // the memory used goes from bytes 'mod_start'
unsigned int end; // to 'mod_end-1' inclusive.
unsigned int size; // in bytes
char *name; // file name
};
 
struct dynalink_module_list
{
int num_apps; // number of loaded ELF objects
int num_dats; // number of loaded Data object
struct app_module_info app[MAX_DYNA_MOD]; // aplications in mem
struct dat_module_info dat[MAX_DYNA_MOD]; // data file in mem
};
 
 
int dynalink_modules( struct multiboot_info* mb,
struct dynalink_module_list* dml,
char* search_string);
 
 
 
#endif //_DYNALINK_H_
 
 
 
/shark/trunk/ports/dynalink/elf.c
0,0 → 1,708
////////////////////////////////////////////////////////////////////////
// elf.c
//
// DynaLink for S.H.A.R.K
// Dynamic ELF object linker.
//
// Original code written by Luca Abeni.
// Adapted by Lex Nahumury 19-7-2006.
//
// This is free software; see GPL.txt
////////////////////////////////////////////////////////////////////////
#include "kernel/kern.h"
#include <kernel/func.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
 
#include <ll/i386/hw-data.h>
#include <ll/i386/mem.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/ctype.h>
#include <ll/i386/x-bios.h>
 
#include "format.h"
#include "elf.h"
 
 
//#define __ELF_DEBUG__
 
char elf_signature[] = "\177ELF";
 
DWORD ELF_read_headers( struct file_ops *kf,
struct table_info *tables)
{
//printk("ELF_read_headers\n");
int res;
 
DWORD entry;
struct elf_header header;
struct elf_section_header h;
 
kf->file_seek(kf->file_offset + 0, kf->seek_set);
kf->file_read(&header, sizeof(struct elf_header));
if (memcmp(header.e_ident, elf_signature, 4)) {
printk("Not an ELF file\n");
printk("Wrong signature: 0x%lx)!!!\n",
*(DWORD *)header.e_ident);
return 0;
}
//printk("ELF signature OK\n");
 
tables->flags = 0;
if (header.e_ident[4] != ELFCLASS32) {
printk("Wrong ELF class\n");
printk("Class: 0x%x!!!\n", header.e_ident[4]);
return 0;
}
//printk("ELF Class OK\n");
 
if (header.e_ident[5] != ELFDATA2LSB) {
printk("Wrong data ordering (not LSB)\n");
printk("Ordering: 0x%x!!!\n", header.e_ident[5]);
return 0;
}
//printk("ELF data ordering OK\n");
 
#ifdef __ELF_DEBUG__
if(header.e_machine != EM_386)
{
printk("Warning: machine = 0x%x!!!\n", header.e_machine);
}
#endif
//printk("ELF Type: 0x%x\n", header.e_type);
 
if(header.e_shoff != 0)
{
#ifdef __ELF_DEBUG__
printk("Section headers @ %ld\n", header.e_shoff);
printk("Number of sections: %d\n", header.e_shnum);
printk("Section header size: %d (0x%x)\n",
header.e_shentsize, header.e_shentsize);
#endif
tables->section_header = header.e_shoff;
tables->section_header_size = header.e_shentsize;
tables->num_sections = header.e_shnum;
}
 
#ifdef __ELF_DEBUG__
if (header.e_phoff != 0) {
printk("Program header table @ %ld\n", header.e_phoff);
printk("Number of segments: %d\n", header.e_phnum);
printk("Segment header size: %d (0x%x)\n",
header.e_phentsize, header.e_phentsize);
}
 
 
#ifdef __ELF_DEBUG__
/* Flags... */
/* RELOCATION */
if (header.f_flags & F_RELFLG) {
printk("No relocation info!\n");
}
if (header.f_flags & F_EXEC) {
printk("Executable file (no unresolved symbols)\n");
}
 
if (header.f_flags & F_LNNO) {
printk("No line numbers!\n");
}
 
if (header.f_flags & F_LSYMS) {
printk("No local symbols!\n");
}
 
if (header.f_flags & F_AR32WR) {
printk("32-bit little endian!\n");
} else {
printk("File type?\n");
}
#endif
 
printk("Section Name String Table is section number %d\n",
header.e_shstrndx);
#endif
if (header.e_shstrndx > tables->num_sections)
{
printk("Error: SNST number > section number...\n");
return 0;
}
res = kf->file_seek( kf->file_offset + tables->section_header +
header.e_shstrndx * tables->section_header_size,
kf->seek_set);
if (res < 0) {
printk("Cannot seek");
return 0;
}
//printk("ELF file seek OK\n");
res = kf->file_read( &h, sizeof(struct elf_section_header));
if (res < 0) {
printk("Cannot read");
return 0;
}
//printk("ELF file read OK\n");
 
tables->section_names = 0;
if(h.sh_size != 0)
{
//printk("ELF Loading Section Names...\n");
 
tables->section_names = (void *)malloc(h.sh_size);
if (tables->section_names == NULL)
{
printk("Failed to allocate space for section names...\n");
return 0;
}
 
res = kf->file_seek( kf->file_offset + h.sh_offset, kf->seek_set);
if (res < 0) {
printk("Cannot seek");
return 0;
}
res = kf->file_read( tables->section_names, h.sh_size);
if (res < 0) {
printk("Cannot read");
return 0;
}
tables->section_names_size = h.sh_size;
}
else
{
printk("0 size?\n");
tables->section_names_size = 0;
}
 
entry = header.e_entry;
if (entry == 0) {
tables->flags |= NO_ENTRY;
tables->flags |= NEED_LOAD_RELOCATABLE;
tables->flags |= NEED_SECTION_RELOCATION;
}
//printk("ELF Read headers Done!\n");
return entry;
};
 
 
int ELF_read_section_headers(struct file_ops *kf,
struct table_info *tables,
struct section_info *scndata)
{
int bss = -1;
int i, j;
struct elf_section_header h;
int header_size;
int stringtable = -1;
struct elf_rel_info r;
 
header_size = tables->section_header_size;
if(header_size > sizeof(struct elf_section_header))
{
printk("Section header size (%d) > sizeof(struct section_header) (%d)\n",
header_size, (int)(sizeof(struct elf_section_header)) );
header_size = sizeof(struct elf_section_header);
}
for (i = 0; i < tables->num_sections; i++)
{
kf->file_seek( kf->file_offset + tables->section_header +
i * tables->section_header_size, kf->seek_set);
kf->file_read( &h, sizeof(struct elf_section_header));
 
#ifdef __ELF_DEBUG__
printk("Section %d: ", i);
printk("Flags 0x%x: \n", h.sh_flags);
#endif
/*
Set this stuff to 0...
If size == 0 the section must not be loaded
*/
scndata[i].num_reloc = 0;
scndata[i].base = 0;
scndata[i].size = 0;
scndata[i].fileptr = 0;
scndata[i].filesize = 0;
 
/* If this is a NULL section, skip it!!! */
if (h.sh_type != SHT_NULL) {
if (tables->section_names != 0) {
#ifdef __ELF_DEBUG__
printk("[%s]", tables->section_names + h.sh_name);
#endif
if (strcmp(tables->section_names + h.sh_name, ".bss") == 0) {
bss = i;
}
}
#ifdef __ELF_DEBUG__
printk(" <0x%lx:0x%lx> (0x%lx)\n",
h.sh_addr,
h.sh_addr + h.sh_size,
h.sh_offset);
#endif
 
if (h.sh_type == SHT_REL) {
#ifdef __ELF_DEBUG__
printk("\t\tSection %d: relocation info!!!\n", i);
printk("\t\tSymbol table: section number %lu\n", h.sh_link);
printk("\t\tSection to modify: %lu\n", h.sh_info);
printk("\t\tNumber of relocation entries: %lu\n",
h.sh_size / h.sh_entsize);
#endif
if (scndata[h.sh_info].num_reloc != 0) {
printk("Double relocation for section\n");
printk("%lu?\n", h.sh_info);
return 0;
}
/* So, ...let's load it!!! */
scndata[h.sh_info].num_reloc = h.sh_size / h.sh_entsize;
//scndata[h.sh_info].reloc = (void *)kf->mem_alloc((h.sh_size / h.sh_entsize) * sizeof(struct reloc_info));
scndata[h.sh_info].reloc = (void *)malloc((h.sh_size / h.sh_entsize) * sizeof(struct reloc_info));
if (scndata[h.sh_info].reloc == NULL) {
printk("Failed to allocate space for relocation info...\n");
return 0;
}
//printk("ELF Allocate space for relocation info OK!\n");
for (j = 0; j < h.sh_size / h.sh_entsize; j++) {
kf->file_seek( kf->file_offset + h.sh_offset + j * h.sh_entsize,
kf->seek_set);
kf->file_read( &r, sizeof(struct elf_rel_info));
scndata[h.sh_info].reloc[j].offset = r.r_offset;
scndata[h.sh_info].reloc[j].symbol = r.r_info >> 8;
/* HACKME!!! Unify the relocation types... */
scndata[h.sh_info].reloc[j].type = (BYTE)r.r_info;
if ((BYTE)r.r_info == R_386_32){
scndata[h.sh_info].reloc[j].type = REL_TYPE_ELF_ABSOLUTE;
} else if ((BYTE)r.r_info == R_386_PC32) {
scndata[h.sh_info].reloc[j].type = REL_TYPE_RELATIVE;
}
}
} else if (h.sh_type == SHT_RELA) {
printk("Error: unsupported relocation section!!!\n");
 
return 0;
} else if ((h.sh_type == SHT_SYMTAB) || (h.sh_type == SHT_DYNSYM)) {
#ifdef __ELF_DEBUG__
printk("\t\tSection %d: symbol table!!!\n", i);
printk("\t\tString table: section number %lu\n", h.sh_link);
printk("\t\tLast local Symbol + 1: %lu\n", h.sh_info);
#endif
tables->symbol = h.sh_offset;
tables->num_symbols = h.sh_size / h.sh_entsize;
tables->symbol_size = h.sh_size;
if (stringtable != -1) {
printk("Error: double string table!!!\n");
return 0;
}
stringtable = h.sh_link;
if (stringtable < i) {
printk("Strange... ");
printk("String table (%d) < Symbol Table\n", stringtable);
return 0;
}
} else if (i == stringtable) {
#ifdef __ELF_DEBUG__
printk("\t\t Section %d: string table!!!\n", i);
#endif
tables->string = h.sh_offset;
tables->string_size = h.sh_size;
stringtable = -1;
} else {
scndata[i].base = h.sh_addr;
scndata[i].size = h.sh_size;
scndata[i].fileptr = h.sh_offset;
if (h.sh_type != SHT_NOBITS) {
#ifdef __ELF_DEBUG__
printk("BSS?\n");
#endif
scndata[i].filesize = h.sh_size;
}
}
} else {
#ifdef __ELF_DEBUG__
printk("NULL Section\n");
#endif
}
 
#if 0
if (h.s_flags & SECT_TEXT) {
printk("Executable section\n");
}
if (h.s_flags & SECT_INIT_DATA) {
printk("Data section\n");
}
if (h.s_flags & SECT_UNINIT_DATA) {
printk("BSS section\n");
scndata[i].filesize = 0;
}
#endif
}
tables->image_base = scndata[0].base;
return bss;
};
 
 
int ELF_read_symbols(struct file_ops *kf,
struct table_info *tables,
struct symbol_info *syms)
{
//printk("ELF read_symbols\n");
int i;
int entsize;
struct elf_symbol_info symbol;
char *s;
 
s = (void *)malloc(tables->string_size);
if(s == NULL)
{
printk("Failed to allocate space for string table...\n");
return 0;
}
tables->string_buffer = (DWORD)s;
kf->file_seek( kf->file_offset + tables->string, kf->seek_set);
kf->file_read( s, tables->string_size);
entsize = tables->symbol_size / tables->num_symbols;
 
for (i = 0; i < tables->num_symbols; i++)
{
kf->file_seek( kf->file_offset + tables->symbol + i * entsize,
kf->seek_set);
kf->file_read( &symbol, sizeof(struct elf_symbol_info));
syms[i].name = s + symbol.st_name;
syms[i].section = symbol.st_shndx;
syms[i].offset = symbol.st_value;
 
if (syms[i].section == SHN_UNDEF) {
/* extern symbol */
if (symbol.st_name != 0)
syms[i].section = EXTERN_SYMBOL;
else /* Mark the empty entry, external symbol with no name is not used :-) */
syms[i].section = NULL_SYMBOL;
}
if (syms[i].section == SHN_COMMON) {
/* extern symbol */
syms[i].section = COMMON_SYMBOL;
syms[i].offset = symbol.st_size;
/* calculate the local_bss_size */
tables->local_bss_size += syms[i].offset;
}
}
 
return 1;
};
 
int Elf_check(struct file_ops *kf)
{
char signature[4];
 
kf->file_offset = kf->file_seek( 0, kf->seek_cur);
kf->file_read(signature, 4);
kf->file_seek( kf->file_offset + 0, kf->seek_set);
 
if(memcmp(signature, elf_signature, 4))
{
return 0;
}
return 1;
};
 
int ELF_relocate_section(struct file_ops *kf,
DWORD base,
struct table_info *tables,
int n,
struct section_info *s,
int sect,
struct symbol_info *syms,
struct symbol *import)
{
int i, idx;
DWORD address, destination;
int j, done;
DWORD local_bss = tables->local_bss;
struct reloc_info *rel = s[sect].reloc;
 
/* Setup the common space-uninitialized symbols at the first section relocation
* Pre-calculate the local BSS size (in read_symbols)
* then allocate for each symbol (in load_relocatable)
*/
if(sect == 0)
{
for(i=0; i<tables->num_symbols; i++)
{
if(syms[i].section == COMMON_SYMBOL)
{
j = syms[i].offset;
syms[i].offset = local_bss;
local_bss += j;
}
else if(syms[i].section == EXTERN_SYMBOL)
{
#ifdef __ELF_DEBUG__
printk("Searching for symbol %s\n", syms[i].name);
#endif
/* Pre-set the external symbol at the same time */
for(j=0, done=0; import[j].name != 0; j++)
{
if(strcmp(import[j].name, syms[i].name) == 0)
{
syms[i].offset = import[j].address;
done = 1;
break;
}
}
if(done == 0)
{
printk("Symbol %s not found\n", syms[i].name);
return -1;
}
}
}
}
 
//printk("[COMMON] s[sect].num_reloc = %d\n", s[sect].num_reloc);
for(i=0; i < s[sect].num_reloc; i++)
{
#ifdef __COFF_DEBUG__
printk("Relocate 0x%lx (index 0x%x): mode %d ",
rel[i].offset, rel[i].symbol, rel[i].type);
#endif
idx = rel[i].symbol;
 
#ifdef __COFF_DEBUG__
printk("%s --> 0x%lx (section %d)\n", syms[idx].name,
syms[idx].offset, syms[idx].section);
#endif
 
switch (rel[i].type)
{
case REL_TYPE_ELF_ABSOLUTE:
destination = s[sect].base + rel[i].offset + base;
// Initial address
address = *((DWORD*)destination);
break;
case REL_TYPE_RELATIVE:
destination = s[sect].base + rel[i].offset + base;
address = 0;
break;
default:
// (Non-)external symbols: only REL32 is supported
printk("Unsupported relocation!\n");
printk("Relocation Type: %d\n", rel[i].type);
return -1;
}
if(syms[idx].section == COMMON_SYMBOL || syms[idx].section == EXTERN_SYMBOL)
{
if(rel[i].type == REL_TYPE_ELF_ABSOLUTE)
address += syms[idx].offset;
else if(rel[i].type == REL_TYPE_RELATIVE)
address = syms[idx].offset - destination - 4;
}
else if(syms[idx].section >= n)
{
// Check if the section exists ...
printk("Unsupported relocation section\n");
printk("Section %d > %d\n", syms[idx].section, n);
printk("Value 0x%lx\n", syms[idx].offset);
return -1;
}
else
{
if(rel[i].type == REL_TYPE_ELF_ABSOLUTE)
{
address += base + s[syms[idx].section].base + syms[idx].offset;
}
else if(rel[i].type == REL_TYPE_RELATIVE)
{
address = (s[syms[idx].section].base + syms[idx].offset) - (s[sect].base + rel[i].offset) - 4;
#ifdef __COFF_DEBUG__
printk("Reloc: 0x%lx + 0x%lx - 0x%lx = 0x%lx ",
syms[idx].offset,
s[syms[idx].section].base,
rel[i].offset , address);
#endif
}
}
#ifdef __COFF_DEBUG__
printk("0x%lx <--- 0x%lx\n", destination, address);
#endif
*((DWORD*)destination) = address;
}
 
return 1;
};
 
 
/* Import symbol with suffix `name'
* NOTE: Any symbol with prefix `_' won't be found and be regarded as internal and hidden
*/
DWORD ELF_import_symbol(struct file_ops *kf,
int n,
struct symbol_info *syms,
char *name,
int *sect)
{
//printk("[COMMON] import_symbol...\n");
int i;
int len = strlen(name);
 
for(i = 0; i < n ; i++)
{
#ifdef __COFF_DEBUG__
printk("Checking symbol %d [%d] --- Sect %d\n", i, n, syms[i].section);
#endif
if ((syms[i].section != EXTERN_SYMBOL) && (syms[i].section != COMMON_SYMBOL) && (syms[i].section != NULL_SYMBOL))
{
#ifdef __COFF_DEBUG__
printk("Compare %s, %s\n", syms[i].name, name);
#endif
if(syms[i].name[0] != '_')
{
int sym_len = strlen(syms[i].name);
if(sym_len >= len && strcmp(syms[i].name+sym_len-len, name) == 0)
{
#ifdef __COFF_DEBUG__
printk("Found: %s --- 0x%x : 0x%lx\n",
syms[i].name, syms[i].section, syms[i].offset);
#endif
break;
}
#ifdef __COFF_DEBUG__
else
{
printk("Cmp failed --- Going to %d\n", i);
}
#endif
}
}
#ifdef __COFF_DEBUG__
else
{
printk("Skipped symbol --- Going to %d\n", i);
}
#endif
}
 
if(i < n)
{ /* Symbol found */
*sect = syms[i].section;
return syms[i].offset;
}
else
{
*sect = -1;
printk("Symbol not found!!!\n");
return 0;
}
};
 
 
DWORD ELF_load_relocatable( struct file_ops *kf,
struct table_info *tables,
int n,
struct section_info *s,
DWORD *size)
{
int i;
DWORD needed_mem = 0;
DWORD local_offset = 0;
BYTE *mem_space, *where_to_place;
 
// Allocate for the local bss at the mean time
for(i=0; i<n; i++)
{
needed_mem += s[i].size;
}
needed_mem += tables->local_bss_size;
mem_space = (BYTE *)malloc(needed_mem);
if(mem_space == NULL)
{
printk("Unable to allocate memory for the program image\n");
return 0;
}
memset(mem_space, 0, needed_mem);
 
#ifdef __ELF_DEBUG__
printk("Loading relocatable @%p; size 0x%lx\n", mem_space, needed_mem);
#endif
 
if(tables->local_bss_size != 0)
tables->local_bss = (DWORD)mem_space + needed_mem - tables->local_bss_size;
else
tables->local_bss = 0;
 
 
for(i=0; i<n; i++)
{
#ifdef __ELF_DEBUG__
printk("Section %d\t", i);
#endif
if(s[i].size != 0)
{
#ifdef __ELF_DEBUG__
printk("Loading @ 0x%lx (0x%lx + 0x%lx)...\n",
(DWORD)mem_space + (DWORD)local_offset,
(DWORD)mem_space, local_offset);
#endif
where_to_place = mem_space + local_offset;
s[i].base = local_offset;
local_offset += s[i].size;
kf->file_seek( kf->file_offset + s[i].fileptr, kf->seek_set);
if(s[i].filesize > 0)
{
kf->file_read( where_to_place, s[i].filesize);
}
}
else
{
#ifdef __ELF_DEBUG__
printk("Not to be loaded\n");
#endif
}
}
 
*size = needed_mem;
return (DWORD)mem_space;
};
 
 
void ELF_free_tables(struct file_ops *kf,
struct table_info *tables,
struct symbol_info *syms,
struct section_info *scndata)
{
int i;
 
for(i = 0; i < tables->num_sections; i++)
if (scndata[i].num_reloc != 0)
free( scndata[i].reloc);
 
free(scndata);
if (syms != NULL) free(syms);
if (tables->string_size != 0) free((DWORD*)tables->string_buffer);
if (tables->section_names_size != 0) free(tables->section_names);
};
 
/shark/trunk/ports/dynalink/dynalink.c
0,0 → 1,559
////////////////////////////////////////////////////////////////////////
// dynalink.c
//
// DynaLink for S.H.A.R.K
// Dynamic ELF object linker.
//
// Original code written by Luca Abeni.
// Adapted by Lex Nahumury 19-7-2006.
//
// This is free software; see GPL.txt
////////////////////////////////////////////////////////////////////////
#include "kernel/kern.h"
#include <kernel/func.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
 
#include <ll/i386/hw-data.h>
#include <ll/i386/mem.h>
#include <ll/i386/hw-instr.h>
#include <ll/i386/cons.h>
#include <ll/i386/error.h>
#include <ll/i386/mem.h>
#include <ll/ctype.h>
#include <ll/i386/x-bios.h>
 
#include "format.h"
#include "dynalink.h"
#include "elf.h"
 
#include <drivers/shark_linuxc26.h>
#include <drivers/shark_pci26.h>
#include <drivers/shark_input26.h>
#include <drivers/shark_keyb26.h>
 
// some shark pci forward declaration stuff (pci20to26.c)
extern int pci20to26_find_class(unsigned int class_code, int index, BYTE *bus, BYTE *dev);
extern int pci20to26_read_config_byte(unsigned int bus, unsigned int dev, int where, BYTE *val);
extern int pci20to26_read_config_word(unsigned int bus, unsigned int dev, int where, WORD *val);
extern int pci20to26_read_config_dword(unsigned int bus, unsigned int dev, int where, DWORD *val);
extern int pci20to26_write_config_byte(unsigned int bus, unsigned int dev, int where, BYTE val);
extern int pci20to26_write_config_word(unsigned int bus, unsigned int dev, int where, WORD val);
extern int pci20to26_write_config_dword(unsigned int bus, unsigned int dev, int where, DWORD val);
 
 
#define __DYNA_DEBUG__
#define NORMAL_PROCESS 0
#define EMPTY_SLOT {0, (DWORD)0xFFFFFFFF}
#define SUBSTITUTE 1
#define ADD 0
 
 
static struct file_ops kf;
static DWORD start;
static DWORD end;
static DWORD pointer;
 
 
//A module can also export symbols by adding them to the kernel symbol table
int add_call(char *name, DWORD address, int mode);
 
// forward declarations of some custom 'syscalls'...
extern void call_shutdown_task(void *arg);
extern DWORD get_tick();
 
static struct symbol syscall_table[] = {
// console & string
{ "cprintf", (DWORD)cprintf },
{ "sprintf", (DWORD)sprintf },
{ "printk", (DWORD)printk },
{ "printf_xy", (DWORD)printf_xy },
{ "puts_xy", (DWORD)puts_xy },
{ "place", (DWORD)place },
{ "_clear", (DWORD)_clear },
{ "clear", (DWORD)clear },
{ "strcpy", (DWORD)strcpy },
// keyboard
{ "keyb_getch", (DWORD)keyb_getch },
{ "keyb_getcode", (DWORD)keyb_getcode },
// math
{ "sin", (DWORD)sin },
{ "cos", (DWORD)cos },
{ "pow", (DWORD)pow },
{ "abs", (DWORD)abs },
// memory
{ "malloc", (DWORD)malloc },
{ "kern_alloc_aligned", (DWORD)kern_alloc_aligned },
{ "free", (DWORD)free },
// I/O
{ "inp", (DWORD)inp },
{ "inpw", (DWORD)inpw },
{ "inpd", (DWORD)inpd },
// pci
{ "pci20to26_read_config_byte", (DWORD)pci20to26_read_config_byte },
{ "pci20to26_read_config_word", (DWORD)pci20to26_read_config_word },
{ "pci20to26_read_config_dword", (DWORD)pci20to26_read_config_dword },
{ "pci20to26_write_config_byte", (DWORD)pci20to26_write_config_byte },
{ "pci20to26_write_config_word", (DWORD)pci20to26_write_config_word },
{ "pci20to26_write_config_dword", (DWORD)pci20to26_write_config_dword },
// task managment
{ "task_testcancel", (DWORD)task_testcancel },
{ "task_message", (DWORD)task_message },
{ "task_createn", (DWORD)task_createn },
{ "task_activate", (DWORD)task_activate },
{ "handler_set", (DWORD)handler_set },
{ "task_nopreempt", (DWORD)task_nopreempt },
{ "task_preempt", (DWORD)task_preempt },
{ "group_activate", (DWORD)group_activate },
// Time & termination
{ "sys_gettime", (DWORD)sys_gettime },
{ "get_tick", (DWORD)get_tick },
{ "perror", (DWORD)perror },
{ "exit", (DWORD)exit },
{ "call_shutdown_task", (DWORD)call_shutdown_task },
{ "sys_shutdown_message", (DWORD)sys_shutdown_message },
{ "add_call", (DWORD)add_call }, //module can add symbol to the kernel symbol table
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
EMPTY_SLOT,
{0, 0}
};
 
void *get_syscall_table(void)
{
return syscall_table;
};
 
int add_call(char *name, DWORD address, int mode)
{
int i;
int done;
int res;
i = 0;
done = 0;
while ((!done) && (syscall_table[i].address != 0)) {
if (!strcmp(syscall_table[i].name, name)) {
done = 1;
} else {
i++;
}
}
 
if (done == 1) {
if (mode == SUBSTITUTE) {
res = syscall_table[i].address;
syscall_table[i].name = name;
syscall_table[i].address = address;
} else {
return -1;
}
} else {
if (mode == SUBSTITUTE) {
return -1;
} else {
i = 0;
while (syscall_table[i].name != 0) {
i++;
}
if (syscall_table[i].address != 0xFFFFFFFF) {
return -1;
}
res = 1;
syscall_table[i].name = name;
syscall_table[i].address = address;
}
}
return res;
};
 
 
 
static DWORD load_process(struct file_ops *kf,
DWORD *ex_exec_space,
DWORD *image_base,
DWORD *ex_size)
{
#ifdef __EXEC_DEBUG__
DWORD offset;
#endif
DWORD size;
DWORD exec_space=0;
int bss_sect, i;
DWORD dyn_entry;
struct section_info *sections;
struct symbol_info *symbols = NULL;
struct table_info tables;
 
// Initialize the table info
tables.section_names_size = 0;
tables.local_bss_size = 0;
tables.private_info = 0;
 
// read ELF headers
dyn_entry = ELF_read_headers(kf, &tables);
 
sections = (struct section_info*)malloc(sizeof(struct section_info) * tables.num_sections);
if(sections == 0)
{
printk("Can't allocate the sections info!\n");
return -1;
}
 
// read ELF section headers
bss_sect = ELF_read_section_headers(kf, &tables, sections);
// Load symbols (if it's objects, calculate the local bss size)
if(tables.num_symbols != 0)
{
symbols = (struct symbol_info*)malloc(tables.num_symbols * sizeof (struct symbol_info));
if (symbols == 0)
{
error("Error allocating symbols table\n");
ELF_free_tables(kf, &tables, symbols, sections);
return -1;
}
// read ELF symbols
ELF_read_symbols(kf, &tables, symbols);
}
 
if(tables.flags & NEED_LOAD_RELOCATABLE)
{
#ifdef __EXEC_DEBUG__
printk("[EXEC]Must load_relocatable()!\n");
#endif
exec_space = ELF_load_relocatable(kf, &tables, tables.num_sections, sections, &size);
}
if(exec_space == 0)
{
printk("Error decoding the Executable data\n");
ELF_free_tables(kf, &tables, symbols, sections);
return -1;
}
 
if(tables.flags & (NEED_SECTION_RELOCATION|NEED_IMAGE_RELOCATION))
{
int res;
void *kernel_symbols;
int reloc_sections;
 
if (tables.flags & NEED_SECTION_RELOCATION)
{
if ((bss_sect < 0) || (bss_sect > tables.num_sections))
{
error("Error: strange file --- no BSS section\n");
/* TODO: Return code... */
ELF_free_tables(kf, &tables, symbols, sections);
free((DWORD*)exec_space);
return -1;
}
}
#ifdef __EXEC_DEBUG__
printk("[EXEC] Start of local BSS: 0x%lx\n", tables.private_info);
#endif
 
kernel_symbols = get_syscall_table();
if(tables.flags & NEED_SECTION_RELOCATION)
{
reloc_sections = tables.num_sections;
} else
{
reloc_sections = 1;
}
#ifdef __EXEC_DEBUG__
printk("[EXEC] reloc_sections = %d\n", reloc_sections);
#endif
// Relocate sections...
for (i=0; i<reloc_sections; i++)
{
res = ELF_relocate_section(kf,
exec_space,
&tables,
tables.num_sections,
sections,
i,
symbols,
kernel_symbols);
if(res < 0)
{
error("Error: relocation failed!!!\n");
/* TODO: Return code... */
ELF_free_tables(kf, &tables, symbols, sections);
free((DWORD*)exec_space);
return -1;
}
}
}
/* The size of the execution space */
*ex_size = size;
if(tables.flags & NO_ENTRY)
{
int init_sect;
/* No entry point... We assume that we need dynamic linking */
#ifdef __EXEC_DEBUG__
printk("[EXEC] Searching for the initialization function...\n");
#endif
if(symbols == 0)
{
error("Error: no symbols!!!\n");
/* TODO: Return code... */
ELF_free_tables(kf, &tables, symbols, sections);
free((DWORD*)exec_space);
return -1;
}
 
// Find the main entry point. Function name ends with kf->entry_name...
//dyn_entry = (DWORD)ELF_import_symbol(kf, tables.num_symbols, symbols, DYN_ENTRY_NAME, &init_sect);
dyn_entry = (DWORD)ELF_import_symbol(kf, tables.num_symbols, symbols, kf->entry_name, &init_sect);
if(init_sect != -1)
{
#ifdef __EXEC_DEBUG__
printk("Found: (%d = 0x%x) 0x%lx\n", init_sect,
init_sect, dyn_entry);
printk("Section Base: 0x%lx Exec Space: 0x%lx\n",
sections[init_sect].base, exec_space);
#endif
dyn_entry += sections[init_sect].base + exec_space;
*image_base = exec_space;
*ex_exec_space = 0;
ELF_free_tables(kf, &tables, symbols, sections);
return dyn_entry;
}
else
{
printk("WARNING: Initialization function not found!\n");
return -1;
}
}
return -1; // error
};
 
 
 
// Read an ELF object in memory, and return it's main entry function's address..
static DWORD get_exec_address( struct file_ops *kf )
{
DWORD exec_space;
DWORD image_base;
DWORD ex_size;
DWORD dyn_entry;
dyn_entry = load_process( kf,
&exec_space,
&image_base,
&ex_size);
 
if(dyn_entry== -1) return 0;
return dyn_entry;
};
 
/*
static char *module_command_line(DWORD mods_addr, int i)
{
struct mods_struct *curr_mod;
curr_mod = (struct mods_struct *)mods_addr;
return curr_mod[i].string;
};
 
static void module_address(DWORD mods_addr, int i, DWORD *start, DWORD *end)
{
struct mods_struct *curr_mod;
curr_mod = (struct mods_struct *)mods_addr;
*start = (DWORD)curr_mod[i].mod_start;
*end = (DWORD)curr_mod[i].mod_end;
};
*/
 
static int modfs_read( void *buff, int size)
{
int len = size;
if(pointer + len > end)
{
len = end - pointer;
}
memcpy(buff, (void *)pointer, len);
pointer += len;
return len;
};
 
 
static int modfs_seek( int pos, int wence)
{
int res;
 
if(wence == 0)
{
res = pos;
}
else if(wence == 1)
{
res = pointer + pos - start;
}
else if(wence == 2)
{
if(end - start < pos) res = 0;
else res = end - start - pos;
}
else res = pointer - start;
 
if(start + res > end) res = end - start;
pointer = start + res;
return res;
};
 
// This will process all modules and fill out a dynalink_module_list.
// We only support valid ELF objects.
// Everything else is treated as DATA.
int dynalink_modules(struct multiboot_info* mb,
struct dynalink_module_list* dml,
char* search_string)
{
int i;
DWORD dyn_entry;
int mods_addr = mb->mods_addr;
int mods_count = mb->mods_count;
// Initialize the Modules Pseudo-FS...
kf.file_seek = modfs_seek;
kf.file_read = modfs_read;
kf.entry_name = search_string;
kf.seek_set = 0;
kf.seek_cur = 1;
// check all modules..
for(i = 0; i < mods_count; i++)
{
#ifdef __DYNA_DEBUG__
printk("[MOD] Process Module #%d:", i);
#endif
kf.file_offset = 0;
// Pseudo-FS open
struct mods_struct* curr_mod = (struct mods_struct*)mods_addr;
start = (DWORD)curr_mod[i].mod_start;
end = (DWORD)curr_mod[i].mod_end;
pointer = start;
 
if( Elf_check(&kf) )
{
// Try to Link the ELF module and get it's main_entry address
dyn_entry = get_exec_address( &kf );
if(dyn_entry)
{
int j = dml->num_apps;
dml->app[j].dyn_entry = dyn_entry;
dml->app[j].start = start;
dml->app[j].end = end;
dml->app[j].size = end - start;
dml->app[j].name = curr_mod[i].string;
#ifdef __DYNA_DEBUG__
printk(" ELF object :%s [%d bytes]\n",
dml->app[j].name, dml->app[j].size);
#endif
++dml->num_apps;
}
else // add it as 'Data' module
{
int j = dml->num_dats;
dml->dat[j].start = start;
dml->dat[j].end = end;
dml->dat[j].size = end - start;
dml->dat[j].name = curr_mod[i].string;
#ifdef __DYNA_DEBUG__
printk(" Data object :%s [%d bytes]\n",
dml->dat[j].name, dml->dat[j].size);
#endif
++dml->num_dats;
}
}
else // it is a 'Data' module
{
int j = dml->num_dats;
dml->dat[j].start = start;
dml->dat[j].end = end;
dml->dat[j].size = end - start;
dml->dat[j].name = curr_mod[i].string;
#ifdef __DYNA_DEBUG__
printk(" Data object :%s [%d bytes]\n",
dml->dat[j].name, dml->dat[j].size);
#endif
++dml->num_dats;
}
//TODO: ? mem_release_module(mods_addr, i, mods_count);
}
return 0;
};
 
 
 
/*
// TODO: haven't finished this yet for SHARK [Lex]
void mem_release_module(DWORD mstart, int m, int mnum)
{
DWORD ms, nms, me, ms1, dummy;
int i;
 
module_address(mstart, m, &ms, &me);
nms = 0;
for (i = 0; i < mnum; i++)
{
module_address(mstart, i, &ms1, &dummy);
if(nms == 0)
{
if(ms1 >= me) nms = ms1;
}
else
{
if((ms1 >= me) && (ms1 < nms)) nms = ms1;
}
}
if (nms == 0) nms = me;
#ifdef __MEM_DEBUG__
printk("releasing %lx - %lx\n", ms, nms);
#endif
 
//pmm_add_region(&high_mem_pool, ms, nms - ms);
 
};
*/
 
/shark/trunk/ports/dynalink/elf.h
0,0 → 1,177
////////////////////////////////////////////////////////////////////////
// elf.h
//
// DynaLink for S.H.A.R.K
// Dynamic ELF object linker.
//
// Original code written by Luca Abeni.
// Adapted by Lex Nahumury 19-7-2006.
//
// This is free software; see GPL.txt
////////////////////////////////////////////////////////////////////////
#ifndef __ELF_HDR__
#define __ELF_HDR__
 
#define ELFCLASS32 1
#define ELFDATA2LSB 1
#define ET_EXEC 2
#define EM_386 3
 
/* This info is needed when parsing the symbol table */
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
 
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
 
#define ELF_ST_BIND(info) ((info) >> 4)
#define ELF_ST_TYPE(info) (((unsigned int) info) & 0xf)
 
/* sh_type */
#define SHT_NULL 0
#define SHT_SYMTAB 2
#define SHT_RELA 4
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_DYNSYM 11
 
#define R_386_32 1
#define R_386_PC32 2
 
/* special section indexes */
#define SHN_UNDEF 0
#define SHN_COMMON 0xFFF2
 
/* e_ident[] indexes */
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
 
#define EI_NIDENT 16
 
/* EI_MAG */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
 
#define PT_LOAD 1
#define PF_W 0x02
 
struct elf_header{
BYTE e_ident[EI_NIDENT];
WORD e_type;
WORD e_machine;
DWORD e_version;
DWORD e_entry; /* Entry point */
DWORD e_phoff;
DWORD e_shoff;
DWORD e_flags;
WORD e_ehsize;
WORD e_phentsize;
WORD e_phnum;
WORD e_shentsize;
WORD e_shnum;
WORD e_shstrndx;
};
 
/* FIXME!!! */
typedef struct {
DWORD p_type;
DWORD p_offset;
DWORD p_vaddr;
DWORD p_paddr;
DWORD p_filesz;
DWORD p_memsz;
DWORD p_flags;
DWORD p_align;
} Elf32_Phdr;
 
struct elf_section_header {
DWORD sh_name;
DWORD sh_type; /* Type of section */
DWORD sh_flags; /* Miscellaneous section attributes */
DWORD sh_addr; /* Section virtual addr at execution */
DWORD sh_offset; /* Section file offset */
DWORD sh_size; /* Size of section in bytes */
DWORD sh_link; /* Index of another section */
DWORD sh_info; /* Additional section information */
DWORD sh_addralign; /* Section alignment */
DWORD sh_entsize; /* Entry size if section holds table */
};
 
struct elf_symbol_info {
DWORD st_name;
DWORD st_value;
DWORD st_size;
BYTE st_info;
BYTE st_other;
WORD st_shndx;
};
 
struct elf_rel_info {
DWORD r_offset;
DWORD r_info;
};
 
struct elf_rela_info {
DWORD r_offset;
DWORD r_info;
DWORD r_addend;
};
 
int Elf_check(struct file_ops *kf);
int ELF_read_symbols(struct file_ops *kf,
struct table_info *tables,
struct symbol_info *syms);
 
int ELF_read_section_headers(struct file_ops *kf,
struct table_info *tables,
struct section_info *scndata);
 
DWORD ELF_read_headers(struct file_ops *kf,
struct table_info *tables);
int ELF_relocate_section(struct file_ops *kf, DWORD base,
struct table_info *tables,
int n,
struct section_info *s,
int sect,
struct symbol_info *syms,
struct symbol *import);
 
DWORD ELF_import_symbol(struct file_ops *kf,
int n,
struct symbol_info *syms,
char *name,
int *sect);
 
DWORD ELF_load_relocatable(struct file_ops *kf,
struct table_info *tables,
int n,
struct section_info *s,
DWORD *size);
 
void ELF_free_tables(struct file_ops *kf,
struct table_info *tables,
struct symbol_info *syms,
struct section_info *scndata);
#endif
 
 
 
 
 
 
 
 
 
/shark/trunk/ports/dynalink/makefile
0,0 → 1,29
# Dynalink
 
ifndef BASE
BASE=../..
endif
 
include $(BASE)/config/config.mk
 
LIBRARY = dynalink
 
OBJS_PATH = $(BASE)/dynalink
 
 
OBJS = dynalink.o elf.o
 
OTHERINCL += -I$(BASE)/drivers/linuxc26/include -I./include -I.
OTHERINCL += -I$(BASE)/drivers/pci/include
OTHERINCL += -I$(BASE)/drivers/input/include
 
 
 
C_OPT += -D__KERNEL__ -D__i386__ $(CFG_VIDEO_OPT)
 
include $(BASE)/config/lib.mk
 
clean::
rm -f $(OBJS)
rm -f deps
 
/shark/trunk/ports/dynalink/format.h
0,0 → 1,90
////////////////////////////////////////////////////////////////////////
// format.h
//
// DynaLink for S.H.A.R.K
// Dynamic ELF object linker.
//
// Original code written by Luca Abeni.
// Adapted by Lex Nahumury 19-7-2006.
//
// This is free software; see GPL.txt
////////////////////////////////////////////////////////////////////////
 
#ifndef __FORMAT_H__
#define __FORMAT_H__
 
#define EXTERN_SYMBOL 0xFF00
#define COMMON_SYMBOL 0xFF01
#define NULL_SYMBOL 0xFFFF
 
#define REL_TYPE_ELF_ABSOLUTE 1
#define REL_TYPE_RELATIVE 4
 
#define NEED_IMAGE_RELOCATION 1
#define NEED_SECTION_RELOCATION 2
#define NEED_LOAD_RELOCATABLE 4
#define NO_ENTRY 16
#define DLL_WITH_STDCALL 32
 
 
struct reloc_info {
DWORD offset;
int symbol;
int type;
};
 
 
struct symbol_info {
char *name;
DWORD offset;
WORD section;
};
 
struct table_info {
DWORD section_header;
WORD num_sections;
WORD section_header_size;
WORD flags;
DWORD symbol;
DWORD num_symbols;
DWORD symbol_size;
DWORD string;
DWORD string_size;
DWORD string_buffer;
char *section_names;
DWORD section_names_size;
DWORD image_base;
DWORD local_bss;
DWORD local_bss_size;
/* In PEI, it's a pei extra info */
DWORD private_info;
};
 
struct section_info {
DWORD base;
DWORD size;
DWORD fileptr;
DWORD filesize;
int num_reloc;
struct reloc_info *reloc;
};
 
/* Only used for ``import'' symbols... */
struct symbol {
char *name;
DWORD address;
};
 
 
struct file_ops
{
int (*file_read)( void *buffer, int len);
int (*file_seek)( int position, int wence);
int seek_set;
int seek_cur;
int file_offset;
char* entry_name;
};
 
 
#endif