diff --git a/Makefile b/Makefile index 460481b..9ffe07a 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ LDFLAGS := $(LDFLAGS) -g -Os ALL_KERNEL_OBJECT_FILES := $(KERNEL_OBJ) $(ARCH_OBJ) $(LIBC_OBJ) ALL_KERNEL_DEPS := $(ALL_KERNEL_OBJECT_FILES:.o=.d) -all: $(BUILD_DIR)/$(KERNEL_EXEC) +all: $(BUILD_DIR)/$(KERNEL_EXEC) tools -include $(ALL_KERNEL_DEPS) @@ -69,7 +69,7 @@ clean: @rm -rf $(BUILD_DIR) $(BUILD_DIR)/compile_commands.json: - @$(MAKE) clean + @$(MAKE) --no-print-directory clean @printf " \033[1;93mGEN\033[0m Generating compiler database.\n" @@ -77,8 +77,11 @@ $(BUILD_DIR)/compile_commands.json: compile-db: $(BUILD_DIR)/compile_commands.json +tools: + @$(MAKE) --no-print-directory -C tools + include arch/$(ARCH)/extra.mk -.PHONY: all compile-db +.PHONY: all tools compile-db .INTERMEDIATE: $(ARCH_TEMP_FILES) diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..85dc686 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,13 @@ +TOOL_LIST := e64patch + +all: + @for prog in $(TOOL_LIST); do \ + $(MAKE) -C $$prog; \ + done + +clean: + @for prog in $(TOOL_LIST); do \ + $(MAKE) -C $$prog clean; \ + done + +.PHONY: all clean diff --git a/tools/e64patch/Makefile b/tools/e64patch/Makefile new file mode 100644 index 0000000..6ee7f5a --- /dev/null +++ b/tools/e64patch/Makefile @@ -0,0 +1,4 @@ +TOOL_NAME := e64patch + +include ../tool-config.mk +include ../tool-template.mk diff --git a/tools/e64patch/elf.h b/tools/e64patch/elf.h new file mode 100644 index 0000000..35a7066 --- /dev/null +++ b/tools/e64patch/elf.h @@ -0,0 +1,284 @@ +#ifndef USERBOOT_ELF_H_ +#define USERBOOT_ELF_H_ + +#include +#include + +#define ELF_MAG0 0x7f +#define ELF_MAG1 'E' +#define ELF_MAG2 'L' +#define ELF_MAG3 'F' +#define ELF_NIDENT 16 + +#define SHT_NONE 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_DYNAMIC 6 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_DYNSYM 11 + +/** Little endian. */ +#define ELFDATA2LSB (1) + +/** 64-bit. */ +#define ELFCLASS64 (2) + +#define EM_386 (3) +#define EM_X86_64 (62) + +/** ELF current version. */ +#define EV_CURRENT (1) + +/** Dynamic section tags. */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_JMPREL 23 +#define DT_GNU_HASH 0x6ffffef5 +#define DT_AUXILIARY 0x7ffffffd + +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_GOT32X 43 + +#define R_X86_64_64 1 +#define R_X86_64_PC32 2 +#define R_X86_64_GOT32 3 +#define R_X86_64_PLT32 4 +#define R_X86_64_COPY 5 +#define R_X86_64_GLOB_DAT 6 +#define R_X86_64_JUMP_SLOT 7 +#define R_X86_64_RELATIVE 8 +#define R_X86_64_GOTPCREL 9 +#define R_X86_64_32 10 + +#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 + +/* Section flags */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 + +#define SHN_UNDEF 0 + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((elf_word_t)(i)) +#define ELF64_ST_BIND(i) ((i) >> 4) +#define ELF64_ST_TYPE(i) ((i)&0xf) + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_NUM 3 + +typedef uint64_t elf_addr_t; +typedef uint64_t elf_off_t; +typedef uint16_t elf_half_t; +typedef uint32_t elf_word_t; +typedef int32_t elf_sword_t; +typedef uint64_t elf_xword_t; +typedef int64_t elf_sxword_t; + +/** + * ELF file header. + */ +typedef struct { + uint8_t e_ident[ELF_NIDENT]; + elf_half_t e_type; + elf_half_t e_machine; + elf_word_t e_version; + elf_addr_t e_entry; + elf_off_t e_phoff; + elf_off_t e_shoff; + elf_word_t e_flags; + elf_half_t e_ehsize; + elf_half_t e_phentsize; + elf_half_t e_phnum; + elf_half_t e_shentsize; + elf_half_t e_shnum; + elf_half_t e_shstrndx; +} elf_ehdr_t; + +/** + * ELF section header. + */ +typedef struct { + elf_word_t sh_name; + elf_word_t sh_type; + elf_xword_t sh_flags; + elf_addr_t sh_addr; + elf_off_t sh_offset; + elf_xword_t sh_size; + elf_word_t sh_link; + elf_word_t sh_info; + elf_xword_t sh_addralign; + elf_xword_t sh_entsize; +} elf_shdr_t; + +/** + * ELF symbol. + */ +typedef struct { + elf_word_t st_name; + unsigned char st_info; + unsigned char st_other; + elf_half_t st_shndx; + elf_addr_t st_value; + elf_xword_t st_size; +} elf_sym_t; + +/** + * ELF program header. + */ +typedef struct { + elf_word_t p_type; + elf_word_t p_flags; + elf_off_t p_offset; + elf_addr_t p_vaddr; + elf_addr_t p_paddr; + elf_xword_t p_filesz; + elf_xword_t p_memsz; + elf_xword_t p_align; +} elf_phdr_t; + +/** + * Extended ELF relocation information. + */ +typedef struct { + elf_addr_t r_offset; + elf_xword_t r_info; + elf_sxword_t r_addend; +} elf_rela_t; + +/** + * Dynamic section entries + */ +typedef struct { + elf_sxword_t d_tag; + union { + elf_xword_t d_val; + elf_addr_t d_ptr; + } d_un; +} elf_dyn_t; + +/** + * Section header types. + */ +enum elf_stype { + ST_NONE = 0, + ST_PROGBITS = 1, + ST_SYMTAB = 2, + ST_STRTAB = 3, + ST_NOBITS = 8, + ST_REL = 9 +}; + +/** + * Program header types. + */ +enum elf_ptype { + PT_NULL = 0, + PT_LOAD = 1, + PT_DYNAMIC = 2, + PT_INTERP = 3, + PT_NOTE = 4, + PT_SHLIB = 5, + PT_PHDR = 6, + PT_TLS = 7, +}; + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF + +/** + * ELF identification byte locations. + */ +enum elf_ident { + EI_MAG0 = 0, + EI_MAG1 = 1, + EI_MAG2 = 2, + EI_MAG3 = 3, + EI_CLASS = 4, + EI_DATA = 5, + EI_VERSION = 6, + EI_OSABI = 7, + EI_ABIVERSION = 8, + EI_PAD = 9 +}; + +enum elf_type { + ET_NONE = 0, + ET_REL = 1, + ET_EXEC = 2, + ET_DYN = 3, +}; + +#define AT_NULL 0 +#define AT_IGNORE 1 +#define AT_EXECFD 2 +#define AT_PHDR 3 +#define AT_PHENT 4 +#define AT_PHNUM 5 +#define AT_PAGESZ 6 +#define AT_BASE 7 +#define AT_FLAGS 8 +#define AT_ENTRY 9 +#define AT_NOTELF 10 +#define AT_UID 11 +#define AT_EUID 12 +#define AT_GID 13 +#define AT_EGID 14 +#define AT_CLKTCK 17 +#define AT_PLATFORM 15 +#define AT_HWCAP 16 +#define AT_FPUCW 18 +#define AT_DCACHEBSIZE 19 +#define AT_ICACHEBSIZE 20 +#define AT_UCACHEBSIZE 21 +#define AT_IGNOREPPC 22 +#define AT_SECURE 23 +#define AT_BASE_PLATFORM 24 +#define AT_RANDOM 25 +#define AT_HWCAP2 26 +#define AT_EXECFN 31 +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 +#define AT_ENTRY_COUNT 38 + +#endif diff --git a/tools/e64patch/main.c b/tools/e64patch/main.c new file mode 100644 index 0000000..df81f93 --- /dev/null +++ b/tools/e64patch/main.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include "elf.h" + +int main(int argc, const char **argv) +{ + if (argc < 2) { + fprintf(stderr, "no elf file specified.\n"); + return -1; + } + + unsigned long pagesz = sysconf(_SC_PAGESIZE); + + FILE *fp = fopen(argv[1], "r+b"); + if (!fp) { + perror(argv[1]); + return -1; + } + + void *p = mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(fp), 0); + if (p == MAP_FAILED) { + perror("mmap"); + fclose(fp); + return -1; + } + + elf_ehdr_t *elf = p; + elf->e_machine = EM_386; + + munmap(p, pagesz); + fclose(fp); + + printf("patched %s e_machine to EM_386\n", argv[1]); + + return 0; +} diff --git a/tools/tool-config.mk b/tools/tool-config.mk new file mode 100644 index 0000000..ce8ba5a --- /dev/null +++ b/tools/tool-config.mk @@ -0,0 +1,8 @@ + +MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +TOOLS_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH))) + +include $(TOOLS_DIR)/make/gcc-host.mk + +TOOLS_BUILD_DIR := $(TOOLS_DIR)/../build/tools +BUILD_DIR := $(TOOLS_BUILD_DIR)/$(TOOL_NAME) diff --git a/tools/tool-template.mk b/tools/tool-template.mk new file mode 100644 index 0000000..80abc9f --- /dev/null +++ b/tools/tool-template.mk @@ -0,0 +1,22 @@ +BUILD_DIR := $(TOOLS_BUILD_DIR)/$(TOOL_NAME) + +SRC := $(wildcard *.c) +OBJ := $(addprefix $(BUILD_DIR)/,$(SRC:.c=.o)) + +$(BUILD_DIR)/$(TOOL_NAME): $(OBJ) + @mkdir -p $(@D) + + @printf " \033[1;36mHOSTLD\033[0m \033[1mtools/$(TOOL_NAME)\033[0m\n" + @$(CC) $< -o $@ $(CFLAGS) $(LDFLAGS) + +$(BUILD_DIR)/%.o: %.c + @printf " \033[1;32mHOSTCC\033[0m $(TOOL_NAME)/$^\n" + @mkdir -p $(@D) + + @$(CC) $< -o $@ -c $(CFLAGS) + +all: $(TOOL_NAME) + +clean: + @printf " \033[1;93mRM\033[0m Deleting sandbox/$(TOOL_NAME)\n" + @rm -rf $(BUILD_DIR)