-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SubX in SubX: computing addresses for labels #34
Conversation
Start of the final phase needed to implement SubX in SubX: $ cat files.subx ... |dquotes |assort |pack |survey |hex > a.elf survey.subx is responsible for assigning addresses to labels and segments.
@charles-l I just spun up this PR for survey.subx. No failing tests yet. Only mildly interesting thing to look at may be the ELF header definitions. |
@charles-l I'm still cleaning up #32 so haven't written any tests here yet. If you're looking for something to do, could you create a function here called Any tests I think of for this seem pretty silly, so let's just test it manually at the commandline. |
I'm thinking hard about how to build this phase, now that dquotes is fully merged (yay!) There seem to be three tasks to perform here (and I'm constantly wondering whether to split them up into multiple phases, but they seem to need some common offset tracking as they read stdin):
Since labels can be defined after they're used, there need to be two passes. The first performs tasks 1 and 2. The second performs task 3. We need to drop labels at some point. And we can't rewind the input fd at the moment. Perhaps it's cleaner to not add Ok, so very high-level pseudocode. Data structures shared between pass 1 and pass 2.
Pass 1
Pass 2
Ugh, this is complicated. |
One small piece we can nibble off today is to extract the logic for |
The only place in |
Ah yes, that's the one. Thanks! |
I think what may stop me spinning my wheels is a helper like Just an idea to throw out there. I'll probably work on it unless you really want to. |
Mostly for tests. For every new type we want to compare in a test, we're now going to start using some primitive that can parse its value from string. In this manner we can get syntax for literals in machine code. Open question: parsing aggregates of aggregates. Like an array of structs. This is the first time we allocate from the heap in standard library tests. So we now need to start initializing the heap in all our apps.
I think the path to readable tests for survey.subx passes through white-box tests.
Excellent! |
OK -- implemented |
That is the whole set. I'm pretty inconsistent there as well; sometimes I support |
Any preference on what you'd like to do next? I've been (veeery sloooowly) building out primitives for checking the trace, so that I can write the survey tests like this:
That feels more useful than printing out say a series of bytes for the ELF header, and then writing a test that I printed out that same series of bytes. |
Woohoo! The final bug was something I introduced in 538f24c :/ No idea what I was thinking. |
I carefully logged the segment a label is declared in but forgot to actually save it in the table. This has been a theoretic concern for some time, but I've never seen it actually happen until now. SubX is just too low level. Now I get past the first two phases but code generation fails to find the 'Entry' label.
map of how far we've gotten by now (functions with '*' independently tested): ✓ compute-offsets* ✓ compute-addresses* ✓ emit-output ✓ emit-headers ✓ emit-elf-header ✓ emit-hex-array* ✓ first emit-elf-program-header-entry ✓ emit-hex-array* ? second emit-elf-program-header-entry emit-hex-array* emit-segments*
All assertions in `test-convert-computes-addresses` still failing.
This PR is done, but sadly I still get an error when compiling
(It only fails in the final We should probably get a sense of whether any of our examples complete without error right now. |
Hrmm... Yeah, I'm only getting segfaults when I run through examples right now, but now that we have tracing, it might be easier to track it down.
|
Are you back on master? 10/12 examples work for me now. |
Just FYI, things are improving rapidly on I'm now trying to get the translator phases themselves through. "SubX in SubX" in "SubX in SubX". I've been posting status updates on this thread: https://mastodon.social/@akkartik/102488929327915911 |
@akkartik oh sweet -- yeah I gave it a shot on master and many of the examples work run through the pipeline now. |
Whoo!!! That is an awesome milestone!! |
Thank you so much! I'm taking a breath to think about what programs I want to write next on this foundation. Something silly/fun just to decompress. Any ideas? Beyond the next few days, creating some syntactic sugar for function calls would be pretty sweet. I think it may first require some sugar for reg/mem operands.
If we had this, we could then have calls like ff 6/subop/push %EAX
68/push 32/imm32
e8/call foo/disp32
81 0/subop/add %ESP 8/imm32 # num args * 4 So that's one idea. I'm also tempted to push on https://github.com/ivandavidov/minimal and see how much I can learn from it. |
This branch is work in progress on implementing SubX in SubX. The big-picture plan is to divide up the work into the following phases:
Each phase is an ELF binary constructed out of a corresponding
.subx
file.0/mod 1/rm32 1/r32
is turned into the single byte08
. (done)==
and containing lines of code or data, and concatenates all segments with the same name. (done)This branch is where the survey phase is being built.
To run its tests (and so see how far along things are):
Contact me if you'd like to contribute. Commit access freely given.