about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-10-01 12:16:05 -0700
committerKartik Agaram <vc@akkartik.com>2018-10-01 12:16:05 -0700
commit5ece295328f872fa368e7852f62f363eb701c0f9 (patch)
tree50120e8f8864e95bd8986e6512b95e9d357735a5
parent745c582e28e22fa5823d031ce2776c7f795913c0 (diff)
downloadmu-5ece295328f872fa368e7852f62f363eb701c0f9.tar.gz
4637 - subx: support multiple input files
-rw-r--r--subx/001help.cc2
-rw-r--r--subx/011run.cc1
-rw-r--r--subx/028translate.cc2
-rw-r--r--subx/034compute_segment_address.cc65
4 files changed, 65 insertions, 5 deletions
diff --git a/subx/001help.cc b/subx/001help.cc
index bf06aee3..64f02274 100644
--- a/subx/001help.cc
+++ b/subx/001help.cc
@@ -73,7 +73,7 @@ void init_help() {
     "    subx --help\n"
     "- Convert a textual SubX program into a standard ELF binary that you can\n"
     "  run on your computer:\n"
-    "    subx translate <input 'source' file> -o <output ELF binary>\n"
+    "    subx translate input1.subx intput2.subx ... -o <output ELF binary>\n"
     "- Run a SubX binary using SubX itself (for better error messages):\n"
     "    subx run <ELF binary>\n"
     "Add '--trace' to any of these commands to also emit a trace, for debugging purposes.\n"
diff --git a/subx/011run.cc b/subx/011run.cc
index b11dae90..88729871 100644
--- a/subx/011run.cc
+++ b/subx/011run.cc
@@ -183,6 +183,7 @@ void flush(program& p, vector<line>& lines) {
     raise << "input does not start with a '==' section header\n" << end();
     return;
   }
+  // End flush(p, lines) Special-cases
   trace(99, "parse") << "flushing to segment" << end();
   p.segments.back().lines.swap(lines);
 }
diff --git a/subx/028translate.cc b/subx/028translate.cc
index 303d6219..7330fa74 100644
--- a/subx/028translate.cc
+++ b/subx/028translate.cc
@@ -64,7 +64,7 @@ if (is_equal(argv[1], "translate")) {
 
 :(code)
 void print_translate_usage() {
-  cerr << "Usage: subx translate <input.subx> -o <output_ELF>\n";
+  cerr << "Usage: subx translate file1 file2 ... -o output\n";
 }
 
 // write out a program to a bare-bones ELF file
diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc
index b877faae..587f25b4 100644
--- a/subx/034compute_segment_address.cc
+++ b/subx/034compute_segment_address.cc
@@ -14,14 +14,73 @@
 +run: add imm32 0x0d0c0b0a to reg EAX
 +run: storing 0x0d0c0b0a
 
-//: update the parser to handle non-numeric segment name
+//: Update the parser to handle non-numeric segment name.
+//:
+//: We'll also support repeated segments with non-numeric names.
+//: When we encounter a new reference to an existing segment we'll *prepend*
+//: the new data to existing data for the segment.
+
+:(before "End Globals")
+map</*name*/string, int> Segment_index;
+bool Currently_parsing_named_segment = false;  // global to permit cross-layer communication
+int Currently_parsing_segment_index = -1;  // global to permit cross-layer communication
+:(before "End Reset")
+Segment_index.clear();
+Currently_parsing_named_segment = false;
+Currently_parsing_segment_index = -1;
 
 :(before "End Segment Parsing Special-cases(segment_title)")
 if (!starts_with(segment_title, "0x")) {
-  trace(99, "parse") << "new segment " << segment_title << end();
-  out.segments.push_back(segment());
+  Currently_parsing_named_segment = true;
+  if (!contains_key(Segment_index, segment_title)) {
+    trace(99, "parse") << "new segment '" << segment_title << "'" << end();
+    if (segment_title == "code")
+      put(Segment_index, segment_title, 0);
+    else if (segment_title == "data")
+      put(Segment_index, segment_title, 1);
+    else
+      put(Segment_index, segment_title, max(2, SIZE(out.segments)));
+    out.segments.push_back(segment());
+  }
+  else {
+    trace(99, "parse") << "prepending to segment '" << segment_title << "'" << end();
+  }
+  Currently_parsing_segment_index = get(Segment_index, segment_title);
+}
+
+:(before "End flush(p, lines) Special-cases")
+if (Currently_parsing_named_segment) {
+  if (p.segments.empty() || Currently_parsing_segment_index < 0) {
+    raise << "input does not start with a '==' section header\n" << end();
+    return;
+  }
+  trace(99, "parse") << "flushing to segment" << end();
+  vector<line>& curr_segment_data = p.segments.at(Currently_parsing_segment_index).lines;
+  curr_segment_data.insert(curr_segment_data.begin(), lines.begin(), lines.end());
+  lines.clear();
+  Currently_parsing_named_segment = false;
+  Currently_parsing_segment_index = -1;
+  return;
 }
 
+:(scenario repeated_segment_merges_data)
+== code
+05/add 0x0d0c0b0a/imm32  # add 0x0d0c0b0a to EAX
+== code
+2d/subtract 0xddccbbaa/imm32  # subtract 0xddccbbaa from EAX
++parse: new segment 'code'
++parse: prepending to segment 'code'
++load: 0x08048054 -> 2d
++load: 0x08048055 -> aa
++load: 0x08048056 -> bb
++load: 0x08048057 -> cc
++load: 0x08048058 -> dd
++load: 0x08048059 -> 05
++load: 0x0804805a -> 0a
++load: 0x0804805b -> 0b
++load: 0x0804805c -> 0c
++load: 0x0804805d -> 0d
+
 //: compute segment address
 
 :(before "End Level-2 Transforms")