-
-
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
All registers are byteswapped when using lldb #119
Comments
Some past issues that might be relevant: #26, #97, and #99 One thing i'll mention right out of the gate is that In this case, it may very well be the case that for I would expect the implementation to follow the same broad strokes as #103 (insofar as it would touch both the Let me know what you find, and if you'd like to take a stab at that functionality! P.S: consider first patching |
For reference, this is the log when attaching lldb:
|
Yep, there sure are a bunch of unimplemented LLDB packets there 😄 I think the next step is definitely to try implementing a basic P.S: in the future, post logs in a code block, or else those checksums end up getting formatted as issue-links, which is a little weird lol |
Some updates on this. It turned out that actually lldb was right and gdb was wrong :) When I filed this bug, my memory reading was essentially pretending to be little endian, which didn't work for anything that isn't 32 bit. So I changed my memory read function to correctly return big endian. As I couldn't find a way to tell gdb that the system is big endian, I now have to manually call "set endian big" in gdb every time I debug. Additionally, this meant that I now have to swap the registers in read_registers() like this: Register read: fn read_registers(...) {
regs.pc = pc.swap_bytes();
let main_registers = *self.nemu.main_registers();
for i in 0..32 {
regs.r[i] = main_registers[i].swap_bytes();
}
regs.lo = self.nemu.mult_lo().swap_bytes();
regs.hi = self.nemu.mult_hi().swap_bytes(); With this, both gdb and lldb work fine. However, this doesn't feel quite right. Two questions about this: |
Oh, okay, very interesting! This definitely has to do with #26 then... Unfortunately, I really don't have any hands-on experience working with big-endian systems, so I don't have answers/opinions to either question off the top of my head. Coming to a conclusion there will require some more research / digging into the GDB source code. Not sure if/when I'll have a chance to sit down and do that, but if you can do the research into what the behavior should be, I can certainly try and set aside some time to whip up some gdbstub-side code / docs to make things as easy as possible for big-endian systems :) |
Though, poking through the GDB docs a bit:
https://sourceware.org/gdb/onlinedocs/gdb/Byte-Order.html#Byte-Order So it might be the case that there's a bit of build-time metadata you're setting incorrectly when building your MIPS executables? |
The problem for me has been that if I pass the binary as an argument to gdb then gdb will autodetect the arch and get everything wrong (I get incorrect package sizes). It seems to ignore (or at least mostly ignore) target_description_xml in that case and just go with some arch that it thinks is the right one. The only thing that works for me is:
Which is...not a great workflow at all. It also has the downside of gdb trying its hardest to run the program at launch - so if you want to debug something early on it might have already happened. |
I hate to say it, but I'm not convinced this is an issue with Of course, i'm happy to be convinced otherwise. e.g: if you can find some other n64 emulator with a gdbstub that does the Right Thing here, we could compare what its doing vs. what gdbstub + your impl is doing and go from there? |
Yeah I don't think this is an issue with gdbstub either |
The only things I see for gdbstub would be:
Anything else is just gdb being annoying |
If that's the case... I wouldn't be opposed to adding some kind of optional auto-byteswap feature into I'm not sure when I'd have the time to sit down and take a crack at implementing something like that, but if you'd like to take a crack at it yourself, I'd happily review any PR sent my way :) |
The workaround is pretty simple - I can byteswap the registers myself. I mostly wanted to confirm with you that this is the right thing to do. You could also leave this as-is frankly. It's a little weird to provide byteswapped u64, but in the grand picture this is one of the smaller tasks to do and it can easily be handled by the client. Having it documented might be useful however. |
Oh! I just realized: if you're using the built-in MIPS arch implementation from As such, I think the real solution here is that you should simply re-implement the MIPS If I'm right, and that makes sense, then I think the appropriate doc update is actually far more simple: "NOTE: gdbstub_arch::mips is implemented for little-endian MIPS systems" |
Given that the only outstanding ask from this issue is a doc update, I think I'm going to close this out for now. Feel free to send in the doc update if you'd like! |
Hi (and sorry for filing so many bugs at once).
I integrated gdbstub into my Nintendo 64 emulator and things mostly work with gdb. However, when I connect with lldb, all registers are byteswapped. I assume this has something to do with the N64 being big-endian and lldb and gdb being too different.
I might be completely wrong here, but I wonder if document explains that: https://opensource.apple.com/source/lldb/lldb-112/docs/lldb-gdb-remote.txt.auto.html (notice that qHostInfo has an endian flag)?
The data that I should be seeing is:
The text was updated successfully, but these errors were encountered: