-
Notifications
You must be signed in to change notification settings - Fork 24
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
Pointers are not processed correctly when stored in global structure #14
Comments
Hi again, just found out that this problem seems not related to struct but to global pointers in general. So if you just leave out the struct but define a global pointer p_u32 you get the same issue without using any struct. Best regards, |
ok... this is even stranger in my case. I tried to run it both with or1ksim and using icarus and the mor1kx-generic system. In both cases it exists after printing
No hanging. No errors. Nothing. Haven't looked at the traces yet though |
Which toolchain are you using btw? I assumed newlib (or1k-elf) and in my case, there is an alignment exception that causes the program to exit when it tries to load |
Thanks that you tried and confirmed the issue. Yes, I am using newlib. Modelsim does not exit but keeps running the hardware sim. In the wave there is almost no activity any more except the program counter toggling between two values. Just to emphasize for someone who also wants to try: it seems no problem with the struct or the printf or the (unsigned int)-cast for the printf but with the global pointer access only. A more minimalistic program to show the problem is
|
Sorry for the delay. Forgot about this one. I think the last example is actually illegal, as you're doing an unaligned word load. I see that the CPU (correctly) jumps to 0x600 which is the exception handler for unaligned accesses. The exception handler itself doesn't do anything clever to handle align exception, and just jumps to exit to terminate the program instead. This is the easiest thing to do, but it doesn't provide much information to the user. There are some other ways this could be done instead. We could print out an error message with the address of the unaligned access. This is what we do in the linux kernel. We could also try to load the word byte by byte in the exception handler and this would fix the problem. I'm not sure however if there are any other implications to this that I'm unaware of, and someone would need to write the code for it. I'm still a bit surprised however that the simulation just keeps running. I would have assumed that mor1kx-monitor should have caught this and stopped the simulation. Are you running this through FuseSoC, and if so, which system are you running? |
Thanks for your response but I do not agree ;-) . Why should this last example be illegal? It WORKS on openrisc when the pointer is local (i.e. moved into the main function). Then I can printf the pointer address and the result, see that the address LSBit is '1' (so not DWORD aligned) and get the right result (0x02030405). So I assume the code for the byte access is already there somewhere but it is not used when the pointer is global. (Does the compiler have other possibilities to optimize the local pointer which are not available to the global one?) It also WORKS on Linux when compiling the example for a (64 bit Debian) Linux machine with "standard" gcc, no matter if global or local pointer. (Do you mean this with Linux kernel?) I do not use FuseSoc but orpsoc only with some hardware accelerators plugged to the Wishbone interface. The simulation keeps running as it is a Modelsim hardware simulation which does not care if the openrisc state machine comes to an exception state but continues simulating the hardware. |
ok, this is strange. I get an unaligned exception even if I move the pointer into the function. Maybe it's something that changed in gcc/binutils? Which versions are you using? I would still argue that this is not valid code, but let's push that aside for now to instead figure out why this works with local pointers :) With the Linux kernel, I mean a program compiled with one of the Linux toolchains (e.g. or1k-linux-musl), running under Linux on an OpenRISC CPU. |
It would also be great if you could send me the elf files for the shorter example, with both local and global pointers so I can take a look at the disassembly |
This is strange indeed. My or1k-elf-gcc version is 4.9.2 . I added the two elf files to the following zip: Let me know if I can further help you. |
Hi,
Following issue occurs on a mor1kx but I think it may be a toolchain problem.
When defining a byte array and casting parts of the byte array to a DWORD, the address of the first byte of the DWORD is probably not DWORD aligned (i.e. &byte_array[1] = 0x00000001 ). Normally, this is no problem and the DWORD pointer can be dereferenced correctly (i.e. p_u32 = (uint32_t *)&byte_array[1]; a=*p_u32;). When storing the DWORD pointer in a global structure, this does not work, the program simply hangs up when trying to dereference the pointer stored in the global struct. Please find below a program to show the problem. The program works fine compiled with standard gcc on a Linux machine but hangs up in Modelsim simulation when compiled with or1k-elf-gcc.
I am not sure to which branch of Openrisc development it belongs but it may be a toolchain problem as the dereferencing in general works when using the local struct. Also I am not sure if this is already fixed as I use an older (~1 year) version of mor1kx and toolchain.
Best regards,
Markus
The text was updated successfully, but these errors were encountered: