about summary refs log tree commit diff stats
path: root/subx/034compute_segment_address.cc
diff options
context:
space:
mode:
authorKartik Agaram <github@akkartik.com>2019-05-18 00:46:19 -0700
committerGitHub <noreply@github.com>2019-05-18 00:46:19 -0700
commit11e725f277d08031d6b18599612a7bbddac050cd (patch)
treecf52127783efc20bbe8d903d96e73bc51a1f752d /subx/034compute_segment_address.cc
parent72853d07bb3cfed09f57ee36b582f8f35fee74e4 (diff)
parent83c67014034bbf9072d7e4555b0e51e815a95756 (diff)
downloadmu-11e725f277d08031d6b18599612a7bbddac050cd.tar.gz
Merge pull request #33 from akkartik/new-segment-header
New syntax for segment headers
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);
'>421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526