about summary refs log tree commit diff stats
path: root/subx/034compute_segment_address.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/034compute_segment_address.cc')
-rw-r--r--subx/034compute_segment_address.cc125
1 files changed, 12 insertions, 113 deletions
diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc
index 47311219..9eb1615d 100644
--- a/subx/034compute_segment_address.cc
+++ b/subx/034compute_segment_address.cc
@@ -1,12 +1,16 @@
-//: Start allowing us to not specify precise addresses for the start of each
-//: segment.
+//: ELF binaries have finicky rules about the precise alignment each segment
+//: should start at. They depend on the amount of code in a program.
+//: We shouldn't expect people to adjust segment addresses everytime they make
+//: a change to their programs.
+//: Let's start taking the given segment addresses as guidelines, and adjust
+//: them as necessary.
 //: This gives up a measure of control in placing code and data.
 
 void test_segment_name() {
   run(
-      "== code\n"
+      "== code 0x09000000\n"
       "05/add-to-EAX  0x0d0c0b0a/imm32\n"
-      // code starts at 0x08048000 + p_offset, which is 0x54 for a single-segment binary
+      // code starts at 0x09000000 + p_offset, which is 0x54 for a single-segment binary
   );
   CHECK_TRACE_CONTENTS(
       "load: 0x09000054 -> 05\n"
@@ -19,113 +23,6 @@ void test_segment_name() {
   );
 }
 
-//: Update the parser to handle non-numeric segment name.
-//:
-//: We'll also support repeated segments with non-numeric names.
-
-:(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")) {
-  Currently_parsing_named_segment = true;
-  if (!contains_key(Segment_index, segment_title)) {
-    trace(3, "parse") << "new segment '" << segment_title << "'" << end();
-    if (out.segments.empty() && segment_title != "code") {
-      raise << "first segment must be 'code' but is '" << segment_title << "'\n" << end();
-      return;
-    }
-    if (SIZE(out.segments) == 1 && segment_title != "data") {
-      raise << "second segment must be 'data' but is '" << segment_title << "'\n" << end();
-      return;
-    }
-    put(Segment_index, segment_title, SIZE(out.segments));
-    out.segments.push_back(segment());
-  }
-  else {
-    trace(3, "parse") << "appending 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) {
-  assert(!p.segments.empty());
-  trace(3, "parse") << "flushing segment" << end();
-  vector<line>& curr_segment_data = p.segments.at(Currently_parsing_segment_index).lines;
-  curr_segment_data.insert(curr_segment_data.end(), lines.begin(), lines.end());
-  lines.clear();
-  Currently_parsing_named_segment = false;
-  Currently_parsing_segment_index = -1;
-  return;
-}
-
-:(code)
-void test_repeated_segment_merges_data() {
-  run(
-      "== code\n"
-      "05/add-to-EAX  0x0d0c0b0a/imm32\n"
-      "== code\n"  // again
-      "2d/subtract-from-EAX  0xddccbbaa/imm32\n"
-  );
-  CHECK_TRACE_CONTENTS(
-      "parse: new segment 'code'\n"
-      "parse: appending to segment 'code'\n"
-      // first segment
-      "load: 0x09000054 -> 05\n"
-      "load: 0x09000055 -> 0a\n"
-      "load: 0x09000056 -> 0b\n"
-      "load: 0x09000057 -> 0c\n"
-      "load: 0x09000058 -> 0d\n"
-      // second segment
-      "load: 0x09000059 -> 2d\n"
-      "load: 0x0900005a -> aa\n"
-      "load: 0x0900005b -> bb\n"
-      "load: 0x0900005c -> cc\n"
-      "load: 0x0900005d -> dd\n"
-  );
-}
-
-void test_error_on_missing_segment_header() {
-  Hide_errors = true;
-  run(
-      "05/add-to-EAX 0/imm32\n"
-  );
-  CHECK_TRACE_CONTENTS(
-      "error: input does not start with a '==' section header\n"
-  );
-}
-
-void test_error_on_first_segment_not_code() {
-  Hide_errors = true;
-  run(
-      "== data\n"
-      "05 00 00 00 00\n"
-  );
-  CHECK_TRACE_CONTENTS(
-      "error: first segment must be 'code' but is 'data'\n"
-  );
-}
-
-void test_error_on_second_segment_not_data() {
-  Hide_errors = true;
-  run(
-      "== code\n"
-      "05/add-to-EAX 0/imm32\n"
-      "== bss\n"
-      "05 00 00 00 00\n"
-  );
-  CHECK_TRACE_CONTENTS(
-      "error: second segment must be 'data' but is 'bss'\n"
-  );
-}
-
 //: compute segment address
 
 :(before "End Level-2 Transforms")
@@ -137,8 +34,10 @@ 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_SEGMENT + i*SPACE_FOR_SEGMENT + p_offset;
+    if (curr.start >= 0x08000000) {
+      // valid address for user space, so assume we're creating a real ELF binary, not just running a test
+      curr.start &= 0xfffff000;  // same number of zeros as the p_align used when emitting the ELF binary
+      curr.start |= p_offset;
       trace(99, "transform") << "segment " << i << " begins at address 0x" << HEXWORD << curr.start << end();
     }
     p_offset += size_of(curr);