From a630d7fb9666bbacdd714ddc12d3c42ef1466ba7 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 13 Feb 2019 00:01:14 -0800 Subject: 4959 It's always seemed ugly to explain the rules for segment names. Let's just always require a fixed name for the code and data segments. --- subx/034compute_segment_address.cc | 39 ++++++++++++++++++++++++++++---------- subx/Readme.md | 3 +-- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'subx') diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc index b6c191e4..d37060a4 100644 --- a/subx/034compute_segment_address.cc +++ b/subx/034compute_segment_address.cc @@ -34,12 +34,15 @@ if (!starts_with(segment_title, "0x")) { 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))); + 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 { @@ -50,10 +53,7 @@ if (!starts_with(segment_title, "0x")) { :(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; - } + assert(!p.segments.empty()); trace(99, "parse") << "flushing to segment" << end(); vector& curr_segment_data = p.segments.at(Currently_parsing_segment_index).lines; curr_segment_data.insert(curr_segment_data.begin(), lines.begin(), lines.end()); @@ -81,6 +81,25 @@ if (Currently_parsing_named_segment) { +load: 0x0900005c -> 0c +load: 0x0900005d -> 0d +:(scenario error_on_missing_segment_header) +% Hide_errors = true; +05/add-to-EAX 0/imm32 ++error: input does not start with a '==' section header + +:(scenario error_on_first_segment_not_code) +% Hide_errors = true; +== data +05 00 00 00 00 ++error: first segment must be 'code' but is 'data' + +:(scenario error_on_second_segment_not_data) +% Hide_errors = true; +== code +05/add-to-EAX 0/imm32 +== bss +05 00 00 00 00 ++error: second segment must be 'data' but is 'bss' + //: compute segment address :(before "End Level-2 Transforms") diff --git a/subx/Readme.md b/subx/Readme.md index de7a0fa7..b03176f0 100644 --- a/subx/Readme.md +++ b/subx/Readme.md @@ -274,8 +274,7 @@ SubX programs map to the same ELF binaries that a conventional Linux system uses. Linux ELF binaries consist of a series of _segments_. In particular, they distinguish between code and data. Correspondingly, SubX programs consist of a series of segments, each starting with a header line: `==` followed by a name. -The first segment is assumed to be for code, and the second for data. By -convention, I name them `code` and `data`. +The first segment must be named `code`; the second must be named `data`. Execution always begins at the start of the `code` segment. -- cgit 1.4.1-2-gfad0 mit.php?id=5b5afb12176437e977f210ee0bd1ed188f390611'>^