Example #1
0
File: module.c Project: wrapl/wrapl
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;
};
Example #2
0
File: module.c Project: wrapl/wrapl
module_t *module_load(const char *Path, const char *File) {
	log_writef("Loading %s, path = %s.\n", File, Path);
	if (Path) return module_load_internal(Path, File, 0);
	//pthread_t Thread = pthread_self();
	//printf("<thread @ %x> Entering module_load:%d(%s, %s)\n", Thread, __LINE__, Path, File);
	const char *Alias = path_join("library:", File);
	pthread_mutex_lock(LibRivaMutex);
	module_t *Module = stringtable_get(Modules, Alias);
	pthread_mutex_unlock(LibRivaMutex);
	if (Module) {
		module_reload(Module);
		//printf("Found module %s = 0x%x\n", Alias, Module);
		//printf("<thread @ %x> Leaving module_load:%d(%s, %s)\n", Thread, __LINE__, Path, File);
		return Module;
	};
	for (path_node *Path = ModuleLibrary; Path; Path = Path->Next) {
		Module = module_load_internal(Path->Dir, File, Alias);
		if (Module) {
			//printf("<thread @ %x> Leaving module_load:%d(%s, %s)\n", Thread, __LINE__, Path, File);
			return Module;
		};
	};
	//printf("<thread @ %x> Leaving module_load:%d(%s, %s)\n", Thread, __LINE__, Path, File);
	return 0;
};
Example #3
0
static void *check_import(riva_t *Riva, const char *Symbol, jmp_buf *OnError) {
	const export_t *Export = stringtable_get(Riva->Exports, Symbol);
	if (Export) {
		void *Data = Export->Section->Data + Export->Offset;
		Export->Section->Fixup(Export->Section, OnError);
		return Data;
	} else {
		return 0;
	};
};
Example #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;
};
Example #5
0
File: module.c Project: wrapl/wrapl
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;
};
Example #6
0
operand_t *compiler_t::lookup(int LineNo, const char *Name) {
	for (scope_t *Scope = this->Scope; Scope; Scope = Scope->Up) {
		operand_t *Operand = (operand_t *)stringtable_get(Scope->NameTable, Name);
		if (Operand) {
			switch (Scope->Type) {
			case scope_t::SC_GLOBAL: {
				if (Operand->Type == operand_t::FUTR) {
					Sys$Module_t *Module = Sys$Module$load(0, Operand->Module);
					if (Module == 0) raise_error(LineNo, "Error: module not found %s\n", Operand->Module);
					if (Operand->Import) {
						if (Sys$Module$import(Module, Operand->Import, (int *)&Operand->Type, (void **)&Operand->Value) == 0) {
							raise_error(LineNo, "Error: import not found %s.%s\n", Operand->Module, Operand->Import);
						};
					} else {
						Operand->Type = operand_t::CNST;
						Operand->Value = (Lang$Object_t *)Module;
					};
				};
				return Operand;
			};
			case scope_t::SC_LOCAL: {
				if (Scope->Function == Function) return Operand;
				operand_t *Operand2 = (operand_t *)integertable_get(Function->VarTable, (uint32_t)Operand);
				if (Operand2 != (operand_t *)0xFFFFFFFF) return Operand2;
				Operand2 = new operand_t;
				Operand2->Type = Operand->Type;
				Operand2->Index = Operand->Index;
				Operand2->Loop = Function->lookup(Scope->Loop);
				integertable_put(Function->VarTable, (uint32_t)Operand, Operand2);
				return Operand2;
			};
			};
		};
	};
	/*switch (this->Scope->Type) {
	case scope_t::SC_GLOBAL: {
		operand_t *Operand = new operand_t;
		Operand->Type = operand_t::GVAR;
		Lang$Object_t **Address = new Lang$Object_t *;
		Address[0] = Lang$Object$Nil;
		Operand->Address = Address;
		declare(Name, Operand);
		return Operand;
	};
	case scope_t::SC_LOCAL: {
		operand_t *Operand = new_local();
		declare(Name, Operand);
		return Operand;
	};
	};*/
	raise_error(LineNo, "Error: identifier %s not declared", Name);
};
Example #7
0
static int riva_import(riva_t *Riva, const char *Symbol, int *IsRef, void **Data) {
	const export_t *Export = stringtable_get(Riva->Exports, Symbol);
	if (Export) {
		jmp_buf OnError[1];
		if (setjmp(OnError)) return 0;
		*IsRef = Export->Flags & EXP_VARIABLE;
		*Data = Export->Section->Data + Export->Offset;
		Export->Section->Fixup(Export->Section, OnError);
		return 1;
	} else {
		return 0;
	};
};
Example #8
0
static void bfd_section_setup(bfd_section_t *Section) {
	bfd *Bfd = Section->Bfd;
	bfd_info_t *BfdInfo = Section->BfdInfo;
	asection *Sect = Section->Sect;
	Section->Size = bfd_get_section_size(Sect);
	bfd_malloc_and_get_section(Bfd, Sect, &Section->Code);
	arelent **Relocs = (arelent **)malloc(bfd_get_reloc_upper_bound(Bfd, Sect));
	Section->NoOfRelocs = bfd_canonicalize_reloc(Bfd, Sect, Relocs, BfdInfo->Symbols);
	Section->Relocs = (relocation_t *)malloc(sizeof(relocation_t) * Section->NoOfRelocs);
	for (int I = Section->NoOfRelocs - 1; I >= 0; --I) {
		relocation_t *Relocation = Section->Relocs + I;
		asymbol *Sym = *(Relocs[I]->sym_ptr_ptr);
		reloc_howto_type *Type = Relocs[I]->howto;
		Relocation->Position = Relocs[I]->address;
		Relocation->Size = bfd_get_reloc_size(Type);
		Relocation->Flags = Type->pc_relative ? RELOC_REL : RELOC_ABS;
		uint32_t *Target = (uint32_t *)(Section->Code + Relocs[I]->address);
		if (Type->pc_relative) {
#ifdef WINDOWS
			*(long *)(Section->Code + Relocs[I]->address) -= Relocs[I]->address + 4;// why oh why is this here???
#else
            *(long *)(Section->Code + Relocs[I]->address) -= Relocs[I]->address;// + 4 on windows platforms ???;
#endif
		};
		if (Sym->section == bfd_und_section_ptr) {
			symbol_t *Symbol;
			do {
				Symbol = (symbol_t *)stringtable_get(BfdInfo->LocalTable, Sym->name);
				if (Symbol) break;
				Symbol = (symbol_t *)stringtable_get(GlobalTable, Sym->name);
				if (Symbol) break;
				Symbol = (symbol_t *)stringtable_get(WeakTable, Sym->name);
				if (Symbol) break;
#ifdef WINDOWS
                char *WindowsSizeHint = strrchr(Sym->name, '@');
                if (WindowsSizeHint) {
                    *WindowsSizeHint = 0;
                    Symbol = (symbol_t *)stringtable_get(BfdInfo->LocalTable, Sym->name);
                    if (Symbol) break;
                    Symbol = (symbol_t *)stringtable_get(GlobalTable, Sym->name);
                    if (Symbol) break;
                    Symbol = (symbol_t *)stringtable_get(WeakTable, Sym->name);
                    if (Symbol) break;
                }
#endif
				printf("%s: unresolved symbol %s.\n", Bfd->filename, Sym->name);
				exit(1);
			} while (0);
			section_t *Section2 = Symbol->Section;
			section_relocate(Section2, Relocation, Target);
			if (Type->partial_inplace) *Target += (uint32_t)Symbol->Offset;
		} else if (Sym->section->userdata) {
			section_t *Section2 = (section_t *)Sym->section->userdata;
			section_relocate(Section2, Relocation, Target);
			if (Type->partial_inplace) *Target += (uint32_t)Sym->value;
		};
	};
};
Example #9
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);
	};
};
Example #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;
};
Example #11
0
static void add_file(const char *FileName) {
	const char *Extension = strrchr(FileName, '.');
	if (Extension == 0) {
		printf("%s: filename must include extension.\n", FileName);
		return;
	};
	file_adder _add = (file_adder)stringtable_get(SupportedFiles, Extension);
	if (_add == 0) {
		printf("%s: unable to determine file type from extension.\n", FileName);
		return;
	};
	struct stat Stat;
	char FullFileName[256];
	for (search_path_t *Node = &SearchPath; Node; Node = Node->Next) {
		sprintf(FullFileName, "%s%s", Node->Path, FileName);
		if (stat(FullFileName, &Stat) == 0) {
			_add(strdup(FullFileName));
			return;
		};
	};
	printf("%s: file not found.\n", FileName);
	exit(1);
};
Example #12
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;
};
Example #13
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);
		};
	};
};