diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d5d538..8771b9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install build-essential fasm mtools xorriso grub-common + sudo apt-get install build-essential fasm mtools xorriso grub-common wget - name: Build run: | make diff --git a/bin/ar/archive.c b/bin/ar/archive.c new file mode 100644 index 0000000..6106a39 --- /dev/null +++ b/bin/ar/archive.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include "archive.h" + +#ifndef O_BINARY +# define O_BINARY 0 +#endif /* !O_BINARY */ + +# define AR_STR_TO_NUM(to, from, len, buff, base) do { \ + memcpy(buff, from, len); \ + buf[len] = '\0'; \ + to = strtol(buff, NULL, base); \ + } while (0) + +static int +read_data(int fd, void *buff, ssize_t size) +{ + ssize_t rbytes; + ssize_t total; + + total = 0; + while ((rbytes = read(fd, (uint8_t *)(buff) + total, size - total)) != 0) + { + total += rbytes; + if (total >= size) + { + break; + } + } + + return (total); +} + +int +archive_open(const char *path) +{ + int fd; + char buff[SARMAG]; + + if ((fd = open(path, O_RDWR | O_BINARY)) < 0) + { + return (-1); + } + + if (read_data(fd, buff, SARMAG) != SARMAG) + { + goto err; + } + + if (strncmp(ARMAG, buff, SARMAG) != 0) + { + goto err; + } + + return (fd); +err: + close(fd); + return (-1); +} + +int +archive_get_entry_hdr(int fd, struct archive_entry_hdr *entry_hdr) +{ + struct arhdr hdr; + ssize_t res; + char buf[13]; + char *tmp; + + entry_hdr->offset = lseek(fd, 0, SEEK_CUR); + res = read_data(fd, &hdr, sizeof(struct arhdr)); + if (res != sizeof(struct arhdr)) + { + if (res == 0) + { + return (0); + } + else + { + return (-1); + } + } + + if (strncmp(ARFMAG, (char *)hdr.ar_fmag, 2) != 0) + { + return (-1); + } + + AR_STR_TO_NUM(entry_hdr->date, hdr.ar_date, 12, buf, 10); + AR_STR_TO_NUM(entry_hdr->uid, hdr.ar_uid, 6, buf, 10); + AR_STR_TO_NUM(entry_hdr->gid, hdr.ar_gid, 6, buf, 10); + AR_STR_TO_NUM(entry_hdr->mode, hdr.ar_mode, 8, buf, 8); + AR_STR_TO_NUM(entry_hdr->size, hdr.ar_size, 10, buf, 10); + + if (strncmp(AR_EXTNAME, (char *)hdr.ar_name, AR_EXTNAME_SZ) == 0) + { + res = atoi((char *)(hdr.ar_name + AR_EXTNAME_SZ)); + read_data(fd, entry_hdr->name, res); + + entry_hdr->name[res] = '\0'; + entry_hdr->size -= res; + } + else + { + memcpy(entry_hdr->name, hdr.ar_name, 16); + for (tmp = entry_hdr->name + 15; *tmp == ' '; tmp--) + { + *tmp = '\0'; + } + } + + return (1); +} + +size_t +archive_skip_entry(int fd, struct archive_entry_hdr *hdr) +{ + size_t sz; + + sz = hdr->size; + if (hdr->size % 2 != 0) + { + sz++; /* skip 0x0A */ + } + return (lseek(fd, sz, SEEK_CUR)); +} + +int +archive_close(int fd) +{ + return (close(fd)); +} diff --git a/bin/ar/archive.h b/bin/ar/archive.h new file mode 100644 index 0000000..79ae58e --- /dev/null +++ b/bin/ar/archive.h @@ -0,0 +1,25 @@ +#include "ar.h" +#ifndef AR_ARCHIVE_H +# define AR_ARCHIVE_H 1 + +# include + +struct archive_entry_hdr { + unsigned offset; + time_t date; + int gid; + int uid; + uint16_t mode; + size_t size; + char name[255]; +}; + +int archive_open(const char *path); +int archive_close(int fd); +int archive_decode_entry_hdr(struct archive_entry_hdr *dest, struct arhdr *src); +int archive_encode_entry_hdr(struct arhdr *dest, struct archive_entry_hdr *src); +int archive_get_entry_hdr(int fd, struct archive_entry_hdr *entry_hdr); +size_t archive_skip_entry(int fd, struct archive_entry_hdr *entry_hdr); +int archive_copy(); + +#endif /* !AR_ARCHIVE_H */ diff --git a/bin/cmd/builtins.inc b/bin/cmd/builtins.inc index 523e36d..247b3d7 100644 --- a/bin/cmd/builtins.inc +++ b/bin/cmd/builtins.inc @@ -1,6 +1,10 @@ -builtins: - db 2, 'cd' - db 1, '.' - db 3, 'set' - db 5, 'unset' - db 4, 'exit' \ No newline at end of file +public builtins +builtins: + db 2, 'cd' + db 1, '.' + db 3, 'set' + db 5, 'unset' + db 4, 'exit' + +public zz +zz db "xptdr", 0 diff --git a/bin/cmd/cmd.asm b/bin/cmd/cmd.asm index c7318ae..e9dea1a 100644 --- a/bin/cmd/cmd.asm +++ b/bin/cmd/cmd.asm @@ -1,13 +1,26 @@ - format COFF - - section '.text' code - - public main - public _start -_start: -main: - int 0x2A - - section '.data' data - - INCLUDE 'builtins.inc' + format COFF + + section '.text' code + extrn lulz + public main + public _start +_start: + jmp main +main: + call dummy_long_str + int 0x2A + + call lulz + + ret + + public dummy_long_str +dummy_long_str: + xor eax, eax + mov esi, zz + int 0x41 + ret + + section '.data' data + + INCLUDE 'builtins.inc' diff --git a/bin/ranlib/main.c b/bin/ranlib/main.c index 95485db..20641e9 100644 --- a/bin/ranlib/main.c +++ b/bin/ranlib/main.c @@ -1,5 +1,244 @@ -int -main(void) +#include +#include +#include +#include +#include +#include +#include +#include "../ar/archive.h" +#include "ar.h" + +struct rsym { + uint32_t offset; + char *symstr; + + struct rsym *next; + struct rsym **prev; +}; + +#define DEFAULT_MODE 0644 + +static int opt_U = 0; +static const char *tmp_path = "ranlib.XXXXXX"; + +static int +temp_archive(void) { - return 0; + char path[19]; + int fd; + + memcpy(path, tmp_path, 19); + fd = mkstemp(path); + if (fd < 0) + { + perror(path); + return (-1); + } + unlink(path); + return (fd); +} + +static void +coff_addsym(struct rsym **syms, int *symcnt, char *strtab, SYMENT *syment) +{ + struct rsym *sym; + char nbuff[9]; + char *name; + + if (syment->n_scnum < 1 || syment->n_sclass != C_EXT) + { + return; + } + + sym = malloc(sizeof(struct rsym)); + if (sym == NULL) + { + return; + } + + if (syment->n_zeroes == 0) + { + name = strtab + syment->n_offset; + } + else + { + memcpy(nbuff, syment->n_name, 8); + nbuff[8] = '\0'; + + name = nbuff; + } + + +} + +static void +coff_getsym(struct rsym **syms, int *symcnt, int fd, struct archive_entry_hdr *entry) +{ + size_t off; + FILHDR hdr; + char *strtab; + uint32_t strtabsz; + SYMENT syment; + int idx; + + off = lseek(fd, 0, SEEK_CUR); + strtab = NULL; + + if (read(fd, &hdr, FILHSZ) != FILHSZ) + { + goto end; + } + + if (hdr.f_magic != F_MACH_I386 || (hdr.f_flags & F_EXEC) != 0 + || (hdr.f_flags & F_LSYMS) != 0) + { + goto end; + } + + /* load strtab but first we need to skip symtab */ + lseek(fd, off + hdr.f_symptr, SEEK_SET); + for (idx = 0; idx < hdr.f_nsyms; idx++) + { + if (read(fd, &syment, SYMESZ) != SYMESZ) + { + goto end; + } + + /* skip auxent */ + if (syment.n_numaux) + { + lseek(fd, AUXESZ * syment.n_numaux, SEEK_CUR); + } + } + + if (read(fd, &strtabsz, sizeof(uint32_t)) != sizeof(uint32_t)) + { + goto end; + } + + strtab = malloc(strtabsz); + if (strtab == NULL) + { + goto end; + } + + if (read(fd, strtab, strtabsz) != strtabsz) + { + goto end; + } + + /* go back to symtab */ + lseek(fd, off + hdr.f_symptr, SEEK_SET); + for (idx = 0; idx < hdr.f_nsyms; idx++) + { + if (read(fd, &syment, SYMESZ) != SYMESZ) + { + goto end; + } + if (syment.n_numaux) + { + lseek(fd, AUXESZ * syment.n_numaux, SEEK_CUR); + } + + coff_addsym(syms, symcnt, strtab, &syment); + } +end: + free(strtab); + lseek(fd, off, SEEK_SET); +} + +static int +ranlib(const char *archive) +{ + int arfd; + int tmpfd; + struct rsym *syms; + int symcnt; + struct archive_entry_hdr entry; + + syms = NULL; + symcnt = 0; + + if ((arfd = archive_open(archive)) < 0) + { + return (-1); + } + + if ((tmpfd = temp_archive()) < 0) + { + archive_close(arfd); + return (-1); + } + + while (archive_get_entry_hdr(arfd, &entry) > 0) + { + printf("Entry: %s\n", entry.name); + if (strcmp(AR_SYMTAB_NAME, entry.name) == 0) + { + archive_skip_entry(arfd, &entry); + continue; + } + + archive_skip_entry(arfd, &entry); + } + + close(tmpfd); + archive_close(arfd); + + return (0); +} + +static void +usage(int retval) +{ + if (retval == EXIT_FAILURE) + { + fprintf(stderr, "Try 'ranlib -h' for more information.\n"); + } + else + { + printf("Usage: ranlib [-D] [-U] archive...\n"); + printf("\t-h\tdisplay this help and exit\n"); + printf("\t-D\tfill mtime, uid, gid with 0 (DEFAULT)\n"); + printf("\t-U\tinsert the real mtime, uid, gid ...\n"); + } + + exit(retval); +} + +int +main(int argc, char **argv) +{ + int fd; + struct archive_entry_hdr entry_hdr; + + while ((argc > 1) && (argv[1][0] == '-')) + { + switch (argv[1][1]) + { + case 'h': + usage(EXIT_SUCCESS); + break; + case 'D': + opt_U = 0; + break; + case 'U': + opt_U = 1; + break; + } + + argv++; + argc--; + } + + if (argc <= 1) usage(EXIT_FAILURE); + + while (argc > 1) + { + ranlib(argv[1]); + argv++; + argc--; + } + + return (EXIT_SUCCESS); } diff --git a/bin/readcoff/main.c b/bin/readcoff/main.c index 7137765..185cdba 100644 --- a/bin/readcoff/main.c +++ b/bin/readcoff/main.c @@ -62,6 +62,7 @@ static int display_header = 0; static int display_optional_header = 0; static int display_sections = 0; static int display_symbol_table = 0; +static int display_relocs = 0; static void usage(int retval) @@ -95,10 +96,12 @@ main(int argc, char **argv) AOUTHDR aout_header; SCNHDR section_header; SYMENT sym_entry; + RELOC reloc_entry; char name[9]; char *type; FILE *fp; int idx; + int j; time_t timedat; char *string_table; size_t sz_stable; @@ -118,10 +121,20 @@ main(int argc, char **argv) display_optional_header = 1; display_symbol_table = 1; display_sections = 1; + //display_relocs = 1; + break; + case 'r': + display_relocs = 1; break; case 'H': display_header = 1; break; + case 's': + display_symbol_table = 1; + break; + case 'S': + display_sections = 1; + break; case 'h': usage(EXIT_SUCCESS); break; @@ -238,6 +251,32 @@ main(int argc, char **argv) printf("\n"); } + if (display_relocs) + { + for (idx = 0; idx < file_header.f_nscns; idx++) + { + fseek(fp, file_header.f_opthdr + FILHSZ + (SCNHSZ * idx), SEEK_SET); + if (fread(§ion_header, 1, SCNHSZ, fp) != SCNHSZ) + { + return (EXIT_FAILURE); + } + + if (section_header.s_relptr == 0 || section_header.s_nreloc == 0) continue; + + memset(name, 0, 9); + memcpy(name, section_header.s_name, 8); + printf("Relocation for section '%s' at offset 0x%X contains %hu entries:\n", name, section_header.s_relptr, section_header.s_nreloc); + printf(" Address Index Type\n"); + fseek(fp, section_header.s_relptr, SEEK_SET); + for (j = 0; j < section_header.s_nreloc; j++) + { + fread(&reloc_entry, 1, RELSZ, fp); + printf(" %08X %08X %04ho\n", reloc_entry.r_vaddr, reloc_entry.r_symndx, reloc_entry.r_type); + } + printf("\n"); + } + } + if (display_symbol_table) { fseek(fp, 0L, SEEK_END); @@ -248,16 +287,13 @@ main(int argc, char **argv) printf("Symbol table contains %d entries:\n", file_header.f_nsyms); printf(" Num: Value Type Name\n"); assert(sizeof(SYMENT) == SYMESZ); - for (idx = 0; idx <= file_header.f_nsyms; idx++) + for (idx = 0; idx < file_header.f_nsyms; idx++) { fseek(fp, file_header.f_symptr + (SYMESZ * idx), SEEK_SET); fread(&sym_entry, 1, SYMESZ, fp); memset(name, 0, 9); memcpy(name, sym_entry.n_name, 8); - if (sym_entry.n_zeroes == 0) - { - } - printf(" %2d: %08x %hd ", idx, sym_entry.n_value, sym_entry.n_type); + printf(" %2d: %08x %hu %d %hd ", idx, sym_entry.n_value, sym_entry.n_type, sym_entry.n_sclass, sym_entry.n_scnum); if (sym_entry.n_zeroes) { printf("%s\n", name); diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 3338d0b..6c09612 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -280,6 +280,8 @@ common32: or eax, (CR0_PG or CR0_WP) mov cr0, eax + cli ; ensure interrupt are disabled + mov eax, STPDBOOT_MAGIC mov ebx, boot_structure diff --git a/include/ar.h b/include/ar.h index 03bc7aa..14c5c20 100644 --- a/include/ar.h +++ b/include/ar.h @@ -10,6 +10,9 @@ # define AR_SYMTAB_NAME "__.SYMDEF" +# define AR_EXTNAME "#1/" +# define AR_EXTNAME_SZ 3 + typedef struct arhdr { uint8_t ar_name[16]; uint8_t ar_date[12]; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 9c0cf51..98402ee 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -65,11 +65,9 @@ kmain: mov eax, 4 call pmm_alloc - xchg bx, bx mov edx, 4 call pmm_free - xchg bx, bx call pic_init diff --git a/kernel/mm/mm.inc b/kernel/mm/mm.inc index 17b4448..7f76bce 100644 --- a/kernel/mm/mm.inc +++ b/kernel/mm/mm.inc @@ -30,8 +30,6 @@ mm_init: mov ecx, VMEM_VM_BESTFIT call vmem_alloc - xchg bx, bx - ret szVmemKernelName db "kmem", 0 diff --git a/tools/Makefile b/tools/Makefile index f12d9bd..bd09f1e 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -15,7 +15,7 @@ elf2coff$(EXEXT): ../bin/elf2coff/main.c parted$(EXEXT): ../sbin/parted/main.c $(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) -ranlib$(EXEXT): ../bin/ranlib/main.c +ranlib$(EXEXT): ../bin/ranlib/main.c ../bin/ar/archive.c $(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) ar$(EXEXT): ../bin/ar/main.c