diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-06-30 09:41:22 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-06-30 09:41:22 -0700 |
commit | b141a448ce0964f2a854b59a799875b94d2f1ec0 (patch) | |
tree | a8b9498262f3e1652ddb299eb11c583fd69116c5 /subx | |
parent | e1eefb8a8a25312754b64f7b74f76c0ee05cace7 (diff) | |
download | mu-b141a448ce0964f2a854b59a799875b94d2f1ec0.tar.gz |
4289 - beginnings of a translator to ELF
The source 'language' is still entirely open. We'll see how it evolves as I write programs in machine code.
Diffstat (limited to 'subx')
-rw-r--r-- | subx/001help.cc | 5 | ||||
-rw-r--r-- | subx/010core.cc | 4 | ||||
-rw-r--r-- | subx/021translate.cc | 96 | ||||
-rwxr-xr-x | subx/ex1 | bin | 0 -> 96 bytes | |||
-rw-r--r-- | subx/ex1.hex | 6 |
5 files changed, 107 insertions, 4 deletions
diff --git a/subx/001help.cc b/subx/001help.cc index d8d81ff0..c4cc3a00 100644 --- a/subx/001help.cc +++ b/subx/001help.cc @@ -8,9 +8,8 @@ if (argc <= 1 || is_equal(argv[1], "--help")) { cerr << "Usage:\n" << " subx test\n" << " subx --help\n" - << " subx run <elf file>\n" - << "Planned:\n" - << " subx compile <ascii file> <elf file>\n" + << " subx run <ELF binary>\n" + << " subx translate <input 'source' file> <output ELF binary>\n" ; return 0; } diff --git a/subx/010core.cc b/subx/010core.cc index 050ac932..07029ff0 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -152,8 +152,10 @@ void run_one_instruction() { } void load_program(const string& text_bytes) { - uint32_t addr = 1; istringstream in(text_bytes); + load_program(in, 1); +} +void load_program(istream& in, uint32_t addr) { in >> std::noskipws; while (has_data(in)) { char c1 = next_hex_byte(in); diff --git a/subx/021translate.cc b/subx/021translate.cc new file mode 100644 index 00000000..de945fbc --- /dev/null +++ b/subx/021translate.cc @@ -0,0 +1,96 @@ +:(before "End Includes") +const int START = 0x08048000; +:(before "End Main") +if (is_equal(argv[1], "translate")) { + assert(argc > 3); + ifstream in(argv[2]); + Mem.resize(1024); + load_program(in, 1); // since we're not going to run it right now, we can load it anywhere + dump_elf(argv[3]); +} + +:(code) +// write out the current Memory contents from address 1 to End_of_program to a +// bare-bones ELF file with a single section/segment and a hard-coded origin address. +void dump_elf(const char* filename) { + ofstream out(filename, ios::binary); + dump_elf_header(out); + for (size_t i = 1; i < End_of_program; ++i) { + char c = Mem.at(i); + out.write(&c, sizeof(c)); + } + out.close(); +} + +void dump_elf_header(ostream& out) { + char c = '\0'; +#define O(X) c = (X); out.write(&c, sizeof(c)) +// host is required to be little-endian +#define emit(X) out.write(reinterpret_cast<const char*>(&X), sizeof(X)) + //// ehdr + // e_ident + O(0x7f); O(/*E*/0x45); O(/*L*/0x4c); O(/*F*/0x46); + O(0x1); // 32-bit format + O(0x1); // little-endian + O(0x1); O(0x0); + for (size_t i = 0; i < 8; ++i) { O(0x0); } + // e_type + O(0x02); O(0x00); + // e_machine + O(0x03); O(0x00); + // e_version + O(0x01); O(0x00); O(0x00); O(0x00); + // e_entry + int e_entry = START + /*size of ehdr*/52 + /*size of phdr*/32; + emit(e_entry); + // e_phoff -- immediately after ELF header + int e_phoff = 52; + emit(e_phoff); + // e_shoff; unused + int dummy32 = 0; + emit(dummy32); + // e_flags; unused + emit(dummy32); + // e_ehsize + uint16_t e_ehsize = 52; + emit(e_ehsize); + // e_phentsize + uint16_t e_phentsize = 0x20; + emit(e_phentsize); + // e_phnum + uint16_t e_phnum = 0x1; + emit(e_phnum); + // e_shentsize + uint16_t dummy16 = 0x0; + emit(dummy16); + // e_shnum + emit(dummy16); + // e_shstrndx + emit(dummy16); + + //// phdr + // p_type + uint32_t p_type = 0x1; + emit(p_type); + // p_offset + emit(dummy32); + // p_vaddr + emit(START); + // p_paddr + emit(START); + // p_filesz + uint32_t size = (End_of_program-1) + /*size of ehdr*/52 + /*size of phdr*/32; + emit(size); + // p_memsz + emit(size); + // p_flags + uint32_t p_flags = 0x5; + emit(p_flags); + // p_align + uint32_t p_align = 0x1000; + emit(p_align); +#undef O +} + +:(before "End Includes") +using std::ios; diff --git a/subx/ex1 b/subx/ex1 new file mode 100755 index 00000000..205f8d60 --- /dev/null +++ b/subx/ex1 Binary files differdiff --git a/subx/ex1.hex b/subx/ex1.hex new file mode 100644 index 00000000..5a6317bd --- /dev/null +++ b/subx/ex1.hex @@ -0,0 +1,6 @@ +# opcode ModR/M SIB displacement immediate +# instruction mod, reg, Reg/Mem bits scale, index, base +# 1-3 bytes 0/1 byte 0/1 byte 0/1/2/4 bytes 0/1/2/4 bytes + bb 2a 00 00 00 # copy 0x2a (42) to EBX + 05 01 00 00 00 # copy 1 to EAX + cd 80 # int 80h |