feat(tools): fas2dump: generate elf file with symbol table from .fas
This commit is contained in:
		
							parent
							
								
									ca6e6e9487
								
							
						
					
					
						commit
						81abea70fd
					
				
					 12 changed files with 1320 additions and 25 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -33,6 +33,9 @@ bochsrc.bxrc | ||||||
| *.EFI | *.EFI | ||||||
| *.fd | *.fd | ||||||
| *.mod | *.mod | ||||||
|  | *.fas | ||||||
|  | *.sym | ||||||
|  | *.dbg | ||||||
| webring.json | webring.json | ||||||
| webring.txt | webring.txt | ||||||
| kernel/const.inc | kernel/const.inc | ||||||
|  |  | ||||||
							
								
								
									
										39
									
								
								bin/fas2sym/buffer.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								bin/fas2sym/buffer.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "fas2sym.h" | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | buffer_put(struct buffer *buff, const uint8_t *data, size_t size, | ||||||
|  | 		   size_t *index) | ||||||
|  | { | ||||||
|  | 	if (index != NULL) | ||||||
|  | 	{ | ||||||
|  | 		*index = buff->cnt; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	while (buff->cap < buff->cnt + size) | ||||||
|  | 	{ | ||||||
|  | 		buff->cap = (buff->cap == 0 ? 32 : buff->cap * 2); | ||||||
|  | 		buff->data = (uint8_t *)realloc(buff->data, buff->cap); | ||||||
|  | 		if (buff->data == NULL) | ||||||
|  | 		{ | ||||||
|  | 			msg_err(NULL); | ||||||
|  | 			return (-1); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	memcpy(buff->data + buff->cnt, data, size); | ||||||
|  | 	buff->cnt += size; | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | buffer_cleanup(struct buffer *buff) | ||||||
|  | { | ||||||
|  | 	buff->cnt = 0; | ||||||
|  | 	buff->cap = 0; | ||||||
|  | 	free(buff->data); | ||||||
|  | 	buff->data = 0; | ||||||
|  | } | ||||||
							
								
								
									
										216
									
								
								bin/fas2sym/elf.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								bin/fas2sym/elf.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,216 @@ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <elf.h> | ||||||
|  | #include "fas2sym.h" | ||||||
|  | 
 | ||||||
|  | enum sections { | ||||||
|  | 	SEC_NULL   = 0, | ||||||
|  | 	SEC_SHSTRTAB, | ||||||
|  | 	SEC_STRTAB, | ||||||
|  | 	SEC_SYMTAB, | ||||||
|  | 	SEC_END | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static Elf32_Ehdr elf_ehdr = { | ||||||
|  | 	{ | ||||||
|  | 		ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, | ||||||
|  | 		ELFCLASS32, ELFDATA2LSB, EV_CURRENT, | ||||||
|  | 		0, 0, 0, 0, 0, 0, 0, 0, 0 | ||||||
|  | 	}, | ||||||
|  | 	ET_REL, EM_386, EV_CURRENT, 0, 0, 0, 0, | ||||||
|  |     sizeof(Elf32_Ehdr), sizeof(Elf32_Phdr), 0, | ||||||
|  | 	sizeof(Elf32_Shdr), SEC_END, SEC_SHSTRTAB | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static Elf32_Shdr elf_shdrs[SEC_END] = { | ||||||
|  | 	{ 0, SHT_NULL, 0, 0, 0, 0, SHN_UNDEF, 0, 0, 0 }, | ||||||
|  | 	/* .shstrtab */ | ||||||
|  | 	{ 1, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, | ||||||
|  | 	/* .strtab */ | ||||||
|  | 	{ 11, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, | ||||||
|  | 	/* .symtab */ | ||||||
|  | 	{ | ||||||
|  | 		19, SHT_SYMTAB, 0, 0, 0, 0, | ||||||
|  | 		SEC_STRTAB, 0, 4, sizeof(Elf32_Sym) | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct buffer elf_shstrtab = { 0, 0, NULL }; | ||||||
|  | static struct buffer elf_strtab = { 0, 0, NULL }; | ||||||
|  | static struct buffer elf_symtab = { 0, 0, NULL }; | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | elf_shstrtab_init(void) | ||||||
|  | { | ||||||
|  | 	const uint8_t initial[] = "\0.shstrtab\0.strtab\0.symtab\0"; | ||||||
|  | 
 | ||||||
|  | 	return (buffer_put(&elf_shstrtab, initial, sizeof(initial), NULL)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | elf_strtab_init(void) | ||||||
|  | { | ||||||
|  | 	const uint8_t initial[] = "\0"; | ||||||
|  | 
 | ||||||
|  | 	return (buffer_put(&elf_strtab, initial, sizeof(initial), NULL)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | elf_symtab_init(void) | ||||||
|  | { | ||||||
|  | 	const Elf32_Sym initial = { 0, 0, 0, 0, 0, SHN_UNDEF }; | ||||||
|  | 
 | ||||||
|  | 	return (buffer_put(&elf_symtab, (uint8_t *)&initial, | ||||||
|  | 					   sizeof(Elf32_Sym), NULL)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | elf_init(void) | ||||||
|  | { | ||||||
|  | 	if (elf_shstrtab_init() != 0) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (elf_strtab_init() != 0) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (elf_symtab_init() != 0) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size, | ||||||
|  | 			   uint8_t info, uint16_t sect) | ||||||
|  | { | ||||||
|  | 	Elf32_Sym sym = { 0 }; | ||||||
|  | 
 | ||||||
|  | 	sym.st_name = name_off; | ||||||
|  | 	sym.st_value = value; | ||||||
|  | 	sym.st_size = size; | ||||||
|  | 	sym.st_info = info; | ||||||
|  | 	sym.st_shndx = sect; | ||||||
|  | 
 | ||||||
|  | 	msg_verbose(2, "add symbol: %s", | ||||||
|  | 				(char *)(elf_strtab.data + name_off)); | ||||||
|  | 
 | ||||||
|  | 	return (buffer_put(&elf_symtab, (uint8_t *)&sym, | ||||||
|  | 					   sizeof(Elf32_Sym), NULL)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | elf_add_str(const char *str, size_t len, size_t *idx) | ||||||
|  | { | ||||||
|  | 	return (buffer_put(&elf_strtab, (uint8_t *)str, len, idx)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | elf_write_tab(struct buffer *buff, FILE *fp) | ||||||
|  | { | ||||||
|  | 	if (buff->cnt == 0 || buff->data == NULL) | ||||||
|  | 	{ | ||||||
|  | 		return (0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fwrite(buff->data, buff->cnt, 1, fp) != 1) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | elf_compute_section_offsets(void) | ||||||
|  | { | ||||||
|  | 	size_t offset; | ||||||
|  | 
 | ||||||
|  | 	offset = sizeof(Elf32_Ehdr); | ||||||
|  | 	elf_shdrs[SEC_SHSTRTAB].sh_offset = offset; | ||||||
|  | 	elf_shdrs[SEC_SHSTRTAB].sh_size = elf_shstrtab.cnt; | ||||||
|  | 
 | ||||||
|  | 	offset += elf_shstrtab.cnt; | ||||||
|  | 
 | ||||||
|  | 	elf_shdrs[SEC_STRTAB].sh_offset = offset; | ||||||
|  | 	elf_shdrs[SEC_STRTAB].sh_size = elf_strtab.cnt; | ||||||
|  | 
 | ||||||
|  | 	offset += elf_strtab.cnt; | ||||||
|  | 
 | ||||||
|  | 	elf_shdrs[SEC_SYMTAB].sh_offset = offset; | ||||||
|  | 	elf_shdrs[SEC_SYMTAB].sh_size = elf_symtab.cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | elf_write(const char *file) | ||||||
|  | { | ||||||
|  | 	FILE *fp; | ||||||
|  | 	int status; | ||||||
|  | 	size_t offset; | ||||||
|  | 
 | ||||||
|  | 	fp = fopen(file, "wb"); | ||||||
|  | 	if (fp == NULL) | ||||||
|  | 	{ | ||||||
|  | 	    msg_err(file); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	status = -1; | ||||||
|  | 
 | ||||||
|  | 	/* compute section headers offset */ | ||||||
|  | 	elf_ehdr.e_shoff = sizeof(Elf32_Ehdr); | ||||||
|  | 	elf_ehdr.e_shoff += elf_shstrtab.cnt +  elf_strtab.cnt; | ||||||
|  | 	elf_ehdr.e_shoff += elf_symtab.cnt; | ||||||
|  | 
 | ||||||
|  | 	if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: An error occurred while writting elf header", file); | ||||||
|  | 		goto end; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (elf_write_tab(&elf_shstrtab, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: An error occured while writting .shstrtab data", file); | ||||||
|  | 		goto end; | ||||||
|  | 	} | ||||||
|  | 	if (elf_write_tab(&elf_strtab, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: An error occured while writting .strtab data", file); | ||||||
|  | 		goto end; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (elf_write_tab(&elf_symtab, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: An error occured while writting .symtab data", file); | ||||||
|  | 		goto end; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* section headers */ | ||||||
|  | 	elf_compute_section_offsets(); | ||||||
|  | 	/* XXX: fix me */ | ||||||
|  | 	elf_shdrs[SEC_SYMTAB].sh_info = 0; /* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/ | ||||||
|  | 
 | ||||||
|  | 	if (fwrite(elf_shdrs, sizeof(Elf32_Shdr), SEC_END, fp) != SEC_END) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: An error occured while writting sections headers", file); | ||||||
|  | 		goto end; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	status = 0; | ||||||
|  | end: | ||||||
|  | 	fclose(fp); | ||||||
|  | 	return (status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | elf_cleanup(void) | ||||||
|  | { | ||||||
|  | 	buffer_cleanup(&elf_shstrtab); | ||||||
|  | 	buffer_cleanup(&elf_strtab); | ||||||
|  | 	buffer_cleanup(&elf_symtab); | ||||||
|  | } | ||||||
							
								
								
									
										192
									
								
								bin/fas2sym/fas.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								bin/fas2sym/fas.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,192 @@ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <fas.h> | ||||||
|  | #include <elf.h> | ||||||
|  | #include "fas2sym.h" | ||||||
|  | 
 | ||||||
|  | static FAS_Hdr fas_hdr; | ||||||
|  | static char *fas_strtab = NULL; | ||||||
|  | static FAS_Sym *fas_symtab = NULL; | ||||||
|  | static uint8_t *fas_psrc = NULL; | ||||||
|  | static size_t fas_sym_cnt = 0; | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | pstr2cstr(char *dst, const uint8_t *src) | ||||||
|  | { | ||||||
|  | 	size_t psz; | ||||||
|  | 
 | ||||||
|  | 	psz = *src++; | ||||||
|  |     while (psz > 0) | ||||||
|  | 	{ | ||||||
|  | 		*dst++ = *src++; | ||||||
|  | 		psz--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*dst = '\0'; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | fas_load_table(uint8_t **dest, size_t offset, size_t size, FILE *fp) | ||||||
|  | { | ||||||
|  | 	if (size == 0) | ||||||
|  | 	{ | ||||||
|  | 		return (0); /* XXX */ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*dest = (uint8_t *)malloc(size); | ||||||
|  | 	if (*dest == NULL) | ||||||
|  | 	{ | ||||||
|  | 		msg_err(NULL); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fseek(fp, offset, SEEK_SET) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_err(NULL); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fread(*dest, size, 1, fp) != 1) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("An unexpected error/eof occured while reading"); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | fas_load_file(const char *file) | ||||||
|  | { | ||||||
|  | 	FILE *fp; | ||||||
|  | 
 | ||||||
|  | 	fp = fopen(file, "rb"); | ||||||
|  | 	if (fp == NULL) | ||||||
|  | 	{ | ||||||
|  | 		msg_err(file); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fread(&fas_hdr, sizeof(FAS_Hdr), 1, fp) != 1) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: unexpected error/eof while reading FAS header", | ||||||
|  | 				 file); | ||||||
|  | 		goto err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fas_hdr.magic != FAS_MAGIC) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: invalid magic, got '%08" PRIX32 | ||||||
|  | 				 "' instead of '%08" PRIX32 "'", | ||||||
|  | 				 file, (uint32_t)FAS_MAGIC); | ||||||
|  | 		goto err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fas_load_table((uint8_t **)&fas_strtab, fas_hdr.strtab_off, | ||||||
|  | 					   fas_hdr.strtab_len, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: can't load string table", file); | ||||||
|  | 		goto err_cleanup; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fas_load_table((uint8_t **)&fas_symtab, fas_hdr.symtab_off, | ||||||
|  | 					   fas_hdr.symtab_len, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		msg_errx("%s: can't load symbol table", file); | ||||||
|  | 		goto err_cleanup; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fas_load_table(&fas_psrc, fas_hdr.psrc_off, fas_hdr.psrc_len, | ||||||
|  | 					   fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 	    msg_errx("%s: can't load preprocessed sources", file); | ||||||
|  | 		goto err_cleanup; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fas_sym_cnt = fas_hdr.symtab_len / sizeof(FAS_Sym); | ||||||
|  | 
 | ||||||
|  | 	msg_verbose(1, "%zu symbol(s) loaded from %s", fas_sym_cnt, file); | ||||||
|  | 
 | ||||||
|  | 	fclose(fp); | ||||||
|  | 	return (0); | ||||||
|  | 
 | ||||||
|  | err_cleanup: | ||||||
|  | 	fas_cleanup(); | ||||||
|  | err: | ||||||
|  | 	fclose(fp); | ||||||
|  | 	return (-1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint32_t | ||||||
|  | fas_export_symbol_name(uint32_t name_off) | ||||||
|  | { | ||||||
|  | 	size_t idx = 0; | ||||||
|  | 	char *ptr; | ||||||
|  | 	char name[256] = { 0 }; | ||||||
|  | 
 | ||||||
|  | 	if (name_off == 0) | ||||||
|  | 	{ | ||||||
|  | 		return (0); /* anonymous symbol */ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (name_off & (1<<31)) /* if in fas strtab */ | ||||||
|  | 	{ | ||||||
|  | 		ptr = fas_strtab + (name_off & ~(1<<31)); /* XXX */ | ||||||
|  | 	} | ||||||
|  | 	else /* otherwhise it's in psrc */ | ||||||
|  | 	{ | ||||||
|  | 		pstr2cstr(name, fas_psrc + name_off); | ||||||
|  | 		ptr = name; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (elf_add_str(ptr, strlen(ptr) + 1, &idx) != 0) | ||||||
|  | 	{ | ||||||
|  | 		/* error occured */ | ||||||
|  | 		return (0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (idx); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | fas_export_symbols(void) | ||||||
|  | { | ||||||
|  | 	size_t idx; | ||||||
|  | 	char *name_ptr; | ||||||
|  |     size_t name_idx; | ||||||
|  | 
 | ||||||
|  | 	/* export file name symbol */ | ||||||
|  | 	name_ptr = fas_strtab + fas_hdr.ifnm_off; | ||||||
|  | 	elf_add_str(name_ptr, strlen(name_ptr) + 1, &name_idx); | ||||||
|  | 	elf_add_symbol(name_idx, 0, 0, ELF32_ST_INFO(STB_LOCAL, STT_FILE), | ||||||
|  | 				   SHN_ABS); | ||||||
|  | 
 | ||||||
|  | 	/* export other symbol */ | ||||||
|  | 	for (idx = 0; idx < fas_sym_cnt; idx++) | ||||||
|  | 	{ | ||||||
|  | 		if ((fas_symtab[idx].flags & FAS_SYM_DEF) == 0 || | ||||||
|  | 			fas_symtab[idx].flags & FAS_SYM_ASM_TIME) | ||||||
|  | 		{ | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		name_idx = fas_export_symbol_name(fas_symtab[idx].name_off); | ||||||
|  | 
 | ||||||
|  | 		elf_add_symbol(name_idx, fas_symtab[idx].value, 0, | ||||||
|  | 					   ELF32_ST_INFO(STB_LOCAL, STT_OBJECT), SHN_ABS); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | fas_cleanup(void) | ||||||
|  | { | ||||||
|  | 	free(fas_psrc); | ||||||
|  | 	fas_psrc = NULL; | ||||||
|  | 	free(fas_symtab); | ||||||
|  | 	fas_symtab = NULL; | ||||||
|  | 	free(fas_strtab); | ||||||
|  | 	fas_strtab = NULL; | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								bin/fas2sym/fas2sym.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								bin/fas2sym/fas2sym.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | #ifndef FAS2SYM_H | ||||||
|  | # define FAS2SYM_H 1 | ||||||
|  | 
 | ||||||
|  | # include <stddef.h> | ||||||
|  | # include <stdint.h> | ||||||
|  | # include <stdarg.h> | ||||||
|  | 
 | ||||||
|  | struct buffer { | ||||||
|  | 	size_t cap; | ||||||
|  | 	size_t cnt; | ||||||
|  | 	uint8_t *data; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* buffer.c */ | ||||||
|  | int buffer_put(struct buffer *buff, const uint8_t *data, | ||||||
|  | 			   size_t size, size_t *index); | ||||||
|  | void buffer_cleanup(struct buffer *buff); | ||||||
|  | 
 | ||||||
|  | /* fas.c */ | ||||||
|  | int fas_load_file(const char *file); | ||||||
|  | void fas_export_symbols(void); | ||||||
|  | void fas_cleanup(void); | ||||||
|  | 
 | ||||||
|  | /* elf.c */ | ||||||
|  | int elf_init(void); | ||||||
|  | int elf_add_str(const char *str, size_t len, size_t *idx); | ||||||
|  | int elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size, | ||||||
|  | 				   uint8_t info, uint16_t sect); | ||||||
|  | int elf_write(const char *file); | ||||||
|  | void elf_cleanup(void); | ||||||
|  | 
 | ||||||
|  | /* main.c */ | ||||||
|  | void msg_err(const char *fmt, ...); | ||||||
|  | void msg_errx(const char *fmt, ...); | ||||||
|  | void msg_verbose(int level, const char *fmt, ...); | ||||||
|  | 
 | ||||||
|  | #endif /* !FAS2SYM_H */ | ||||||
							
								
								
									
										152
									
								
								bin/fas2sym/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								bin/fas2sym/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,152 @@ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <libgen.h> | ||||||
|  | #include "fas2sym.h" | ||||||
|  | 
 | ||||||
|  | static const char *prg_name; | ||||||
|  | static const char *outfile = "out.sym"; | ||||||
|  | static int verbose = 0; | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | msg_err_common(const char *fmt, va_list ap) | ||||||
|  | { | ||||||
|  | 	fprintf(stderr, "%s: ", prg_name); | ||||||
|  | 	if (fmt) | ||||||
|  | 	{ | ||||||
|  | 		vfprintf(stderr, fmt, ap); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | msg_errx(const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  | 
 | ||||||
|  | 	va_start(ap, fmt); | ||||||
|  | 
 | ||||||
|  | 	msg_err_common(fmt, ap); | ||||||
|  | 	fprintf(stderr, "\n"); | ||||||
|  | 
 | ||||||
|  | 	va_end(ap); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | msg_err(const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  | 
 | ||||||
|  | 	va_start(ap, fmt); | ||||||
|  | 
 | ||||||
|  | 	msg_err_common(fmt, ap); | ||||||
|  | 	if (fmt) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, ": "); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fprintf(stderr, "%s\n", strerror(errno)); | ||||||
|  | 
 | ||||||
|  | 	va_end(ap); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | msg_verbose(int level, const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list ap; | ||||||
|  | 
 | ||||||
|  | 	va_start(ap, fmt); | ||||||
|  | 	if (level <= verbose) | ||||||
|  | 	{ | ||||||
|  | 		vprintf(fmt, ap); | ||||||
|  | 		printf("\n"); | ||||||
|  | 	} | ||||||
|  | 	va_end(ap); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | usage(int retval) | ||||||
|  | { | ||||||
|  | 	if (retval == EXIT_FAILURE) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "Try '%s -h' for more information.\n", | ||||||
|  | 				prg_name); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		printf("Usage: %s [-o OUTPUT] file\n", prg_name); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	exit(retval); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | version(void) | ||||||
|  | { | ||||||
|  | 	printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT); | ||||||
|  | 
 | ||||||
|  | 	exit(EXIT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | main(int argc, char **argv) | ||||||
|  | { | ||||||
|  | 	int c; | ||||||
|  | 	int status; | ||||||
|  | 
 | ||||||
|  | 	prg_name = basename(argv[0]); | ||||||
|  | 
 | ||||||
|  | 	while ((c = getopt(argc, argv, "hvVo:")) != -1) | ||||||
|  | 	{ | ||||||
|  | 		switch (c) | ||||||
|  | 		{ | ||||||
|  | 		case 'h': | ||||||
|  | 			usage(EXIT_SUCCESS); | ||||||
|  | 			break; | ||||||
|  | 		case 'V': | ||||||
|  | 			version(); | ||||||
|  | 			break; | ||||||
|  | 		case 'v': | ||||||
|  | 			verbose++; | ||||||
|  | 			break; | ||||||
|  | 		case 'o': | ||||||
|  | 			outfile = optarg; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			usage(EXIT_FAILURE); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (optind >= argc) | ||||||
|  | 	{ | ||||||
|  | 		usage(EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fas_load_file(argv[optind]) != 0) | ||||||
|  | 	{ | ||||||
|  | 		return (EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	status = EXIT_FAILURE; | ||||||
|  | 
 | ||||||
|  | 	if (elf_init() != 0) | ||||||
|  | 	{ | ||||||
|  | 		goto cleanup; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fas_export_symbols(); | ||||||
|  | 
 | ||||||
|  | 	if (elf_write(outfile) != 0) | ||||||
|  | 	{ | ||||||
|  | 		goto cleanup; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	status = EXIT_SUCCESS; | ||||||
|  | cleanup: | ||||||
|  | 	elf_cleanup(); | ||||||
|  | 	fas_cleanup(); | ||||||
|  | 
 | ||||||
|  | 	return (status); | ||||||
|  | } | ||||||
							
								
								
									
										338
									
								
								bin/fasdump/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								bin/fasdump/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,338 @@ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <inttypes.h> | ||||||
|  | #include <fas.h> | ||||||
|  | 
 | ||||||
|  | struct buff { | ||||||
|  | 	size_t size; | ||||||
|  | 	uint8_t *data; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static char *prg_name = "fasdump"; | ||||||
|  | static struct fas_header hdr; | ||||||
|  | static struct buff strtab = { 0, NULL }; | ||||||
|  | static struct buff symtab = { 0, NULL }; | ||||||
|  | static struct buff psrc = { 0, NULL }; | ||||||
|  | static struct buff asmdmp = { 0, NULL }; | ||||||
|  | static struct buff sectab = { 0, NULL }; | ||||||
|  | static struct buff symref = { 0, NULL }; | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | version(void) | ||||||
|  | { | ||||||
|  | 	printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT); | ||||||
|  | 	exit(EXIT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | usage(int retval) | ||||||
|  | { | ||||||
|  | 	if (retval == EXIT_FAILURE) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "Try '%s -h' for more informations.", prg_name); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	exit(retval); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | readall(uint8_t *dest, size_t size, FILE *fp) | ||||||
|  | { | ||||||
|  | 	size_t total; | ||||||
|  | 	size_t byte_read; | ||||||
|  | 
 | ||||||
|  | 	total = 0; | ||||||
|  | 	do | ||||||
|  | 	{ | ||||||
|  | 		byte_read = fread(dest + total, 1, size - total, fp); | ||||||
|  | 		if (byte_read == 0) | ||||||
|  | 		{ | ||||||
|  | 			return (-1); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		total += byte_read; | ||||||
|  | 	} | ||||||
|  | 	while (total < size); | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | load_table(struct buff *dst, size_t off, size_t len, FILE *fp) | ||||||
|  | { | ||||||
|  | 	dst->size = len; | ||||||
|  | 	if (len == 0) | ||||||
|  | 	{ | ||||||
|  | 		return (0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dst->data = (uint8_t *)malloc(len); | ||||||
|  | 	if (dst->data == NULL) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (fseek(fp, off, SEEK_SET) != 0) | ||||||
|  | 	{ | ||||||
|  | 		goto clean_up; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (readall(dst->data, len, fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		goto clean_up; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | 
 | ||||||
|  | clean_up: | ||||||
|  | 	free(dst->data); | ||||||
|  | 	dst->size = 0; | ||||||
|  | 	return (-1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | read_header(FILE *fp) | ||||||
|  | { | ||||||
|  | 	if (readall((uint8_t *)&hdr, sizeof(struct fas_header), fp) != 0) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (hdr.magic != FAS_MAGIC) | ||||||
|  | 	{ | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline char * | ||||||
|  | strtab_get(size_t off) | ||||||
|  | { | ||||||
|  | 	if (off > strtab.size) | ||||||
|  | 	{ | ||||||
|  | 		return (NULL); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (strtab.data + off); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_header(void) | ||||||
|  | { | ||||||
|  | 	printf("FAS Header:\n"); | ||||||
|  | 	printf("  Magic:                %X\n", hdr.magic); | ||||||
|  | 	printf("  Fasm version:         %d.%d\n", hdr.ver_major, | ||||||
|  | 		   hdr.ver_minor); | ||||||
|  | 	printf("  Length:               %hu\n", hdr.length); | ||||||
|  | 	printf("  Input file:           %s\n", strtab_get(hdr.ifnm_off)); | ||||||
|  | 	printf("  Output file:          %s\n", strtab_get(hdr.ofnm_off)); | ||||||
|  | 	printf("  String table offset:  0x%08X\n", hdr.strtab_off); | ||||||
|  | 	printf("  String table length:  %u\n", hdr.strtab_len); | ||||||
|  | 	printf("  Symbol table offset:  0x%08X\n", hdr.symtab_off); | ||||||
|  | 	printf("  Symbol table length:  %u\n", hdr.symtab_len); | ||||||
|  | 	printf("  ASM dump offset:      0x%08X\n", hdr.asmdmp_off); | ||||||
|  | 	printf("  ASM dump length:      %d\n", hdr.asmdmp_len); | ||||||
|  | 	printf("  Section table offset: 0x%08X\n", hdr.sectab_off); | ||||||
|  | 	printf("  Section table length: %d\n", hdr.sectab_len); | ||||||
|  | 	printf("  Symref table offset:  0x%08X\n", hdr.symref_off); | ||||||
|  | 	printf("  Symref table length:  %d\n", hdr.symref_len); | ||||||
|  | 
 | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_sections(void) | ||||||
|  | { | ||||||
|  | 	size_t seccnt; | ||||||
|  | 	size_t idx; | ||||||
|  | 	uint32_t *sec; | ||||||
|  | 
 | ||||||
|  | 	seccnt = sectab.size / sizeof(uint32_t); | ||||||
|  | 	sec = (uint32_t *)sectab.data; | ||||||
|  | 	printf("Section names:\n"); | ||||||
|  | 	for (idx = 0; idx < seccnt; idx++) | ||||||
|  | 	{ | ||||||
|  | 		printf("  %s\n", strtab_get(sec[idx])); | ||||||
|  | 	} | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | pstr2cstr(char *dst, const char *src) | ||||||
|  | { | ||||||
|  | 	size_t plen; | ||||||
|  | 
 | ||||||
|  | 	plen = *src++; | ||||||
|  | 
 | ||||||
|  | 	while (plen > 0) | ||||||
|  | 	{ | ||||||
|  | 		*dst++ = *src++; | ||||||
|  | 		plen--; | ||||||
|  | 	} | ||||||
|  | 	*dst = '\0'; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_sym_name(uint32_t off) | ||||||
|  | { | ||||||
|  | 	char name_str[255] = {0}; | ||||||
|  | 
 | ||||||
|  | 	if (off == 0) | ||||||
|  | 	{ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	if (off & (1<<31)) | ||||||
|  | 	{ | ||||||
|  | 		strncpy(name_str, strtab_get(off & ~(1<<31)), 255); | ||||||
|  | 		name_str[254] = '\0'; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		pstr2cstr(name_str, psrc.data + off); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	printf("%s", name_str); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_sym_section(uint8_t type, uint32_t rel) | ||||||
|  | { | ||||||
|  | 	if (type == FAS_ABS) | ||||||
|  | 	{ | ||||||
|  | 		printf("ABS "); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (rel & (1<<31)) | ||||||
|  | 	{ | ||||||
|  | 		printf("UND "); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		printf("%-3" PRIu32 " %-2" PRIu8 " ", rel, type); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | /*
 | ||||||
|  | static const char * | ||||||
|  | get_symbol_type(uint8_t type) | ||||||
|  | { | ||||||
|  | 	switch (type) | ||||||
|  | 	{ | ||||||
|  | 	case FAS_ABS: | ||||||
|  | 		return ("ABS"); | ||||||
|  | 	case FAS_REL_32: | ||||||
|  | 		return ("REL_32"); | ||||||
|  | 	default: | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ("???"); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | static void | ||||||
|  | print_symbols(void) | ||||||
|  | { | ||||||
|  | 	size_t symcnt; | ||||||
|  | 	size_t idx; | ||||||
|  | 	struct fas_symbol *sym; | ||||||
|  | 
 | ||||||
|  | 	printf("Symbol table:\n"); | ||||||
|  | 	symcnt = symtab.size / sizeof(struct fas_symbol); | ||||||
|  | 	sym = (struct fas_symbol *)symtab.data; | ||||||
|  | 
 | ||||||
|  | 	printf("   Num: Value              Size Ndx Name\n"); | ||||||
|  | 
 | ||||||
|  | 	for (idx = 0; idx < symcnt; idx++) | ||||||
|  | 	{ | ||||||
|  | 		printf("%6d: ", idx); | ||||||
|  | 		printf("0x%016" PRIx64 " ", sym[idx].value); | ||||||
|  | 		printf("%-4" PRIu8 " ", sym[idx].size); | ||||||
|  | 		//printf("%s ", get_symbol_type(sym[idx].type));
 | ||||||
|  | 		print_sym_section(sym[idx].type, sym[idx].reloc); | ||||||
|  | 		print_sym_name(sym[idx].name_off); | ||||||
|  | 		printf("\n"); | ||||||
|  | /*
 | ||||||
|  | 		printf("\t %04" PRIx16 " : ", sym[idx].flags); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_DEF) printf("DEF "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_ASM_TIME) printf("ASM_TIME "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_NOT_FWD_REF) printf("NOT_FWD "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_USED) printf("USED "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_PRD_USED) printf("PRD_USED "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_LPRD_USED) printf("LPRD_USED "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_PRD_DEF) printf("PRD_DEF "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_LPRD_DEF) printf("LPRD_DEF "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_OPT_ADJ) printf("OPT_ADJ "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_TWO_CMPLMNT) printf("TWO_CMPLMNT "); | ||||||
|  | 		if (sym[idx].flags & FAS_SYM_MARKER) printf("MARKER "); | ||||||
|  | 		printf("\n"); | ||||||
|  | */ | ||||||
|  | 		/*printf("%X\n", sym[idx].value);*/ | ||||||
|  | 	} | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_asm_dump(void) | ||||||
|  | { | ||||||
|  | 	struct fas_asmdmp *dmp; | ||||||
|  | 
 | ||||||
|  | 	dmp = (struct fas_asmdmp *)asmdmp.data; | ||||||
|  | 	printf(" 0x%" PRIx32 " 0x%" PRIx64 "\n", dmp->of_off, dmp->addr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | process_file(char *fname) | ||||||
|  | { | ||||||
|  | 	FILE *fp; | ||||||
|  | 
 | ||||||
|  | 	fp = fopen(fname, "rb"); | ||||||
|  | 	if (fp == NULL) | ||||||
|  | 	{ | ||||||
|  | 		return (EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	read_header(fp); | ||||||
|  | 	load_table(&strtab, hdr.strtab_off, hdr.strtab_len, fp); | ||||||
|  | 	load_table(&symtab, hdr.symtab_off, hdr.symtab_len, fp); | ||||||
|  | 	load_table(&psrc, hdr.psrc_off, hdr.psrc_len, fp); | ||||||
|  | 	load_table(&asmdmp, hdr.asmdmp_off, hdr.asmdmp_len, fp); | ||||||
|  | 	load_table(§ab, hdr.sectab_off, hdr.sectab_len, fp); | ||||||
|  | 
 | ||||||
|  | 	print_header(); | ||||||
|  | 	print_sections(); | ||||||
|  | 	print_symbols(); | ||||||
|  | 	print_asm_dump(); | ||||||
|  | 
 | ||||||
|  | 	fclose(fp); | ||||||
|  | 
 | ||||||
|  | 	return (EXIT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	while ((argc > 1) && (argv[1][0] == '-')) | ||||||
|  | 	{ | ||||||
|  | 		switch (argv[1][1]) | ||||||
|  | 		{ | ||||||
|  | 		case 'h': | ||||||
|  | 			usage(EXIT_SUCCESS); | ||||||
|  | 			break; | ||||||
|  | 		case 'V': | ||||||
|  | 			version(); | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			usage(EXIT_FAILURE); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		argv++; | ||||||
|  | 		argc--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (argc <= 1) usage(EXIT_FAILURE); | ||||||
|  | 
 | ||||||
|  | 	return (process_file(argv[1])); | ||||||
|  | } | ||||||
|  | @ -98,7 +98,7 @@ _start: | ||||||
| 
 | 
 | ||||||
| 	jmp .skip_fat | 	jmp .skip_fat | ||||||
| 
 | 
 | ||||||
| 	; fallback to fat12	 | 	; fallback to fat12 | ||||||
| 	; for now fat12 is asumed | 	; for now fat12 is asumed | ||||||
| .fat_fallback: | .fat_fallback: | ||||||
| 	mov si, szMsgFatFallback | 	mov si, szMsgFatFallback | ||||||
|  | @ -129,7 +129,7 @@ _start: | ||||||
| 	xor bx, bx | 	xor bx, bx | ||||||
| 
 | 
 | ||||||
| 	call disk_read_sectors | 	call disk_read_sectors | ||||||
| 	 | 
 | ||||||
| 	; load stage 2 | 	; load stage 2 | ||||||
| 	mov ax, KERNEL_PRELOAD/0x10 | 	mov ax, KERNEL_PRELOAD/0x10 | ||||||
| 	mov es, ax | 	mov es, ax | ||||||
|  | @ -146,7 +146,7 @@ _start: | ||||||
| 	call boot_info_print_mmap | 	call boot_info_print_mmap | ||||||
| 
 | 
 | ||||||
| 	; video information | 	; video information | ||||||
| 	;call video_setup | 	call video_setup | ||||||
| 
 | 
 | ||||||
| 	; load GDT and enter Protected-Mode | 	; load GDT and enter Protected-Mode | ||||||
| 	lgdt [gdt_ptr] | 	lgdt [gdt_ptr] | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ struc VesaInfo | ||||||
| 	.Version               dw ? | 	.Version               dw ? | ||||||
| 	.OEMNamePtr            dd ? | 	.OEMNamePtr            dd ? | ||||||
| 	.Capabilities          dd ? | 	.Capabilities          dd ? | ||||||
| 	.VideoModesPtr         dw ? | 	.VideoModesPtr         dd ? | ||||||
| 	.CountOf64KBlocks      dw ? | 	.CountOf64KBlocks      dw ? | ||||||
| 	.OEMSoftwareRevision   dw ? | 	.OEMSoftwareRevision   dw ? | ||||||
| 	.OEMVendorNamePtr      dd ? | 	.OEMVendorNamePtr      dd ? | ||||||
|  | @ -28,7 +28,7 @@ struc VesaModeInfo | ||||||
| 	.WindowPositioning dd ? | 	.WindowPositioning dd ? | ||||||
| 	.BytesPerScanLine  dw ? | 	.BytesPerScanLine  dw ? | ||||||
| 
 | 
 | ||||||
| 	; --   | 	; -- | ||||||
| 	.Width            dw ? | 	.Width            dw ? | ||||||
| 	.Height           dw ? | 	.Height           dw ? | ||||||
| 	.WidthChar        db ? | 	.WidthChar        db ? | ||||||
|  | @ -72,11 +72,11 @@ video_setup: | ||||||
| 	jne .err | 	jne .err | ||||||
| 	cmp [vesa_block_buffer.Signature], 'VESA' | 	cmp [vesa_block_buffer.Signature], 'VESA' | ||||||
| 	jne .err | 	jne .err | ||||||
| 
 | 	; XXX: fix me | ||||||
| 	push [vesa_block_buffer.OEMProductNamePtr] | 	push word [vesa_block_buffer.OEMProductNamePtr] | ||||||
| 	push [vesa_block_buffer.OEMVendorNamePtr] | 	push word [vesa_block_buffer.OEMVendorNamePtr] | ||||||
| 	push [vesa_block_buffer.CountOf64KBlocks] | 	push word [vesa_block_buffer.CountOf64KBlocks] | ||||||
| 	push [vesa_block_buffer.OEMNamePtr] | 	push word [vesa_block_buffer.OEMNamePtr] | ||||||
| 	xor ecx, ecx | 	xor ecx, ecx | ||||||
| 	mov cx, [vesa_block_buffer.Version] | 	mov cx, [vesa_block_buffer.Version] | ||||||
| 	push ecx | 	push ecx | ||||||
|  | @ -84,7 +84,7 @@ video_setup: | ||||||
| 	call bios_log | 	call bios_log | ||||||
| 
 | 
 | ||||||
| 	mov di, vesa_info_block_buffer | 	mov di, vesa_info_block_buffer | ||||||
| 	mov bx, [vesa_block_buffer.VideoModesPtr] | 	mov ebx, [vesa_block_buffer.VideoModesPtr] | ||||||
| 	mov cx, [bx] | 	mov cx, [bx] | ||||||
| 	cmp cx, 0xFFFF | 	cmp cx, 0xFFFF | ||||||
| 	je .err | 	je .err | ||||||
|  | @ -110,6 +110,7 @@ vesa_block_buffer VesaInfo | ||||||
| vesa_info_block_buffer VesaModeInfo | vesa_info_block_buffer VesaModeInfo | ||||||
| 
 | 
 | ||||||
| szMsgVesaInfo db "Version: %x", CR, LF, "OEM Name: %s", CR, LF, "Total Memory: %d", CR, LF, "Vendor name: %s", CR, LF, "Product name: %s", 0 | szMsgVesaInfo db "Version: %x", CR, LF, "OEM Name: %s", CR, LF, "Total Memory: %d", CR, LF, "Vendor name: %s", CR, LF, "Product name: %s", 0 | ||||||
|  | szMsgVesaModeInfo db "%dx%dx%d", CR, LF, 0 | ||||||
| szMsgDetectVideo db "Fetch video information.", 0 | szMsgDetectVideo db "Fetch video information.", 0 | ||||||
| szMsgFramebuffer db "Fb: %x", 0 | szMsgFramebuffer db "Fb: %x", 0 | ||||||
| szMsgErrorVesa db "Failed to detect VBE mode", 0 | szMsgErrorVesa db "Failed to detect VBE mode", 0 | ||||||
|  |  | ||||||
							
								
								
									
										192
									
								
								include/elf.h
									
										
									
									
									
								
							
							
						
						
									
										192
									
								
								include/elf.h
									
										
									
									
									
								
							|  | @ -1,23 +1,189 @@ | ||||||
| #ifndef ELF_H | #ifndef ELF_H | ||||||
| # define ELF_H 1 | # define ELF_H 1 | ||||||
| 
 | 
 | ||||||
|  | /* spec: https://refspecs.linuxfoundation.org/elf/elf.pdf
 | ||||||
|  |  *       elf(5) | ||||||
|  |  */ | ||||||
| # include <stdint.h> | # include <stdint.h> | ||||||
| 
 | 
 | ||||||
| # define ELF_MAG0 0x7F | # define ELFMAG0 0x7F | ||||||
| # define ELF_MAG1 0x45 | # define ELFMAG1 0x45 | ||||||
| # define ELF_MAG2 0x4C | # define ELFMAG2 0x4C | ||||||
| # define ELF_MAG3 0x46 | # define ELFMAG3 0x46 | ||||||
| 
 | 
 | ||||||
| # define EI_NIDENT 16 | # 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_VERSION 6 | ||||||
|  | # define EI_PAD     7 | ||||||
|  | # define EI_NIDENT  16 | ||||||
| 
 | 
 | ||||||
| struct elf_header  | # define ET_NONE   0 | ||||||
| { | # define ET_REL    1 | ||||||
| 	uint8_t e_ident[EI_NIDENT]; | # define ET_EXEC   2 | ||||||
| 	uint16_t e_type; | # define ET_DYN    3 | ||||||
| 	uint16_t e_machine; | # define ET_CORE   4 | ||||||
| 	uint32_t e_version; | # define ET_LOPROC 0xFF00 | ||||||
| }; | # define ET_HIPROC 0xFFFF | ||||||
| 
 | 
 | ||||||
| /* TODO */ | # define EM_NONE        0 | ||||||
|  | # define EM_M32         1 | ||||||
|  | # define EM_SPARC       2 | ||||||
|  | # define EM_386         3 | ||||||
|  | # define EM_68K         4 | ||||||
|  | # define EM_88K         5 | ||||||
|  | # define EM_860         7 | ||||||
|  | # define EM_MIPS        8 | ||||||
|  | # define EM_MIPS_RS4_BE 10 | ||||||
|  | 
 | ||||||
|  | # define EV_NONE    0 | ||||||
|  | # define EV_CURRENT 1 | ||||||
|  | 
 | ||||||
|  | # define ELFCLASSNONE 0 | ||||||
|  | # define ELFCLASS32   1 | ||||||
|  | # define ELFCLASS64   2 | ||||||
|  | 
 | ||||||
|  | # define ELFDATANONE 0 | ||||||
|  | # define ELFDATA2LSB 1 | ||||||
|  | # define ELFDATA2MSB 2 | ||||||
|  | 
 | ||||||
|  | typedef uint32_t Elf32_Addr; | ||||||
|  | typedef uint16_t Elf32_Half; | ||||||
|  | typedef uint32_t Elf32_Off; | ||||||
|  | typedef int32_t  Elf32_Sword; | ||||||
|  | typedef uint32_t Elf32_Word; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	uint8_t    e_ident[EI_NIDENT]; | ||||||
|  | 	Elf32_Half e_type; | ||||||
|  |     Elf32_Half e_machine; | ||||||
|  |     Elf32_Word e_version; | ||||||
|  | 	Elf32_Addr e_entry; | ||||||
|  |     Elf32_Off  e_phoff; | ||||||
|  | 	Elf32_Off  e_shoff; | ||||||
|  | 	Elf32_Word e_flags; | ||||||
|  | 	Elf32_Half e_ehsize; | ||||||
|  | 	Elf32_Half e_phentsize; | ||||||
|  | 	Elf32_Half e_phnum; | ||||||
|  | 	Elf32_Half e_shentsize; | ||||||
|  | 	Elf32_Half e_shnum; | ||||||
|  |     Elf32_Half e_shstrndx; | ||||||
|  | } Elf32_Ehdr; | ||||||
|  | 
 | ||||||
|  | # define SHN_UNDEF     0 | ||||||
|  | # define SHN_LORESERVE 0xFF00 | ||||||
|  | # define SHN_LOPROC    0xFF00 | ||||||
|  | # define SHN_HIPROC    0xFF1F | ||||||
|  | # define SHN_ABS       0xFFF1 | ||||||
|  | # define SHN_COMMON    0xFFF2 | ||||||
|  | # define SHN_HIRESERVE 0xFFFF | ||||||
|  | 
 | ||||||
|  | # define SHT_NULL     0 | ||||||
|  | # define SHT_PROGBITS 1 | ||||||
|  | # define SHT_SYMTAB   2 | ||||||
|  | # define SHT_STRTAB   3 | ||||||
|  | # define SHT_RELA     4 | ||||||
|  | # define SHT_HASH     5 | ||||||
|  | # define SHT_DYNAMIC  6 | ||||||
|  | # define SHT_NOTE     7 | ||||||
|  | # define SHT_NOBITS   8 | ||||||
|  | # define SHT_REL      9 | ||||||
|  | # define SHT_SHLIB    10 | ||||||
|  | # define SHT_DYNSYM   11 | ||||||
|  | # define SHT_LOPROC   0x70000000 | ||||||
|  | # define SHT_HIPROC   0x7FFFFFFF | ||||||
|  | # define SHT_LOUSER   0x80000000 | ||||||
|  | # define SHT_HIUSER   0xFFFFFFFF | ||||||
|  | 
 | ||||||
|  | # define SHF_WRITE     0x1 | ||||||
|  | # define SHF_ALLOC     0x2 | ||||||
|  | # define SHF_EXECINSTR 0x4 | ||||||
|  | # define SHF_MASKPROC  0xF0000000 | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Elf32_Word sh_name; | ||||||
|  | 	Elf32_Word sh_type; | ||||||
|  | 	Elf32_Word sh_flags; | ||||||
|  | 	Elf32_Addr sh_addr; | ||||||
|  | 	Elf32_Off  sh_offset; | ||||||
|  | 	Elf32_Word sh_size; | ||||||
|  | 	Elf32_Word sh_link; | ||||||
|  | 	Elf32_Word sh_info; | ||||||
|  | 	Elf32_Word sh_addralign; | ||||||
|  | 	Elf32_Word sh_entsize; | ||||||
|  | } Elf32_Shdr; | ||||||
|  | 
 | ||||||
|  | # define STN_UNDER 0 | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     Elf32_Word st_name; | ||||||
|  | 	Elf32_Addr st_value; | ||||||
|  | 	Elf32_Word st_size; | ||||||
|  | 	uint8_t    st_info; | ||||||
|  | 	uint8_t    st_other; | ||||||
|  | 	Elf32_Half st_shndx; | ||||||
|  | } Elf32_Sym; | ||||||
|  | 
 | ||||||
|  | # define ELF32_ST_BIND(x)    ((x)>>4) | ||||||
|  | # define ELF32_ST_TYPE(x)    ((x)&0xf) | ||||||
|  | # define ELF32_ST_INFO(b, t) (((b)<<4)+((t)&0xf)) | ||||||
|  | 
 | ||||||
|  | # define STB_LOCAL   0 | ||||||
|  | # define STB_GLOBAL  1 | ||||||
|  | # define STB_WEAK    2 | ||||||
|  | # define STB_LOPROC  13 | ||||||
|  | # define STB_HIPROC  15 | ||||||
|  | 
 | ||||||
|  | # define STT_NOTYPE  0 | ||||||
|  | # define STT_OBJECT  1 | ||||||
|  | # define STT_FUNC    2 | ||||||
|  | # define STT_SECTION 3 | ||||||
|  | # define STT_FILE    4 | ||||||
|  | # define STT_LOPROC  13 | ||||||
|  | # define STT_HIPROC  15 | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Elf32_Addr r_offset; | ||||||
|  | 	Elf32_Word r_info; | ||||||
|  | } Elf32_Rel; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Elf32_Addr  r_offset; | ||||||
|  | 	Elf32_Word  r_info; | ||||||
|  | 	Elf32_Sword r_addend; | ||||||
|  | } Elf32_Rela; | ||||||
|  | 
 | ||||||
|  | # define ELF32_R_SYM(x)    ((x)>>8) | ||||||
|  | # define ELF32_R_TYPE(x)   ((uint8_t)(i)); | ||||||
|  | # define ELF32_R_INFO(s,t) (((s)<<8)+(uint8_t)(t)) | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	Elf32_Word p_type; | ||||||
|  | 	Elf32_Off  p_offset; | ||||||
|  | 	Elf32_Addr p_vaddr; | ||||||
|  | 	Elf32_Addr p_paddr; | ||||||
|  | 	Elf32_Word p_filesz; | ||||||
|  | 	Elf32_Word p_memsz; | ||||||
|  | 	Elf32_Word p_flags; | ||||||
|  | 	Elf32_Word p_align; | ||||||
|  | } Elf32_Phdr; | ||||||
|  | 
 | ||||||
|  | # define PT_NULL    0 | ||||||
|  | # define PT_LOAD    1 | ||||||
|  | # define PT_DYNAMIC 2 | ||||||
|  | # define PT_INTERP  3 | ||||||
|  | # define PT_NOTE    4 | ||||||
|  | # define PT_SHLIB   5 | ||||||
|  | # define PT_PHDR    6 | ||||||
|  | # define PT_LOPROC  0x70000000 | ||||||
|  | # define PT_HIPROC  0x7FFFFFFF | ||||||
|  | 
 | ||||||
|  | # define PF_X        0x1 | ||||||
|  | # define PF_W        0x2 | ||||||
|  | # define PF_R        0x4 | ||||||
|  | # define PF_MASKPROC 0xF0000000 | ||||||
| 
 | 
 | ||||||
| #endif /* !ELF_H */ | #endif /* !ELF_H */ | ||||||
|  |  | ||||||
							
								
								
									
										140
									
								
								include/fas.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								include/fas.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,140 @@ | ||||||
|  | #ifndef FAS_H | ||||||
|  | # define FAS_H 1 | ||||||
|  | 
 | ||||||
|  | # include <stdint.h> | ||||||
|  | 
 | ||||||
|  | # define FAS_MAGIC 0x1A736166 | ||||||
|  | 
 | ||||||
|  | typedef struct fas_header | ||||||
|  | { | ||||||
|  | 	uint32_t magic; | ||||||
|  | 	uint8_t  ver_major; | ||||||
|  | 	uint8_t  ver_minor; | ||||||
|  | 	uint16_t length; | ||||||
|  | 	uint32_t ifnm_off; | ||||||
|  | 	uint32_t ofnm_off; | ||||||
|  | 	uint32_t strtab_off; | ||||||
|  | 	uint32_t strtab_len; | ||||||
|  | 	uint32_t symtab_off; | ||||||
|  | 	uint32_t symtab_len; | ||||||
|  | 	uint32_t psrc_off; | ||||||
|  | 	uint32_t psrc_len; | ||||||
|  | 	uint32_t asmdmp_off; | ||||||
|  | 	uint32_t asmdmp_len; | ||||||
|  | 	uint32_t sectab_off; | ||||||
|  | 	uint32_t sectab_len; | ||||||
|  | 	uint32_t symref_off; | ||||||
|  | 	uint32_t symref_len; | ||||||
|  | } FAS_Hdr; | ||||||
|  | 
 | ||||||
|  | # define FAS_SYM_DEF         0x001 | ||||||
|  | # define FAS_SYM_ASM_TIME    0x002 | ||||||
|  | # define FAS_SYM_NOT_FWD_REF 0x004 | ||||||
|  | # define FAS_SYM_USED        0x008 | ||||||
|  | # define FAS_SYM_PRD_USED    0x010 | ||||||
|  | # define FAS_SYM_LPRD_USED   0x020 | ||||||
|  | # define FAS_SYM_PRD_DEF     0x040 | ||||||
|  | # define FAS_SYM_LPRD_DEF    0x080 | ||||||
|  | # define FAS_SYM_OPT_ADJ     0x100 | ||||||
|  | # define FAS_SYM_TWO_CMPLMNT 0x200 | ||||||
|  | # define FAS_SYM_MARKER      0x400 | ||||||
|  | 
 | ||||||
|  | enum fas_symbol_type | ||||||
|  | { | ||||||
|  | 	FAS_ABS, | ||||||
|  | 	FAS_REL_SEG, | ||||||
|  | 	FAS_REL_32, | ||||||
|  | 	FAS_REL_R_32, | ||||||
|  | 	FAS_REL_64, | ||||||
|  | 	FAS_GOT_32, | ||||||
|  | 	FAS_PLT_32, | ||||||
|  | 	FAS_PLT_R_32 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef struct fas_symbol | ||||||
|  | { | ||||||
|  | 	uint64_t value; | ||||||
|  | 	uint16_t flags; | ||||||
|  | 	uint8_t  size; | ||||||
|  | 	uint8_t  type; | ||||||
|  | 	uint32_t ext_SIB; | ||||||
|  | 	uint16_t pass_ldef; | ||||||
|  | 	uint16_t pass_lused; | ||||||
|  | 	uint32_t reloc; | ||||||
|  | 	uint32_t name_off; | ||||||
|  | 	uint32_t psrc_line_off; | ||||||
|  | } FAS_Sym; | ||||||
|  | 
 | ||||||
|  | struct fas_psrc_line | ||||||
|  | { | ||||||
|  | 	uint32_t from; | ||||||
|  | 	uint32_t lineno; | ||||||
|  | 	uint32_t src_off; | ||||||
|  | 	uint32_t macro_off; | ||||||
|  | 	uint8_t  tokens[]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum fas_code | ||||||
|  | { | ||||||
|  | 	FAS_CODE_16 = 16, | ||||||
|  | 	FAS_CODE_32 = 32, | ||||||
|  | 	FAS_CODE_64 = 64 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct fas_asmdmp | ||||||
|  | { | ||||||
|  | 	uint32_t of_off; | ||||||
|  | 	uint32_t psrc_line_off; | ||||||
|  | 	uint64_t addr; | ||||||
|  | 	uint32_t ext_SIB; | ||||||
|  | 	uint32_t reloc; | ||||||
|  | 	uint8_t  type; | ||||||
|  | 	uint8_t  code; | ||||||
|  | 	uint8_t  virt; | ||||||
|  | 	uint8_t  high; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum fas_register | ||||||
|  | { | ||||||
|  | 	FAS_REG_BX   = 0x23, | ||||||
|  | 	FAS_REG_BP   = 0x25, | ||||||
|  | 	FAS_REG_SI   = 0x26, | ||||||
|  | 	FAS_REG_DI   = 0x27, | ||||||
|  | 	FAS_REG_EAX  = 0x40, | ||||||
|  | 	FAS_REG_ECX  = 0x41, | ||||||
|  | 	FAS_REG_EDX  = 0x42, | ||||||
|  | 	FAS_REG_EBX  = 0x43, | ||||||
|  | 	FAS_REG_ESP  = 0x44, | ||||||
|  | 	FAS_REG_EBP  = 0x45, | ||||||
|  | 	FAS_REG_ESI  = 0x46, | ||||||
|  | 	FAS_REG_EDI  = 0x47, | ||||||
|  | 	FAS_REG_R8D  = 0x48, | ||||||
|  | 	FAS_REG_R9D  = 0x49, | ||||||
|  | 	FAS_REG_R10D = 0x4A, | ||||||
|  | 	FAS_REG_R11D = 0x4B, | ||||||
|  | 	FAS_REG_R12D = 0x4C, | ||||||
|  | 	FAS_REG_R13D = 0x4D, | ||||||
|  | 	FAS_REG_R14D = 0x4E, | ||||||
|  | 	FAS_REG_R15D = 0x4F, | ||||||
|  | 	FAS_REG_RAX  = 0x80, | ||||||
|  | 	FAS_REG_RCX  = 0x81, | ||||||
|  | 	FAS_REG_RDX  = 0x82, | ||||||
|  | 	FAS_REG_RBX  = 0x83, | ||||||
|  | 	FAS_REG_RSP  = 0x84, | ||||||
|  | 	FAS_REG_RBP  = 0x85, | ||||||
|  | 	FAS_REG_RSI  = 0x86, | ||||||
|  | 	FAS_REG_RDI  = 0x87, | ||||||
|  | 	FAS_REG_R8   = 0x88, | ||||||
|  | 	FAS_REG_R9   = 0x89, | ||||||
|  | 	FAS_REG_R10  = 0x8A, | ||||||
|  | 	FAS_REG_R11  = 0x8B, | ||||||
|  | 	FAS_REG_R12  = 0x8C, | ||||||
|  | 	FAS_REG_R13  = 0x8D, | ||||||
|  | 	FAS_REG_R14  = 0x8E, | ||||||
|  | 	FAS_REG_R15  = 0x8F, | ||||||
|  | 	FAS_REG_EIP  = 0x94, | ||||||
|  | 	FAS_REG_RIP  = 0x98, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* !FAS_H */ | ||||||
|  | @ -1,4 +1,9 @@ | ||||||
| TARGET	= ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) elf2coff$(EXEXT) ar$(EXEXT) ranlib$(EXEXT) | TARGET	= ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) \
 | ||||||
|  | 			elf2coff$(EXEXT) ar$(EXEXT) ranlib$(EXEXT) \
 | ||||||
|  | 			fasdump$(EXEXT) fas2sym$(EXEXT) | ||||||
|  | 
 | ||||||
|  | FAS2SYM_SRCS = main.c fas.c elf.c buffer.c | ||||||
|  | FAS2SYM_OBJS = $(addprefix ../bin/fas2sym/, $(FAS2SYM_SRCS:.c=.o)) | ||||||
| 
 | 
 | ||||||
| .PHONY: all | .PHONY: all | ||||||
| all: $(TARGET) | all: $(TARGET) | ||||||
|  | @ -21,6 +26,12 @@ ranlib$(EXEXT): ../bin/ranlib/main.c ../bin/ar/archive.c | ||||||
| ar$(EXEXT): ../bin/ar/main.c | ar$(EXEXT): ../bin/ar/main.c | ||||||
| 	$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) | 	$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) | ||||||
| 
 | 
 | ||||||
|  | fasdump$(EXEXT): ../bin/fasdump/main.c | ||||||
|  | 	$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) | ||||||
|  | 
 | ||||||
|  | fas2sym$(EXEXT): $(FAS2SYM_OBJS) | ||||||
|  | 	$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) | ||||||
|  | 
 | ||||||
| .PHONY: install | .PHONY: install | ||||||
| install: $(TARGET) | install: $(TARGET) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue