diff --git a/Makefile b/Makefile index 963d050d..856cc0a4 100644 --- a/Makefile +++ b/Makefile @@ -45,5 +45,6 @@ force_look: clean: cd bootloader; $(MAKE) clean cd kernel; $(MAKE) clean + cd programs/one; $(MAKE) clean rm -f *.bin rm -f *.flp \ No newline at end of file diff --git a/kernel/include/stl/string.hpp b/kernel/include/stl/string.hpp index 2705bbb7..98c93ca8 100644 --- a/kernel/include/stl/string.hpp +++ b/kernel/include/stl/string.hpp @@ -150,6 +150,10 @@ public: return !_size; } + CharT* c_str(){ + return _data; + } + const CharT* c_str() const { return _data; } diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 64e8a96e..89c3751a 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -1,5 +1,4 @@ -//======================================================================= -// Copyright Baptiste Wicht 2013. + // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -63,7 +62,7 @@ void cat_command(const std::vector& params); void mkdir_command(const std::vector& params); void rm_command(const std::vector& params); void touch_command(const std::vector& params); -void exec_command(const std::vector& params); +void readelf_command(const std::vector& params); void shutdown_command(const std::vector& params); struct command_definition { @@ -95,7 +94,7 @@ command_definition commands[25] = { {"mkdir", mkdir_command}, {"touch", touch_command}, {"rm", rm_command}, - {"exec", exec_command}, + {"readelf", readelf_command}, {"shutdown", shutdown_command}, }; @@ -636,8 +635,123 @@ void rm_command(const std::vector& params){ } } -void exec_command(const std::vector& params){ - //TODO +struct elf_header { + char e_ident[16]; + uint16_t e_type; + uint16_t e_machine; + uint32_t e_version; + uint64_t e_entry; + uint64_t e_phoff; + uint64_t e_shoff; + uint32_t e_flags; + uint16_t e_ehsize; + uint16_t e_phentsize; + uint16_t e_phnum; + uint16_t e_shentsize; + uint16_t e_shnum; + uint16_t e_shstrndx; +}__attribute__((packed)); + +struct program_header { + uint32_t p_type; + uint32_t p_flags; + uint64_t p_offset; + uint64_t p_vaddr; + uint64_t p_paddr; + uint64_t p_filesize; + uint64_t p_memsz; + uint64_t p_align; +}__attribute__((packed)); + +struct section_header { + uint32_t sh_name; + uint32_t sh_type; + uint64_t sh_flags; + uint64_t sh_addr; + uint64_t sh_offset; + uint64_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint64_t sh_addralign; + uint64_t sh_entsize; +}__attribute__((packed)); + +void readelf_command(const std::vector& params){ + if(params.size() < 2){ + k_print_line("Need the name of the executable to read"); + + return; + } + + if(!disks::mounted_partition() || !disks::mounted_disk()){ + k_print_line("Nothing is mounted"); + + return; + } + + auto content = disks::read_file(params[1]); + + if(content.empty()){ + k_print_line("The file does not exist or is empty"); + + return; + } + + auto buffer = content.c_str(); + auto header = reinterpret_cast(buffer); + + if(header->e_ident[0] == 0x7F && header->e_ident[1] == 'E' && + header->e_ident[2] == 'L' && header->e_ident[3] == 'F'){ + + if(header->e_ident[4] == 2){ + k_printf("Number of Program Headers: %u\n", static_cast(header->e_phnum)); + k_printf("Number of Section Headers: %u\n", static_cast(header->e_shnum)); + + auto program_header_table = reinterpret_cast(buffer + header->e_phoff); + auto section_header_table = reinterpret_cast(buffer + header->e_shoff); + + for(size_t p = 0; p < header->e_phnum; ++p){ + auto& p_header = program_header_table[p]; + + k_printf("Program header %u\n", p); + k_printf("\tVirtual Address: %h\n", p_header.p_paddr); + k_printf("\tMemory Size: %u\n", p_header.p_memsz); + k_printf("\tFile Size: %u\n", p_header.p_filesize); + } + + auto& string_table_header = section_header_table[header->e_shstrndx]; + auto string_table = buffer + string_table_header.sh_offset; + + for(size_t s = 0; s < header->e_shnum; ++s){ + auto& s_header = section_header_table[s]; + + k_printf("Section \"%s\"\n", &string_table[s_header.sh_name]); + k_printf("\tVirtual Address: %h\n", s_header.sh_addr); + k_print("\tFlags:"); + + if(s_header.sh_flags & 0x1){ + k_print(" W"); + } + if(s_header.sh_flags & 0x2){ + k_print(" A"); + } + if(s_header.sh_flags & 0x4){ + k_print(" X"); + } + if(s_header.sh_flags & 0x0F000000){ + k_print(" OS"); + } + if(s_header.sh_flags & 0xF0000000){ + k_print(" CPU"); + } + k_print_line(); + } + } else { + k_print_line("Only ELF_64 executables are supported"); + } + } else { + k_print_line("Not and ELF file"); + } } void shutdown_command(const std::vector&){ diff --git a/programs/one/Makefile b/programs/one/Makefile index 5a9bb981..a3d4d9a5 100644 --- a/programs/one/Makefile +++ b/programs/one/Makefile @@ -4,8 +4,12 @@ default: a.out include ../../cpp.mk -a.out: src/main.cpp +%.cpp.o: src/%.cpp $(CC) $(CPP_FLAGS_64) $(WARNING_FLAGS) -c $< -o $@ +a.out: main.cpp.o + $(CC) $(COMMON_LINK_FLAGS) -e main $(CPP_FLAGS_64) -o a.out main.cpp.o + clean: + rm *.cpp.o rm -rf a.out diff --git a/programs/one/a.out b/programs/one/a.out old mode 100644 new mode 100755 index 78d7e000..e3f2b791 Binary files a/programs/one/a.out and b/programs/one/a.out differ