ARMv8 exception vector significance of EL0_SP - arm64

I am new to ARMv8 architecture and while reading the v8 exception vectors I am not able to understand significance of adding SP_EL0 level vectors while SP_ELx vector set exists. What I am trying to find a use case where this is useful. I understand that when the exception is taken at same level by default the stack of same exception level is used for example if EL2 (Hyp) mode is defined then if exception occurs while being at EL2 level the stack defined at EL2 will be used but not sure if I configure to use EL0 level stack under what use cases this could be useful ? Can some one give a use case and explain ?
Also while going through the spec it seems these two different stack usage idea is taken from Cortex-M architecture but i am not very clear with thread and handler modes as well. Can any one explain it ?
Just wanted to add here that ARMv7 doesn't have thread and handler concept so i am not clear requirement in ARMv8.
Thanks

SP_EL0 is the "normal" stack pointer. Your code that runs in any EL should be running on SP_EL0 whenever it can. SP_EL1/2/3 is the "exception" stack pointer for that mode. When an exception, fault, or interrupt happens, the processor switches to this stack (and possibly switches EL). Your exception handler code should do what it needs to save the exception state and get itself onto SP_EL0 to complete handling the exception.
That is, your EL0 user code, your EL1 kernel code, your EL2 hypervisor, and your EL3 monitor should all be using SP_EL0 except in the early stages of their exception handlers. If you were to take a nested exception while on SP_ELx (non-zero), you could blow over your stack, ELR, FAR, etc. which is why you want to save these and get back to SP_EL0 as soon as you can.

Related

Do local variables in webassembly live in the same stack?

I know that webassembly is a stack-based virtual machine (or that it is bytecode run on such a machine). This means that instructions like (i32.const) or (i32.load) push values onto the stack and instructions like (i32.add) or will pop values from the stack to use. However, does that mean that local variables made with:
(local $var i32)
inside of a function automatically reserve space in the stack? Or is that only true for "executable" instructions? Wouldn't it be possible to pop the stack local variable that way? Also how would the amount of the stack to pop be determined when returning from a function call?
I realize that local variables have their own instructions like (local.set) and (local.get), so it feels like they live on a different stack than the one where temporary data from executable instructions live.
How one will implement the WebAssembly runtime is not strictly defined by the specification. What is defined is the outcome of the execution.
Some instructions can trap in certain cases. These cases are defined by the specification. For a module to be valid, the local get/set instructions indexes (or names) must be valid in their current scopes. That means that during runtime these instructions must not trap because the indexes/names they reference are invalid.
That means that the runtime environment must allocate the needed stack space for all locals during the call of the function. The implementation may have limitations on the frames/values in the stack. There are discussions about the maximum evaluation stack depth. From the specs:
If the runtime limits of an implementation are exceeded during execution of a computation, then it may terminate that computation and report an embedder-specific error to the invoking code.
Additionally to that the stack in WebAssembly is polymorphic and at runtime a valid program must not be able to pop more then it has pushed. However, during validation it is possible, cite:
However, a polymorphic stack cannot underflow, but instead generates Unknown types as needed.

Using pthreads with MPICH

I am having trouble using pthreads in my MPI program. My program runs fine without involving pthreads. But I then decided to execute a time-consuming operation in parallel and hence I create a pthread that does the following (MPI_Probe, MPI_Get_count, and MPI_Recv). My program fails at MPI_Probe and no error code is returned. This is how I initialize the MPI environment
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided_threading_support);
The provided threading support is '3' which I assume is MPI_THREAD_SERIALIZED. Any ideas on how I can solve this problem?
The provided threading support is '3' which I assume is MPI_THREAD_SERIALIZED.
The MPI standard defines thread support levels as named constants and only requires that their values are monotonic, i.e. MPI_THREAD_SINGLE < MPI_THREAD_FUNNELED < MPI_THREAD_SERIALIZED < MPI_THREAD_MULTIPLE. The actual numeric values are implementation-specific and should never be used or compared against.
MPI communication calls by default never return error codes other than MPI_SUCCESS. The reason for that is, MPI calls the communicator's error handler before an MPI call returns and all communicators are initially created with MPI_ERRORS_ARE_FATAL installed as their error handler. That error handler terminates the program and usually prints some debugging information, e.g. the reason for the failure. Both MPICH (and its countless variants) and Open MPI produce quite elaborate reports on what led to the termination.
To enable user error handling on communicator comm, you should make the following call:
MPI_Comm_set_errhandler(comm, MPI_ERRORS_RETURN);
Watch out for the error codes returned - their numerical values are also implementation-specific.
If your MPI implementation isn't willing to give you MPI_THREAD_MULTIPLE, there's three things you can do:
Get a new MPI implementation.
Protect MPI calls with a critical section.
Cut it out with the threading thing.
I would suggest #3. The whole point of MPI is parallelism -- if you find yourself creating multiple threads for a single MPI subprocess, you should consider whether those threads should have been independent subprocesses to begin with.
Particularly with MPI_THREAD_MULTIPLE. I could maybe see a use for MPI_THREAD_SERIALIZED, if your threads are sub-subprocess workers for the main subprocess thread... but MULTIPLE implies that you're tossing data around all over the place. That loses you the primary convenience offered by MPI, namely synchronization. You'll find yourself essentially reimplementing MPI on top of MPI.
Okay, now that you've read all that, the punchline: 3 is MPI_THREAD_MULTIPLE. But seriously. Reconsider your architecture.

