-
Notifications
You must be signed in to change notification settings - Fork 18
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
MIPS Support #23
Comments
End of stack likely just means it's not caught |
I'm running under emulation, with somewhat subpar tools (old school assembly level debugger); but tracing the program's execution and I can see that my call to In the actual code raising the exception however (first statement in main is The net result is my custom Some things I'm left wondering is whether or not my linker script may be incorrect, and the one or all of the symbols used for static unwinding are mis-located or similar? Or perhaps there are some changes that need to be made to one or both of Here's my patches so far (somewhat hacky, I need to upstream MIPS arch to gimli and bypassed it for now) and my linkerscript. |
I think your register saving code is incorrect. You need to ensure that all registers are saved to the correct offset of the |
Are they used for anything beyond debug printing? I noticed this as well this morning, but figured it innocuous for now as the restore will work regardless. ^^ I'll give it a try after work though 😄 |
It's necessary for stack unwinding. |
Quick update, I correctly calculated all the offsets, as well as the size of the context; and I'm unfortunately still encountering the same issue. Really scratching my head on this one and think I may just have to throw in the towel. The only lead I have at this point is that Any ideas what may lead to this? Are there any decent ways to verify that |
It's very hard to tell from distance what's wrong. It could be with the assembly, gimli or the usage. I'd suggest you to submit your change as a draft PR and add |
So to follow up on this, I'm still having trouble with both:
It seems like it's failing even on x86_64-unknown-linux-gnu based on testing. I hate to ask, but would you mind looking over the the test and seeing if there's anything obviously wrong with the setup? Otherwise I think I've isolated the issue to specifically these two features/the combination of them with a custom panic_handler.rs (albeit, I couldn't tell you the root cause, and that test should probably use the |
I didn't see where fde-static is used |
Not using it in that test specifically, so I don't need to manually link the symbol for all configurations, but it exhibits the same unwind failure as manually linking it in. I would expect My apologies though, the test name is a misnomer, and it should be |
Registry does nothing if there's no explicit registration |
Ah, okay, misinterpreted |
Yeah, I think I've exhausted all of my options trying to triage this one. Between your changes, and the many dozens of permutations of linker scripts and build changes I've tried to make; I simply can't get any sort of unwinding to work on |
What issue are you still having after #24? Try verifying the actual value of __executable_start, __etext and __eh_frame to see if they point to the correct location. |
According to the linker script, the __eh_frame_hdr_start symbol is already exposed. Perhaps you can enable the fde-custom feature and try this: use unwinding::custom_eh_frame_finder::*;
struct MyFrameFinder;
unsafe impl EhFrameFinder for MyFrameFinder {
fn find(&self, pc: usize) -> Option<FrameInfo> {
extern "C" {
static __eh_frame_hdr_start: u8;
}
Some(FrameInfo {
text_base: 0,
kind: FrameInfoKind::EhFrameHdr(&__eh_frame_hdr_start as *const u8 as usize),
})
}
}
// Usage
set_custom_eh_frame_finder(&MyFrameFinder); |
Unfortunately still hits the same error as my custom linker script; error code 5 and aborts (though that's rather handy indeed) - my suspicion is that there's something going wrong at link time (perhaps a linker bug, or an issue with the linker script/target configuration) but I'm unfortunately not really equipped to confirm that. Inspecting the elf with objdump at least confirmed that my linker script seemingly assigns things correctly (grepped Here's the elf, if you'd like to analyze it (though don't feel you have to; it'd be lovely to get to the bottom of this but I have definitely asked far too much of you already): One thing of note, is I did notice using the snippet from the README was causing the linker to emit |
Briefly looked into the binary I didn't notice anything obviously wrong. Might be related to PSP/normal MIPS difference. AFAIK libunwind used by rust-psp is also patched... |
Perhaps it would wise of me to investigate what those patches were, and how they were building it. The thing that kicked this off was libunwind becoming unstable recently, so I was hoping to find a nice unwinding solution that we would have far more control over. In any case, appreciate that you looked into it, I'll do some digging and see if there's anything interesting. :) |
So I haven't really been able to dig up any information on what/if any patches were made to libunwind; so for now I'm assuming they built it from trunk 🙂 The only info I've really managed to dig up is this. I assume this corresponds to Anything you're able to glean from the differences there? |
The fallback unwinding mechanism shouldn't be relevant here, it's only supposed to be used when there's no unwind table for a function. If |
I tried that early on, but not post custom-fde + context fixes, At this point I'm thinking I may just need mock things up in a test executable on a platform I can actually debug, and feed Gimli the eh_frame data + RAs from the mipsel executable. Then I can potentially get to the bottom of why it's failing to get the initial frame info. Unfortunately very time consuming, but I think I've exhausted all my options, and I suppose it would at least confirm if the problem is with the DWARF data or not. |
That's very useful information! I am not aware that there's a fixed offset being applied at load time. This demystified everything. It's important for the linker to know where the program will be loaded to (or, alternative, the program needs to compiled as PIE, in this case there'll be some runtime relocation fixups necessary for the program to do at init time). The unwinder really expects to see the correct address in this particular case. The psp_test program that you attached doesn't do either -- the I saw the linker script forced .text to locate at 0 and I thought it's actually loaded into that place. ELF does support different virtual address and physical address, you might be able to use that feature to convey the correct virtual address to the linker but still make PRX (I don't know what's that though) happy? Alternatively try use PIE/PIC flags to see if it can work. Link that might be useful: https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html |
Interestingly, it seems like the linker totally ignores any and all attempts to change LMA/VMA; the resulting .text section always has a VMA/LMA of 00000000. I came across this thread where someone else seemingly ran into a similar issue but I'm stumped as of right now. 🙂 And PRX is the Sony flavor of ELF - the ELF I sent you actually ends up going through a process that rewrites the executable sections and so on to match the expected format on the PSP. Though that should be mostly irrelevant to this issue, since this seems to be some sort of linker issue happening long before that step. -- Managed to get around that with I'll probably need to do a bit of digging and see what exactly is going on here; because it clearly does want things to be loaded at zero initially (crashes otherwise), but then it seems like things are relocated/remapped in some way to that address after initialization. |
Yeah unfortunately, I think the vaddr being set to zero is going to be a hard requirement for the PRX to load correctly. So I don't think there's much I can do at link time, and there's definitely some Sony specific relocation happening. Would you happen to have any suggestions? Since we're post-processing the ELF anyway, I have to wonder if patching up the .eh_frame/_hdr data might be an option? Though I'm not sure just how complex that would end up being. Outside of that, I don't think PIC/PIE will work, but maybe there's something that can be done there in one way or another. |
What's the issue with PIC/PIE? |
Mostly just unfamiliar with it, and slightly concerned it will degrade performance (though, of course, I suppose in release From my testing, compilation works just fine, but I get an invalid memory access immediately after starting the executable. I presume this is due to me needing to do some sort of setup in executable start? |
I did some further research and I think PIC/PIE is indeed probably not needed. I think the tool flow is that an ELF linker first produce an executable with relocation enabled, and then the PRX tool will use these relocation information. In this case, the eh_frame in memory should be pointing to the relocated PC address IMO? Does libunwind work for the same binary? |
Also, have you tried to change linker from LLVM ld to GNU ld? This could also make a difference. |
Yeah, you would think so? I was looking at the PRX tool yesterday to try to spot some issue there, but found nothing immediately obvious. I was going to put some time into rewriting it today, just to eliminate the tool as a possible concern. It's based on a much older tool written in C, so I was going to look there to see if I can spot any differences.
It used to, but with a recent nightly bump it started to exhibit consistent crashes. Before that it worked reasonably well, with occasional failures – which is why I've been leaning towards an issue with
Aye probably not, but it would be interesting to see if it unblocks things for now. I've been reading up on it a bit today, and trying to find some information on what kind of preinit needs to happen in executables that use it. Unfortunately struggling to find much of anything, which is unfortunate. |
Unfortunately not a simple thing to do in this case, fails to link, and I'll probably need to install the custom gcc toolchain to get it working. More effort than I'd want to ask of a user, so I'll continue with the other mitigation investigations for now. |
Hello, I'm targeting bare metal on
mipsel-sony-psp
and would love to be able to use unwinding instead of libunwind. I managed to get it mostly working by manually adding an Arch + registers for MIPS and following the bare metal guide + no std sample.Unfortunately I think there's likely some MIPS specific magic required though, as raise exception fails with end of stack (5).
I figured you might be able to point me in the right direction? :)
The text was updated successfully, but these errors were encountered: