diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-03-03 22:09:50 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-03-03 22:21:03 -0800 |
commit | 71e4f3812982dba2efb471283d310224e8db363e (patch) | |
tree | ea111a1acb8b8845dbda39c0e1b4bac1d198143b /035compute_segment_address.cc | |
parent | c6b928be29ac8cdb4e4d6e1eaa20420ff03e5a4c (diff) | |
download | mu-71e4f3812982dba2efb471283d310224e8db363e.tar.gz |
7842 - new directory organization
Baremetal is now the default build target and therefore has its sources at the top-level. Baremetal programs build using the phase-2 Mu toolchain that requires a Linux kernel. This phase-2 codebase which used to be at the top-level is now under the linux/ directory. Finally, the phase-2 toolchain, while self-hosting, has a way to bootstrap from a C implementation, which is now stored in linux/bootstrap. The bootstrap C implementation uses some literate programming tools that are now in linux/bootstrap/tools. So the whole thing has gotten inverted. Each directory should build one artifact and include the main sources (along with standard library). Tools used for building it are relegated to sub-directories, even though those tools are often useful in their own right, and have had lots of interesting programs written using them. A couple of things have gotten dropped in this process: - I had old ways to run on just a Linux kernel, or with a Soso kernel. No more. - I had some old tooling for running a single test at the cursor. I haven't used that lately. Maybe I'll bring it back one day. The reorg isn't done yet. Still to do: - redo documentation everywhere. All the README files, all other markdown, particularly vocabulary.md. - clean up how-to-run comments at the start of programs everywhere - rethink what to do with the html/ directory. Do we even want to keep supporting it? In spite of these shortcomings, all the scripts at the top-level, linux/ and linux/bootstrap are working. The names of the scripts also feel reasonable. This is a good milestone to take stock at.
Diffstat (limited to '035compute_segment_address.cc')
-rw-r--r-- | 035compute_segment_address.cc | 86 |
1 files changed, 0 insertions, 86 deletions
diff --git a/035compute_segment_address.cc b/035compute_segment_address.cc deleted file mode 100644 index 5c627a7b..00000000 --- a/035compute_segment_address.cc +++ /dev/null @@ -1,86 +0,0 @@ -//: 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 0x09000000\n" - "05/add-to-EAX 0x0d0c0b0a/imm32\n" - // code starts at 0x09000000 + p_offset, which is 0x54 for a single-segment binary - ); - CHECK_TRACE_CONTENTS( - "load: 0x09000054 -> 05\n" - "load: 0x09000055 -> 0a\n" - "load: 0x09000056 -> 0b\n" - "load: 0x09000057 -> 0c\n" - "load: 0x09000058 -> 0d\n" - "run: add imm32 0x0d0c0b0a to EAX\n" - "run: storing 0x0d0c0b0a\n" - ); -} - -//: compute segment address - -:(before "End Transforms") -Transform.push_back(compute_segment_starts); - -:(code) -void compute_segment_starts(program& p) { - trace(3, "transform") << "-- compute segment addresses" << end(); - 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 >= 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 & 0xfff); - trace(99, "transform") << "segment " << i << " begins at address 0x" << HEXWORD << curr.start << end(); - } - p_offset += size_of(curr); - assert(p_offset < SEGMENT_ALIGNMENT); // for now we get less and less available space in each successive segment - } -} - -uint32_t size_of(const segment& s) { - uint32_t sum = 0; - for (int i = 0; i < SIZE(s.lines); ++i) - sum += num_bytes(s.lines.at(i)); - return sum; -} - -// Assumes all bitfields are packed. -uint32_t num_bytes(const line& inst) { - uint32_t sum = 0; - for (int i = 0; i < SIZE(inst.words); ++i) - sum += size_of(inst.words.at(i)); - return sum; -} - -int size_of(const word& w) { - if (has_argument_metadata(w, "disp32") || has_argument_metadata(w, "imm32")) - return 4; - else if (has_argument_metadata(w, "disp16")) - return 2; - // End size_of(word w) Special-cases - else - return 1; -} - -//: Dependencies: -//: - We'd like to compute segment addresses before setting up global variables, -//: because computing addresses for global variables requires knowing where -//: the data segment starts. -//: - We'd like to finish expanding labels before computing segment addresses, -//: because it would make computing the sizes of segments more self-contained -//: (num_bytes). -//: -//: Decision: compute segment addresses before expanding labels, by being -//: aware in this layer of certain argument types that will eventually occupy -//: multiple bytes. -//: -//: The layer to expand labels later hooks into num_bytes() to teach this -//: layer that labels occupy zero space in the binary. |