Exemple #1
0
int module_import0(module_t *Module, const char *Symbol, int *IsRef, void **Data) {
	//pthread_t Thread = pthread_self();
	//printf("<thread @ %x> Entering module_import0:%d(%s, %s)\n", Thread, __LINE__, Module->Name, Symbol);
	pthread_mutex_lock(Module->Lock);
	export_t *Export = stringtable_get(Module->Symbols, Symbol);
	if (Export) {
		*IsRef = Export->IsRef;
		*Data = Export->Data;
		pthread_mutex_unlock(Module->Lock);
		//printf("<thread @ %x> Leaving module_import0:%d(%s, %s)\n", Thread, __LINE__, Module->Name, Symbol);
		return 1;
	};
	Symbol = GC_STRDUP(Symbol);
	for (module_provider_t *Provider = Module->Providers; Provider; Provider = Provider->Next) {
		if (!Provider->HasImports) continue;
		if (Provider->ImportFunc == directory_import) continue;
		if (Provider->ImportFunc(Provider->ImportInfo, Symbol, IsRef, Data)) {
			export_t *Export = new(export_t);
			Export->IsRef = *IsRef;
			Export->Data = *Data;
			stringtable_put(Module->Symbols, Symbol, Export);
			pthread_mutex_unlock(Module->Lock);
			//printf("<thread @ %x> Leaving module_import0:%d(%s, %s)\n", Thread, __LINE__, Module->Name, Symbol);
			return 1;
		};
	};
	pthread_mutex_unlock(Module->Lock);
	//printf("<thread @ %x> Leaving module_import0:%d(%s, %s)\n", Thread, __LINE__, Module->Name, Symbol);
	return 0;
};
Exemple #2
0
void module_provider_export(module_provider_t *Provider, const char *Symbol, int IsRef, void *Data) {
	export_t *Export = new(export_t);
	Export->IsRef = IsRef;
	Export->Data = Data;
	pthread_mutex_lock(LibRivaMutex);
	stringtable_put(Provider->Module->Symbols, Symbol, Export);
	pthread_mutex_unlock(LibRivaMutex);
};
Exemple #3
0
void module_export(module_t *Module, const char *Name, int IsRef, void *Data) {
	export_t *Export = new(export_t);
	Export->IsRef = IsRef;
	Export->Data = Data;
	pthread_mutex_lock(LibRivaMutex);
	stringtable_put(Module->Symbols, Name, Export);
	pthread_mutex_unlock(LibRivaMutex);
};
Exemple #4
0
static void symbols_section_relocate(symbols_section_t *Section, relocation_t *Relocation, uint32_t *Target) {
	const char *Name = Section->Symbols + *Target;
	*Target = 0;
	section_t *Symbol = (section_t *)stringtable_get(SymbolTable, Name);
	if (!Symbol) {
		Name = strdup(Name);
		Symbol = (section_t *)new_symbol_section(Name);
		stringtable_put(SymbolTable, Name, Symbol);
	};
	section_require(Symbol);
	Relocation->Section = Symbol;
};
Exemple #5
0
static module_t *module_load_internal(const char *Path, const char *File, const char *Alias) {
	//pthread_t Thread = pthread_self();
	//printf("<thread @ %x> Entering module_load_internal:%d(%s, %s)\n", Thread, __LINE__, Path, File);
	const char *Name = path_join(Path, File);
	pthread_mutex_lock(LibRivaMutex);
	module_t *Module = stringtable_get(Modules, Name);
	if (Module) {
		pthread_mutex_unlock(LibRivaMutex);
		module_reload(Module);
		//printf("<thread @ %x> Leaving module_load_internal:%d(%s, %s)\n", Thread, __LINE__, Path, File);
		return Module;
	};
	module_provider_t *Providers = module_find_loaders(Name, ModuleLoaders, -1);
	if (!Providers) {
		pthread_mutex_unlock(LibRivaMutex);
		//printf("<thread @ %x> Leaving module_load_internal:%d(%s, %s)\n", Thread, __LINE__, Path, File);
		return 0;
	};
	Module = stringtable_get(Modules, Name);
	if (Module) {
		pthread_mutex_unlock(LibRivaMutex);
		module_reload(Module);
		//printf("<thread @ %x> Leaving module_load_internal:%d(%s, %s)\n", pthread_self(), __LINE__, Path, File);
		return Module;
	};
	Module = new(module_t);
	Module->Type = ModuleT;
	Module->Name = Name;
	Module->Path = path_dir(Name);
	Module->TimeStamp = ModuleTimeStamp;
	Module->Lock[0] = RecursiveMutex;
	stringtable_put(Modules, Name, Module);
	if (Alias) stringtable_put(Modules, Alias, Module);
	pthread_mutex_lock(Module->Lock);
	pthread_mutex_unlock(LibRivaMutex);
	module_call_loaders(Name, Module, Providers);
	pthread_mutex_unlock(Module->Lock);
	//printf("<thread @ %x> Leaving module_load_internal:%d(%s, %s)\n", Thread, __LINE__, Path, File);
	return Module;
};
Exemple #6
0
static library_section_t *new_library_section(const char *Path) {
	static section_methods Methods = {
		default_section_setup,
		default_section_relocate,
		(void (*)(section_t *, FILE *))library_section_debug,
		(void (*)(section_t *, gzFile ))library_section_write
	};
	library_section_t *Section = new(library_section_t);
	((section_t *)Section)->Index = SEC_UNUSED;
	((section_t *)Section)->Methods = &Methods;
	memset(Section->Imports, 0, sizeof(Section->Imports));
	Section->Path = Path;
	stringtable_put(LibraryTable, Path, Section);
	return Section;
};
Exemple #7
0
static import_section_t *new_import_section(library_section_t *Library, const char *Name, int Type) {
	static section_methods Methods = {
		(void (*)(section_t *))import_section_setup,
		default_section_relocate,
		(void (*)(section_t *, FILE *))import_section_debug,
		(void (*)(section_t *, gzFile ))import_section_write
	};
	import_section_t *Section = new(import_section_t);
	((section_t *)Section)->Index = SEC_UNUSED;
	((section_t *)Section)->Methods = &Methods;
	Section->Name = Name;
	Section->Library = Library;
	Section->Type = Type;
	stringtable_put(Library->Imports, Name, Section);
	return Section;
};
Exemple #8
0
static void add_bfd(bfd *Bfd) {
	if (bfd_check_format(Bfd, bfd_object)) {
		bfd_info_t *BfdInfo = new(bfd_info_t);
		BfdInfo->FileName = Bfd->filename;
		memset(BfdInfo->LocalTable, 0, sizeof(BfdInfo->LocalTable));
		BfdInfo->Symbols = (asymbol **)malloc(bfd_get_symtab_upper_bound(Bfd));
		int NoOfSymbols = bfd_canonicalize_symtab(Bfd, BfdInfo->Symbols);
		bfd_map_over_sections(Bfd, (bfd_map)add_bfd_section, BfdInfo);
		for (int I = NoOfSymbols - 1; I >= 0; --I) {
			asymbol *Sym = BfdInfo->Symbols[I];
			if (Sym->flags & BSF_GLOBAL) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(BfdInfo->LocalTable, Name, Symbol);
				stringtable_put(GlobalTable, Name, Symbol);
			} else if (Sym->section == bfd_com_section_ptr) {
				symbol_t *Symbol = (symbol_t *)stringtable_get(GlobalTable, Sym->name);
				bss_section_t *Section;
				if (!Symbol) {
					const char *Name = strdup(Sym->name);
					Section = new_bss_section(0);
					Symbol = new_symbol(Name, (section_t *)Section, 0);
					stringtable_put(GlobalTable, Name, Symbol);
					stringtable_put(BfdInfo->LocalTable, Name, Symbol);
				} else {
					Section = (bss_section_t *)Symbol->Section;
				};
				if (Sym->value > Section->Size) Section->Size = Sym->value;
			} else if (Sym->flags & BSF_LOCAL) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(BfdInfo->LocalTable, Name, Symbol);
			} else if (Sym->flags & BSF_WEAK) {
				const char *Name = strdup(Sym->name);
				symbol_t *Symbol = new_symbol(Name, (section_t *)Sym->section->userdata, Sym->value);
				stringtable_put(WeakTable, Name, Symbol);
			} else if (Sym->section == bfd_und_section_ptr) {
			} else if (Sym->flags & BSF_DEBUGGING) {
			    // This may be supported later
			} else {
				printf("%s: unknown symbol type: %8x.\n", Bfd->filename, Sym->flags);
				exit(1);
			};
		};
	} else if (bfd_check_format(Bfd, bfd_archive)) {
		bfd *Bfd2 = 0;
		while ((Bfd2 = bfd_openr_next_archived_file(Bfd, Bfd2))) add_bfd(Bfd2);
	};
};
Exemple #9
0
static method_section_t *new_method_section() {
	static section_methods Methods = {
		(void (*)(section_t *))method_section_setup,
		invalid_section_relocate,
		(void (*)(section_t *, FILE *))method_section_debug,
		(void (*)(section_t *, gzFile ))method_section_write
	};
	if (MethodSection == 0) {
		MethodSection = new(method_section_t);
		((section_t *)MethodSection)->Methods = &Methods;
		((section_t *)MethodSection)->Index = SEC_UNUSED;
		MethodSection->Blocks = 0;
		MethodSection->Size = 0;
		MethodSection->NoOfRelocs = 0;
		new_export("<methods>", "__methods", EXP_CONSTANT);
		symbol_t *Symbol = new_symbol("<methods>", (section_t *)MethodSection, 0);
		stringtable_put(GlobalTable, "<methods>", Symbol);
	};
	return MethodSection;
};
Exemple #10
0
static int library_file_module(lua_State *State) {
    int NoOfArgs = lua_gettop(State);
    lua_getglobal(State, "Library");
    library_file_t *Library = lua_touserdata(State, -1);
    lua_pop(State, 1);

    int PathSize = 0;
    for (int I = 1; I <= NoOfArgs; ++I) PathSize += strlen(lua_tostring(State, I)) + 1;
    char *Path = (char *)malloc(PathSize), *PathPtr = Path;
#ifdef WINDOWS
    char *Name = (char *)malloc(PathSize + 1), *NamePtr = Name + 1;
    Name[0] = '_';
#else
	char *Name = (char *)malloc(PathSize), *NamePtr = Name;
#endif
    for (int I = 1; I <= NoOfArgs; ++I) {
        char *Temp = lua_tostring(State, I);
		PathPtr = stpcpy(PathPtr, Temp);
		*(PathPtr++) = '/';
		NamePtr = stpcpy(NamePtr, Temp);
		*(NamePtr++) = '$';
    };
    PathPtr[-1] = 0;
	NamePtr[-1] = 0;

	library_section_t *LibrarySection = (library_section_t *)stringtable_get(LibraryTable, Path);
	if (LibrarySection == 0) {
        LibrarySection = new_library_section(Path);
        symbol_t *Symbol = new(symbol_t);
        Symbol->Name = Name;
        Symbol->Section = (section_t *)LibrarySection;
        Symbol->Offset = 0;
        stringtable_put(GlobalTable, Name, Symbol);
	};

    Library->Section = LibrarySection;
    return 0;
};
Exemple #11
0
static int library_file_export(lua_State *State) {
    int NoOfArgs = lua_gettop(State);
    lua_getglobal(State, "Library");
    library_file_t *Library = lua_touserdata(State, -1);
    lua_pop(State, 1);
    int Flags = 0;
    const char *Internal = 0;
    const char *External = 0;
    for (int I = 1; I <= NoOfArgs; ++I) {
        if (lua_isstring(State, I)) {
            if (Internal == 0) {
                Internal = strdup(lua_tostring(State, I));
            } else {
                External = strdup(lua_tostring(State, I));
            };
        } else if (lua_isuserdata(State, I)) {
            void *Name = lua_touserdata(State, I);
            for (export_type *E = ExportTypes; E->Name; ++E) {
                if (E->Name == Name) {
                    Flags = E->Flags;
                    break;
                };
            };
        };
    };
    if (External == 0) asprintf(&External, "%s%s", Library->Prefix, Internal);

    //printf("Adding export: %s -> %s\n", Internal, External);

    import_section_t *ImportSection = (import_section_t *)stringtable_get(Library->Section->Imports, Internal);
    if (ImportSection == 0) {
        ImportSection = new_import_section(Library->Section, Internal, Flags);
    };
    symbol_t *Symbol = new_symbol(External, (section_t *)ImportSection, 0);
    stringtable_put(GlobalTable, External, Symbol);
    return 0;
};
Exemple #12
0
int main(int Argc, char **Argv) {
	if (Argc < 2) {
		puts("Usage: rlink [-o output] [-l listing] inputs ... ");
	} else {
		bfd_init();
		stringtable_put(SupportedFiles, ".rlib", (void *)add_library_file);
		stringtable_put(SupportedFiles, ".rdef", (void *)add_definition_file);
		stringtable_put(SupportedFiles, ".a", (void *)add_object_file);
		stringtable_put(SupportedFiles, ".o", (void *)add_object_file);
		stringtable_put(SupportedFiles, ".obj", (void *)add_object_file);
		stringtable_put(SupportedFiles, ".mo", (void *)add_object_file);
		stringtable_put(SupportedFiles, ".io", (void *)add_object_file);
		char *OutFile = 0;
		char *ListFile = 0;
		for (int I = 1; I < Argc; ++I) {
			if (Argv[I][0] == '-') {
				switch (Argv[I][1]) {
				case 'o':
					OutFile = Argv[I] + 2;
					break;
				case 'l':
					add_file(Argv[I] + 2);
					break;
				case 'L':
					add_path(Argv[I] + 2);
				case 's':
					break;
                case 'm':
                    Platform = Argv[I] + 2;
				case '?':
					ListFile = Argv[I] + 2;
					break;
				};
			} else {
				add_file(Argv[I]);
			};
		};
		for (export_t *Export = Exports.Head; Export; Export = Export->Next) {
			symbol_t *Symbol = (symbol_t *)stringtable_get(GlobalTable, Export->Internal);
			if (Symbol) {
				section_require(Export->Section = Symbol->Section);
				Export->Offset = Symbol->Offset;
			} else {
				printf("exported symbol not found: %s.\n", Export->Internal);
				exit(1);
			};
		};
		if (ListFile) {
			FILE *File = fopen(ListFile, "w");
			for (section_t *Section = Sections.Head; Section; Section = Section->Next) section_debug(Section, File);
			for (export_t *Export = Exports.Head; Export; Export = Export->Next) {
				fprintf(File, "export: %s -> %d[%d]\n", Export->External, Export->Section->Index, Export->Offset);
			};
			for (require_t *Require = Requires.Head; Require; Require = Require->Next) {
				fprintf(File, "require: %s[%d]\n", Require->Library, Require->Flags);
			};
			fclose(File);
		};
		if (OutFile) {
			uint32_t Temp;
			gzFile File = gzopen(OutFile, "wb9");
			gzwrite(File, "RIVA", 4);
			Temp = NoOfSections; gzwrite(File, &Temp, 4);
			Temp = NoOfExports; gzwrite(File, &Temp, 4);
			Temp = NoOfRequires; gzwrite(File, &Temp, 4);
			for (section_t *Section = Sections.Head; Section; Section = Section->Next) section_write(Section, File);
			for (export_t *Export = Exports.Head; Export; Export = Export->Next) {
				Temp = Export->Flags; gzwrite(File, &Temp, 1);
				Temp = Export->Section->Index; gzwrite(File, &Temp, 4);
				Temp = Export->Offset; gzwrite(File, &Temp, 4);
				Temp = strlen(Export->External); gzwrite(File, &Temp, 4);
				gzwrite(File, Export->External, Temp);
			};
			for (require_t *Require = Requires.Head; Require; Require = Require->Next) {
				Temp = Require->Flags; gzwrite(File, &Temp, 1);
				Temp = strlen(Require->Library); gzwrite(File, &Temp, 4);
				gzwrite(File, Require->Library, Temp);
			};
			gzclose(File);
		};
	};
};
Exemple #13
0
void module_add_alias(module_t *Module, const char *Name) {
	pthread_mutex_lock(LibRivaMutex);
	stringtable_put(Modules, Name, Module);
	pthread_mutex_unlock(LibRivaMutex);
};
Exemple #14
0
void compiler_t::declare(const char *Name, operand_t *Operand) {
	stringtable_put(Scope->NameTable, Name, Operand);
};
Exemple #15
0
static int riva_load(module_t *Module, const char *FileName) {
	riva_t *Riva = unew(riva_t); // This really should be new...
	module_setup(Module, Riva, (module_importer)riva_import);

	gzFile File = gzopen(FileName, "rb");
	char *LoadPath;
	for (int I = strlen(FileName) - 1; I >= 0; --I) {
		if (FileName[I] == PATHCHR) {
			strncpy(LoadPath = (char *)GC_malloc_atomic(I + 2), FileName, I + 1);
			break;
		};
	};
	module_set_path(Module, LoadPath);

	uint32_t Magic; gzread(File, &Magic, 4);
	if (Magic != 0x41564952) {
		log_errorf("Error: %s is not a valid riva module\n", FileName);
		return 0;
	};

	uint32_t NoOfSections; gzread(File, &NoOfSections, 4);
	uint32_t NoOfExports; gzread(File, &NoOfExports, 4);
	uint32_t NoOfRequires; gzread(File, &NoOfRequires, 4);

	jmp_buf OnError[1];

	if (setjmp(OnError)) return 0;
	section_t **Sections = (Riva->Sections = (section_t **)GC_malloc(NoOfSections * sizeof(section_t *)));
	for (int I = 0; I < NoOfSections; ++I) Sections[I] = new(section_t);
	for (int I = 0; I < NoOfSections; ++I) {
		section_t *Section = Sections[I];
		uint8_t Type; gzread(File, &Type, 1);
		switch (Type) {
		case SECT_CODE: {
			Section->Fixup = fixup_code_section;
			gzread(File, &Section->Flags, 1);
			uint32_t Length; gzread(File, &Length, 4);
			uint32_t NoOfRelocs; gzread(File, &NoOfRelocs, 4);
			Section->NoOfRelocs = NoOfRelocs;
			reloc_t *Relocs = (Section->Relocs = (reloc_t *)GC_malloc_uncollectable(NoOfRelocs * sizeof(reloc_t)));
			if (Section->Flags & FLAG_GC) {
				Section->Data = GC_malloc_uncollectable(Length);
			} else {
				Section->Data = GC_malloc_atomic_uncollectable(Length);
			};
			gzread(File, Section->Data, Length);
			for (int J = 0; J < NoOfRelocs; ++J) {
				reloc_t *Reloc = &Relocs[J];
				gzread(File, &Reloc->Size, 1);
				gzread(File, &Reloc->Flags, 1);
				gzread(File, &Reloc->Position, 4);
				uint32_t Index; gzread(File, &Index, 4);
				Reloc->Section = Sections[Index];
			};
		break;};
		case SECT_LIBRARY: {
			Section->Fixup = fixup_library_section;
			gzread(File, &Section->Flags, 1);
			uint32_t Length; gzread(File, &Length, 4);
			gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length);
			Section->Name[Length] = 0;
			if (Section->Flags == LIBRARY_ABS) {
				Section->Path = 0;
			} else if (Section->Flags == LIBRARY_REL) {
				Section->Path = LoadPath;
			};
			for (char *P = Section->Name; *P; ++P) if (*P == '/') *P = PATHCHR;
		break;};
		case SECT_IMPORT: {
			Section->Fixup = fixup_import_section;
			gzread(File, &Section->Flags, 1);
			uint32_t Index; gzread(File, &Index, 4);
			Section->Library = Sections[Index];
			uint32_t Length; gzread(File, &Length, 4);
			gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length);
			Section->Name[Length] = 0;
		break;};
		case SECT_BSS: {
			Section->Fixup = fixup_bss_section;
			gzread(File, &Section->Flags, 1);
			uint32_t Size; gzread(File, &Size, 4);
			Section->Data = (uint8_t *)GC_malloc(Size);
		break;};
		case SECT_SYMBOL: {
			Section->Fixup = fixup_symbol_section;
			gzread(File, &Section->Flags, 1);
			uint32_t Length; gzread(File, &Length, 4);
			gzread(File, Section->Name = (char *)GC_malloc_atomic(Length + 1), Length);
			Section->Name[Length] = 0;
		break;};
		};
	};
	for (int I = 0; I < NoOfExports; ++I) {
		export_t *Export = new(export_t);
		gzread(File, &Export->Flags, 1);
		uint32_t Index; gzread(File, &Index, 4);
		Export->Section = Sections[Index];
		gzread(File, &Export->Offset, 4);
		uint32_t Length; gzread(File, &Length, 4);
		char *Name = (char *)GC_malloc_atomic(Length + 1);
		gzread(File, Name, Length);
		Name[Length] = 0;
		stringtable_put(Riva->Exports, Name, Export);
	};
	for (int I = 0; I < NoOfRequires; ++I) {
		uint8_t Flags; gzread(File, &Flags, 1);
		uint32_t Length; gzread(File, &Length, 4);
		char *Name = (char *)GC_malloc_atomic(Length + 1);
		char *Path = 0;
		gzread(File, Name, Length);
		Name[Length] = 0;
		if (Flags == LIBRARY_REL) Path = LoadPath;
		for (char *P = Name; *P; ++P) if (*P == '/') *P = PATHCHR;
		module_load(Path, Name);
	};
	gzclose(File);

	void (*__init)(module_t *) = check_import(Riva, "__init", OnError);
 	if (__init) __init(Module);
 	void *Methods = check_import(Riva, "__methods", OnError);
 	if (Methods) add_methods(Methods);
	return 1;
};