diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-09-01 20:37:54 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-09-01 20:38:32 -0700 |
commit | 1bbbf14f338a7379f66a1e00d972ed1e90fd9b09 (patch) | |
tree | cd2c455f1434512332542136135276102cce3a42 /subx | |
parent | a49bc41365bf6b4f0c006c5fbdcb4b519634c42c (diff) | |
download | mu-1bbbf14f338a7379f66a1e00d972ed1e90fd9b09.tar.gz |
4532
Make segment names a separate transform.
Diffstat (limited to 'subx')
-rw-r--r-- | subx/028translate.cc | 33 | ||||
-rw-r--r-- | subx/037compute_segment_address.cc | 31 |
2 files changed, 36 insertions, 28 deletions
diff --git a/subx/028translate.cc b/subx/028translate.cc index cc41e715..4c2ba133 100644 --- a/subx/028translate.cc +++ b/subx/028translate.cc @@ -30,28 +30,12 @@ if (is_equal(argv[1], "translate")) { if (trace_contains_errors()) return 1; transform(p); if (trace_contains_errors()) return 1; - compute_segment_offsets(p); save_elf(p, argv[3]); if (trace_contains_errors()) unlink(argv[3]); return 0; } -:(before "End segment Fields") -uint32_t offset; -:(before "End segment Constructor") -offset = 0; :(code) -void compute_segment_offsets(program& p) { - uint32_t p_offset = /*size of ehdr*/0x34 + SIZE(p.segments)*0x20/*size of each phdr*/; - uint32_t cumulative_segment_size = 0; - for (size_t i = 0; i < p.segments.size(); ++i) { - segment& curr = p.segments.at(i); - curr.offset = p_offset + cumulative_segment_size; -//? cerr << "offset " << i << ": " << curr.offset << '\n'; - cumulative_segment_size += num_words(curr); - } -} - // write out a program to a bare-bones ELF file void save_elf(const program& p, const char* filename) { ofstream out(filename, ios::binary); @@ -61,12 +45,6 @@ void save_elf(const program& p, const char* filename) { out.close(); } -uint32_t start(const program& p, const int segment_index) { - const segment& seg = p.segments.at(segment_index); - if (seg.start != 0) return seg.start; // if start is already initialized, use it - return CODE_START + SEGMENT_SIZE*segment_index + seg.offset; -} - void write_elf_header(ostream& out, const program& p) { char c = '\0'; #define O(X) c = (X); out.write(&c, sizeof(c)) @@ -86,7 +64,7 @@ void write_elf_header(ostream& out, const program& p) { // e_version O(0x01); O(0x00); O(0x00); O(0x00); // e_entry - int e_entry = start(p, /*segment*/0); // convention + int e_entry = p.segments.at(0).start; // convention emit(e_entry); // e_phoff -- immediately after ELF header int e_phoff = 0x34; @@ -113,23 +91,22 @@ void write_elf_header(ostream& out, const program& p) { // e_shstrndx emit(dummy16); + uint32_t p_offset = /*size of ehdr*/0x34 + SIZE(p.segments)*0x20/*size of each phdr*/; for (int i = 0; i < SIZE(p.segments); ++i) { - const segment& curr = p.segments.at(i); //// phdr // p_type uint32_t p_type = 0x1; emit(p_type); // p_offset - uint32_t p_offset = curr.offset; emit(p_offset); // p_vaddr - uint32_t p_start = start(p, i); + uint32_t p_start = p.segments.at(i).start; emit(p_start); // p_paddr emit(p_start); // p_filesz - uint32_t size = num_words(curr); - assert(size < SEGMENT_SIZE); + uint32_t size = num_words(p.segments.at(i)); + assert(p_offset + size < SEGMENT_SIZE); emit(size); // p_memsz emit(size); diff --git a/subx/037compute_segment_address.cc b/subx/037compute_segment_address.cc new file mode 100644 index 00000000..ee2b1bb4 --- /dev/null +++ b/subx/037compute_segment_address.cc @@ -0,0 +1,31 @@ +//: Start allowing us to not specify precise addresses for the start of each +//: segment. +//: This gives up a measure of control in placing code and data. + +:(scenario segment_name) +% Mem_offset = CODE_START; +== code +05/add 0x0d0c0b0a/imm32 # add 0x0d0c0b0a to EAX +# code starts at 0x08048000 + p_offset, which is 0x54 for a single-segment binary ++load: 0x08048054 -> 05 ++load: 0x08048055 -> 0a ++load: 0x08048056 -> 0b ++load: 0x08048057 -> 0c ++load: 0x08048058 -> 0d ++run: add imm32 0x0d0c0b0a to reg EAX ++run: storing 0x0d0c0b0a + +:(before "End Level-2 Transforms") +Transform.push_back(compute_segment_starts); + +:(code) +void compute_segment_starts(program& p) { + uint32_t p_offset = /*size of ehdr*/0x34 + SIZE(p.segments)*0x20/*size of each phdr*/; + for (size_t i = 0; i < p.segments.size(); ++i) { + segment& curr = p.segments.at(i); + if (curr.start == 0) + curr.start = CODE_START + i*SEGMENT_SIZE + p_offset; + p_offset += num_words(curr); + assert(p_offset < SEGMENT_SIZE); // for now we get less and less available space in each successive segment + } +} |