michaelcmartin/Ophis

Allow dumping of address:label mappings to a file

Closed this issue · 12 comments

When debugging code on real hardware it is nice to be able to see where in the source an address correlates to.

One way to achieve this is a label dump showing the assembled address of each label.

Another nice way is to have the disassembly output (which Ophis already produces) to be annotated with labels.

It's probably best to have some combination of both, and I'm thinking that it might be necessary to add some pretty-printing steps to some of them; a lot of labels get mangled a bit going through the translation process (particularly when macros or scope markers are involved). It's pretty common to have defined extra labels that point entirely outside of the source code, so I'd expect that there would have to be a label dump covering at least those.

Hello,

On Mon, Mar 24, 2014 at 2:53 PM, Michael C. Martin <notifications@github.com

wrote:

It's probably best to have some combination of both, and I'm thinking that
it might be necessary to add some pretty-printing steps to some of them; a
lot of labels get mangled a bit going through the translation process
(particularly when macros or scope markers are involved). It's pretty
common to have defined extra labels that point entirely outside of the
source code, so I'd expect that there would have to be a label dump
covering at least those.

Yes, this will certainly be the case.

Where are the labels and values stored? With that information, assuming I
get some spare time, I can have a closer look at what's involved, unless
you prefer to attack this yourself.

Paul.

Reply to this email directly or view it on GitHubhttps://github.com//issues/21#issuecomment-38411428
.

I took a brief glance at the code, and it looks like the labels/addresses are stored in the Environment object (src/Ophis/Environment.py).

When I said earlier it couldn't be too difficult, I had forgotten about Ophis' nested scopes, sorry 😅 It does look like maybe another mapping dict might have to be added, to associate a labelled address back to the original label even after a scope has been exited. But, such a map might also be a good place to record details of label mangling too (to associate each mangled label with its original label.) I say this without familiarity of the guts, but they seem like two parts of the same problem.

Here is a cheap hack that dumps an extremely crude mapfile. It does not distinguish between labels with the same name in different scopes. I haven't tested it on macros at all, so I don't know what it dumps for them.

https://github.com/catseye/Ophis/commit/c0bf2e98b77ac4a16712052c5cbc8b0d262a789e

This is a great start. I have merged it into my Ophis repo (git://
github.com/gardners/Ophis).
Next step from my perspective is to have address on the left, and to sort
them by address. I have done the first part
gardners@b126b3e914343a244afe3400f4f4adb4d0710c7fbut
haven't had a think about how to sort the output, although there are
many ways it could be done.

As this commit stands it is already somewhat useful for me, as I can run
the output through sort and correlate it to addresses running on the
hardware.

Paul.

On Mon, Mar 24, 2014 at 11:08 PM, catseye notifications@github.com wrote:

Here is a cheap hack that dumps an extremely crude mapfile. It does not
distinguish between labels with the same name in different scopes. I
haven't tested it on macros at all, so I don't know what it dumps for them.

catseye@c0bf2e9https://github.com/catseye/Ophis/commit/c0bf2e98b77ac4a16712052c5cbc8b0d262a789e

Reply to this email directly or view it on GitHubhttps://github.com//issues/21#issuecomment-38438794
.

Glad it's of some use.

I had a compelling use case for this feature some time ago (like maybe a year ago) but I don't quite remember what it was. I probably wanted to place a watch on an obscurely-located variable while debugging a retrogame I was writing. This little hack would have been sufficient for that purpose too.

Which raises the question, is it worth putting in the effort to do it 100% correctly? Omitting labels used in macros would probably be an acceptable limitation, at least for an initial version of the feature. But omitting labels used in local scopes might be too much (it would leave us with just the global labels.) But for local scopes, there should be a way to distinguish two labels with the same name in the dump, for example by line number in the source program. And this looks like it would still be a fair bit of work, since that information isn't recorded AFAICS.

Hello,

Yes, the full feature would be useful.

What I am hearing is that global labels is the low hanging fruit, so I
suggest focussing on that. Then when that is there and working, we can
turn progressively to the other features as the need arises.

Out of curiosity, what is the retrogame you were working on?

My use case for now is writing firmware and software for a Commodore 65
inspired FPGA based computer (See c65gs.blogspot.com.au).

Paul.

On Fri, Apr 4, 2014 at 1:17 AM, catseye notifications@github.com wrote:

Glad it's of some use.

I had a compelling use case for this feature some time ago (like maybe a
year ago) but I don't quite remember what it was. I probably wanted to
place a watch on an obscurely-located variable while debugging a retrogame
I was writing. This little hack would have been sufficient for that purpose
too.

Which raises the question, is it worth putting in the effort to do it 100%
correctly? Omitting labels used in macros would probably be an acceptable
limitation, at least for an initial version of the feature. But omitting
labels used in local scopes might be too much (it would leave us with just
the global labels.) But for local scopes, there should be a way to
distinguish two labels with the same name in the dump, for example by line
number in the source program. And this looks like it would still be a fair
bit of work, since that information isn't recorded AFAICS.

Reply to this email directly or view it on GitHubhttps://github.com//issues/21#issuecomment-39459871
.

I poked a little at this; source lines for labels are available as part of an assembler pass (if you run with the not really as useful as one might like -dddd option you'll get a raw label dump) so a "prepare labels" pass either just before or just after assembling might be the best way to collect all the information.

Sounds like good progress.

On Sat, Apr 5, 2014 at 3:30 PM, Michael C. Martin
notifications@github.comwrote:

I poked a little at this; source lines for labels are available as part of
an assembler pass (if you run with the not really as useful as one might
like -dddd option you'll get a raw label dump) so a "prepare labels" pass
either just before or just after assembling might be the best way to
collect all the information.

Reply to this email directly or view it on GitHubhttps://github.com//issues/21#issuecomment-39629104
.

@michaelcmartin Thanks; I didn't see where source line numbers were being stored, but I'll look harder.

@gardners I agree, restricting it to global labels to start is probably good. I haven't checked out your fork yet, but placing the address in the first column makes more sense (because unlike labels, there is a limit to their length. You can always use awk to postprocess it to the other way around.)

As to the retrogame, it's nothing very special -- just a scrolling shooter with a twist that I've wanted to write since I was a young'un. It's a little more ambitious than the only retrogame I've actually released for the C64, so I keep it around and come back to it every so often. In fact, the last time I came back to it I decided it was too complicated to do in raw assembly, so I started working on a type-safe-ish compiler for a 6502-like language which uses Ophis as its backend.

I don't think I'd heard of the C65 or the 4502 until you mentioned them. An interesting transitional platform somewhere between the C64 and the Amiga, for sure!

I've created a new "labelmap" branch to experiment with this. I've got mapping labels to source locations cracked, but there's some stuff that still slips a bit through the cracks - in particular, anonymous labels look funny, included file paths are always absolute, macro arguments should never be listed at all, and I'm currently sorting on sourcefile location instead of binary location.

I'm thinking I might also want to fold this into the program listing generator, or at least refactor it to put it next to there. That would let it be more easily folded back into the assembler pass.

(hi_stella.oph uses macros, labels inside macros, anonymous labels, and locations aliased to multiple names. As such it's a pretty good testbed, but it does lack macros with arguments.)

This is now fixed in master. I used catseye's syntax for this. Macros, temporary, and anonymous labels are all fully supported with reasonable sourcecode locations (or, in macro invocation cases, sourcecode location chains).

Some of my other projects are bearing fruit too, so I think a real 2.1 release should be in the works soon enough...