diff --git a/bin/fas2sym/elf.c b/bin/fas2sym/elf.c index 0dbd462..436b1a4 100644 --- a/bin/fas2sym/elf.c +++ b/bin/fas2sym/elf.c @@ -1,10 +1,12 @@ #include #include +#include #include #include "fas2sym.h" enum sections { SEC_NULL = 0, + SEC_TEXT, SEC_SHSTRTAB, SEC_STRTAB, SEC_SYMTAB, @@ -17,20 +19,25 @@ static Elf32_Ehdr elf_ehdr = { ELFCLASS32, ELFDATA2LSB, EV_CURRENT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - ET_REL, EM_386, EV_CURRENT, 0, 0, 0, 0, + ET_DYN, 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 }, + /* .text */ + { + 1, SHT_NOBITS, SHF_ALLOC | SHF_EXECINSTR, + 0, 0, 0, SHN_UNDEF, 0, 1, 0 + }, /* .shstrtab */ - { 1, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, + { 7, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, /* .strtab */ - { 11, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, + { 17, SHT_STRTAB, 0, 0, 0, 0, SHN_UNDEF, 0, 1, 0 }, /* .symtab */ { - 19, SHT_SYMTAB, 0, 0, 0, 0, + 25, SHT_SYMTAB, 0, 0, 0, 0, SEC_STRTAB, 0, 4, sizeof(Elf32_Sym) } }; @@ -42,7 +49,7 @@ 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"; + const uint8_t initial[] = "\0.text\0.shstrtab\0.strtab\0.symtab\0"; return (buffer_put(&elf_shstrtab, initial, sizeof(initial), NULL)); } @@ -100,6 +107,8 @@ elf_add_symbol(uint32_t name_off, uint32_t value, uint32_t size, msg_verbose(2, "add symbol: %s", (char *)(elf_strtab.data + name_off)); + elf_shdrs[SEC_SYMTAB].sh_info += 1; + return (buffer_put(&elf_symtab, (uint8_t *)&sym, sizeof(Elf32_Sym), NULL)); } @@ -146,6 +155,55 @@ elf_compute_section_offsets(void) elf_shdrs[SEC_SYMTAB].sh_size = elf_symtab.cnt; } +static void +elf_resolve_symbols(void) +{ + Elf32_Sym *syms; + char *strtab; + size_t idx; + size_t symcnt; + uint32_t begin = 0; + uint32_t end = 0; + + if (text_begin == NULL || text_end == NULL) + { + return; + } + + syms = (Elf32_Sym *)elf_symtab.data; + strtab = (char *)elf_strtab.data; + symcnt = (elf_symtab.cnt / sizeof(Elf32_Sym)); + + for (idx = 0; idx < symcnt; idx++) + { + if (strcmp(strtab + syms[idx].st_name, text_begin) == 0) + { + begin = syms[idx].st_value; + msg_verbose(1, "Sym %s: %X\n", text_begin, begin); + } + else if (strcmp(strtab + syms[idx].st_name, text_end) == 0) + { + end = syms[idx].st_value; + } + + if (begin != 0 && end != 0) + { + break; + } + } + + elf_shdrs[SEC_TEXT].sh_addr = begin; + elf_shdrs[SEC_TEXT].sh_size = end - begin; + + for (idx = 0; idx < symcnt; idx++) + { + if (syms[idx].st_value >= begin && syms[idx].st_value <= end) + { + syms[idx].st_shndx = SEC_TEXT; + } + } +} + int elf_write(const char *file) { @@ -167,6 +225,8 @@ elf_write(const char *file) elf_ehdr.e_shoff += elf_shstrtab.cnt + elf_strtab.cnt; elf_ehdr.e_shoff += elf_symtab.cnt; + elf_resolve_symbols(); + if (fwrite(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fp) != 1) { msg_errx("%s: An error occurred while writting elf header", file); @@ -193,7 +253,7 @@ elf_write(const char *file) /* section headers */ elf_compute_section_offsets(); /* XXX: fix me */ - elf_shdrs[SEC_SYMTAB].sh_info = 0; /* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/ + elf_shdrs[SEC_SYMTAB].sh_info += 1;/*= 0; *//* (elf_symtab.cnt / sizeof(Elf32_Sym)) + 1;*/ if (fwrite(elf_shdrs, sizeof(Elf32_Shdr), SEC_END, fp) != SEC_END) { diff --git a/bin/fas2sym/fas.c b/bin/fas2sym/fas.c index f759000..9724a91 100644 --- a/bin/fas2sym/fas.c +++ b/bin/fas2sym/fas.c @@ -131,9 +131,9 @@ fas_export_symbol_name(uint32_t name_off) return (0); /* anonymous symbol */ } - if (name_off & (1<<31)) /* if in fas strtab */ + if (name_off & (1u<<31)) /* if in fas strtab */ { - ptr = fas_strtab + (name_off & ~(1<<31)); /* XXX */ + ptr = fas_strtab + (name_off & ~(1u<<31)); /* XXX */ } else /* otherwhise it's in psrc */ { diff --git a/bin/fas2sym/fas2sym.h b/bin/fas2sym/fas2sym.h index ab993db..4f90b6a 100644 --- a/bin/fas2sym/fas2sym.h +++ b/bin/fas2sym/fas2sym.h @@ -30,6 +30,9 @@ int elf_write(const char *file); void elf_cleanup(void); /* main.c */ +extern const char *text_begin; +extern const char *text_end; + void msg_err(const char *fmt, ...); void msg_errx(const char *fmt, ...); void msg_verbose(int level, const char *fmt, ...); diff --git a/bin/fas2sym/main.c b/bin/fas2sym/main.c index 4378c12..f52a0b5 100644 --- a/bin/fas2sym/main.c +++ b/bin/fas2sym/main.c @@ -10,6 +10,8 @@ static const char *prg_name; static const char *outfile = "out.sym"; static int verbose = 0; +const char *text_begin = NULL; +const char *text_end = NULL; static void msg_err_common(const char *fmt, va_list ap) @@ -77,6 +79,15 @@ usage(int retval) else { printf("Usage: %s [-o OUTPUT] file\n", prg_name); + printf("OPTIONS:\n"); + printf(" -o OUTPUT Set output file (default: %s)\n", + outfile); + printf(" -t begin,end XXXX (addr or symbol)\n"); + /* + * -t start,end (text) + * -b start,end (bss) + * -d start,end (data) + */ } exit(retval); @@ -95,10 +106,11 @@ main(int argc, char **argv) { int c; int status; + char *tmp; prg_name = basename(argv[0]); - while ((c = getopt(argc, argv, "hvVo:")) != -1) + while ((c = getopt(argc, argv, "hvVo:t:")) != -1) { switch (c) { @@ -114,6 +126,19 @@ main(int argc, char **argv) case 'o': outfile = optarg; break; + case 't': + tmp = strchr(optarg, ','); + if (tmp == NULL) + { + usage(EXIT_FAILURE); + } + + *tmp = '\0'; + text_begin = optarg; + text_end = tmp + 1; + + msg_verbose(2, ".text: %s, %s", text_begin, text_end); + break; default: usage(EXIT_FAILURE); break; diff --git a/bin/fasdump/main.c b/bin/fasdump/main.c index 488c90a..a5aa184 100644 --- a/bin/fasdump/main.c +++ b/bin/fasdump/main.c @@ -185,7 +185,7 @@ print_symbol_section(uint8_t type, uint32_t rel) return; } - if (rel & (1<<31)) + if (rel & (1u<<31)) { printf("UND "); } @@ -204,9 +204,9 @@ print_symbol_name(uint32_t off) { return; } - if (off & (1<<31)) + if (off & (1u<<31)) { - printf("%s", strtab + (off & ~(1<<31))); + printf("%s", strtab + (off & ~(1u<<31))); } else { @@ -230,6 +230,7 @@ print_symbols(void) printf("%-4" PRIu8 " ", symtab[idx].size); print_symbol_section(symtab[idx].type, symtab[idx].reloc); print_symbol_name(symtab[idx].name_off); + /*printf(" %" PRIx8, symtab[idx].flags); */ printf("\n"); } printf("\n"); diff --git a/kernel/Makefile b/kernel/Makefile index 3f89969..fdc2819 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -42,6 +42,8 @@ SRCS = kernel.asm \ bio.inc \ $(ASMINCS) +FAS2SYMFLAGS = -t kmain,kend + .PHONY: const.inc const.inc: const.inc.in @$(VERSION_SH) diff --git a/share/mk/stpd.kernel.mk b/share/mk/stpd.kernel.mk index 9a5c92c..1bd2db9 100644 --- a/share/mk/stpd.kernel.mk +++ b/share/mk/stpd.kernel.mk @@ -11,7 +11,7 @@ $(KERNEL).sys $(KERNEL).fas &: $(SRCS) $(KERNEL).sym: $(KERNEL).fas $(MSG_CREATE) - @$(FAS2SYM) -o $@ $< + @$(FAS2SYM) $(FAS2SYMFLAGS) -o $@ $< .PHONY: install install: $(DESTDIR)/$(KERNEL).sys $(SYMSDIR)/$(KERNEL).sym