Delphi exceptions not letting me see local variables

When debugging in Delphi, an exception will correctly tell me the line of code causing the fault, but I cannot get access to any local variables. Is this a limitation in the debugger? Or am I missing something simple? At present, I have to mirror all local variables to a global on the line before the fault, recompile the program and hope to be able to repeat the same exception.
For example
MyArray[I]:=Foo(...);
If I is out of bounds (with bounds checking turned on), I cannot see what the variable I is, unless I mirrored it to a globally scoped debug variable on the previous line.
Or if I have
MyInteger:=Trunc(MyFloat),
and MyFloat is 6.1E+17, I have no idea what it's value is.
You can see the values of local variables when you select the proper line in the call stack window. It is usually one or two lines before the exception is raised.
I don't have the exact version at hand when this has been implemented, but it is definitely one of the newer versions.
The "problem" is caused by the compiler as far as I know. The optimization feature of the compiler acts like a garbage collector, it frees the variables declared within a function when not used any more.
To overcome the problem, write a exception handler and make a fake use of the variable within the exception catch block.

Converting C to Delphi - Guidance

I am converting a low level C library to Delphi.
I find a lot of casts. I think it is normal in C World. I think I am safe in throwing them out. Integer is 32 bit only here. What do you think?
What could be the overhead of OOP if I convert it to objects etc?
Similarly I want to know the cost of try .. finally and exceptions.
Give me any tip that you think would be useful.
3 Similarly I want to know the cost of try .. finally and exceptions.
The cost of a try ... finally is negligable except in tight loops (put them around and not in the loop). Use them liberally to protect all your resources by balancing all instantiations / opens / allocations with free's / closes / de-allocations.
<code-to-open-a-file>
try
...
finally
<code-to-close-the-file>
end;
The cost of a try ... except is noticeably higher. Use them to respond to exceptions occuring, but only when you can actually take some meaningful action like counter acting the reason for the exception, logging some specific information that would be lost at a higher level in your app, etc. Otherwise let the exception propagate to the caller of your code so it can (eventually) be caught at a more general level.
Never let exceptions escape your application or library or any thread within it.
Never "eat" exceptions by having an empty except block:
try
...
except
end;
There really is only one type of situation where this makes sense: catching exceptions in code that logs exceptions... And then always add a comment to say why you are eating the exception.
You may find some helpful suggestions in the answers to this question on SO:
Best resources for converting C/C++ dll headers to Delphi?
You may also want to take a look at the C-To-Pas project which aims to automate much of the conversion from C to Delphi.
Moving from a procedural language to OOP is a big leap. There are many advantages of using OOP. OOPs are easier to code and maintain. Choosing Delphi PL is a good choice because it can also access at low level by inserting assembly codes. Try-catch is used to prevent program crashes at run time because of exceptions.

Why does execution jump to the end of a proc after an exception?

When an unhandled exception happens while debugging some code in any procedure/function/method, the debugger stops there and shows the message.
If I now continue debugging step by step, the execution jumps directly from the line that created the exception to the end of the current procedure (if there is no finally block).
Woulnd't it be just as good to continue with the next line of the current procedure?
Why jump to the end of the proc and continue with the calling procedure?
Is this just by design or is there a good reason for it?
An exception is a unexpected situation, that why processings is stopped.
The jump to the end of the procedure is an invisible finally statement to release any locally "allocated" memory, like strings, interfaces, records etc.
If you want to handle a exception the you have to incapsulate the call that can give an exception with try .. except statement, and use an "on" clause to only handle that particular exception that you want to handle.
In the except you can inspect variables in the debugger and in code you can raise the exception again if needed.
In general, an uncaught exception will execute a hidden "finally" in each function on the stack, as it "unwinds" up to an exception handler. This cleans up local variables in each stackframe. In languages like C++ with the Resource Acquisition Is Initialization paradigm, it will also cause destructors to run.
Eventually, somewhere up the callstack, the exception will be caught by a handler. If there's no explicit one, the system-provided one will kill the process, because what else can it reasonably do?
Throwing an exception is a way of saying "Something unexpected happening. I don't know how to handle this". In such case it it better not to do anything (other than throwing the exception) than to try to continue, not knowing if what you're doing is correct.
In real life you have the same kind of thing: If someone asks you to count to 10 in Hebrew (or some language you don't know), you just say you don't know. You don't go ahead and try anyway.
I would expect it to jump to the end of the proc, and then jump to the except or finally block of the calling proc. Does it really continue in the calling proc as if nothing had happened? What does it use as the return value (if it's a function call)?
Continuing with the next line in the original proc/function would be a very bad thing - it would mean the code executing radically differently in a debugger to in release (where the exception would indeed cause execution to exit that proc/function unless there's an except/finally block). Why should debugging let you ignore exceptions completely?
It has to unwind the stack to find a handler.
I do agree it's very annoying behavior. Continuing isn't an option but it sure would make life easier if the debugger was pointing to the spot that threw it with the local variables still intact. Obviously, the next step would be to the hidden finally, not to the next line.
I just want to be able to examine everything I can about what caused it. I was just fighting this not very long ago. Text parsing, I KNEW the offending string contained no non-numeric characters (sanity limits mean the overflow case should never happen, it's my data file, all I'm worried about is oopses) and so I didn't put an exception handler around the StrToInt--what's this nonsense about it not being a valid number????? Yup--the routine wouldn't call it with anything non-numeric in the buffer--but an empty string has nothing non-numeric in it!

Resources