SPARC window_overflow - window

Suppose I have 8 windows like this figure: http://www.sics.se/~psm/sparcwin.gif
And I'm right in that situation, WIM points to w7, and I'm in window w0.
Suppose that in this window, I'm going to call some function that recives one parameter. So I set the parameter value to %o1 (to let the function recive it in %i0).
Ok, then I make the call, and the function does a 'save'. WIM in that window bit is 1, so a window_overflow is triggered. What I understood about this, is that the handler save on the stack of window w7 (%sp), the registers %i1,..,%i7,%l0,..,%l7, to let then 'when going back' in the window_underflow recover that window.
My question is... when the window is saved, the originals %i0,...,%i7 of w7 where lost due to now are the parameters of the function that the program in w0 called (because I set %o0,.. in w0 before calling and then make the 'save' fault). So this "system" does not make sense, so I guess I'm missing something.
Another similar question. Suppose my program in w0 does not call a function, but use %o0,%o1,.. as "local" variables, I would have the same problem without even know that I killed %i0,%i1,.. of w7.
ANSWER: I found that the invalid windows is already saved in the stack, so when the 'save' is done, the window_overflow handler would save w6 in the stack (and set WIM to w6). This obviously explains all about my question. I guess I confused myselft when seeing an handler example of this trap and not remembering that in V8 it always decrements CWP without checking WIM.

Related

How did debuggers for 16-bit real mode programs produce stack traces?

I'm messing around with running old DOS programs in an emulator, and I've gotten to the point where I'd like to trace the program's stack. However, I'm running into a problem, specifically how to detect near calls and far calls. Some pretext:
A near call pushes only the IP onto the stack, and is expected to be paired with a ret which pops only the IP to return to.
A far call pushes both the CS and IP onto the stack, and is expected to be paired with a retf which pops both the CS and IP to return to.
There is no way to know whether a call is a near call or a far call, except by knowing which kind of instruction called it, or which return it uses.
Luckily, for the period this program was developed in, BP-based stack frames were very common, so walking the stack doesn't seem to be a problem: I just follow the BP-chain. Unfortunately, getting the CS and/or IP is difficult, because there doesn't seem to be any way for me to determine whether a call is a near call or a far call by looking at the stack alone.
I have metadata about functions available, so I can tell whether a function is a near or far call if I already know the actual CS and IP, but I can't figure out the IP and CS unless I already know if it's a far call or near call.
I'm having a little success by just guessing and seeing if my guess results in a valid function lookup, but I think this method will produce a lot of false positives.
So my question is this: How did debuggers of the DOS era deal with this problem and produce stack traces? Is there some algorithm for this I'm missing, or did they just encode debug information in the stack? (If this is the case, then I'll have to come up with something else.)
Just a guess, I've never actually used 16-bit x86 development tools (modern or back in the day):
You know the CS:IP value of the current function (or one that triggered a fault or whatever from an exception frame).
You might have metadata that tells you whether this is a "far" function that's called with a far call or not. Or you could attempt decoding until you get to a retn or retf, and use that to decide whether the return address is a near IP or a far CS:IP.
(Assuming this is a normal function that returns with some kind of ret. Or if it ends with a jmp tailcall to another function, then the return address probably matches that, but that's another level of assumptions. And figuring out that a near jmp is the end of a function instead of just a jump within a large function is am ambiguous problem without any symbol metadata.)
But anyway, apply the same thing to the parent function: after one level of successful backtracing, you now have the CS:IP of the instruction after the call in your parent function, and the SS:BP value of the BP linked list.
And BTW, yes there's a very good reason for legacy BP stack frames being widely used: [SP] isn't a valid 16-bit addressing mode, and only [BP] as a base implies SS as a segment, so yes, using BP for access to the stack was the only good option for random access (not just push/pop for temporaries). No reason not to save/restore it first (before any other registers or reserving stack space) to make a conventional stack-frame.

.call alternative in kernel mode

I see that .call is not supported in kernel mode for WinDbg. But I seem to remember GDB does allow call with kernel mode debugging.
Can anyone:
Suggest how I could call an arbitrary function in WinDbg in kernel mode debugging
Explain why .call is only supported in user mode?
Raymond Chen describes how .call is implemented here:
Stupid debugger tricks: Calling functions and methods
Back in the old days, if you wanted to call a function from inside the debugger, you had to do it by hand: Save the registers, push the parameters onto the stack (or into registers if the function uses fastcall or thiscall) push the address of the ntdll!DbgBreakPoint function, move the instruction pointer to the start of the function you want to call, then hit "g" to resume execution. The function runs then returns to the ntdll!DbgBreakPoint, where the debugger regains control and you can look at the results. Then restore the registers (including the original instruction pointer) and resume debugging. (That paragraph was just a quick recap; I'm assuming you already knew that.)
You would need a different return address since ntdll!DbgBreakPoint is a user mode address. Since he mentions using g then you would want to set a breakpoint on the return address.

IoGetDeviceObjectPointer() fails with no return status

This is my code:
UNICODE_STRING symbol;
WCHAR ntNameBuffer[128];
swprintf(ntNameBuffer, L"\\Device\\Harddisk1\\Partition1");
RtlInitUnicodeString(&symbol, ntNameBuffer);
KdPrint(("OSNVss:symbol is %ws\n",symbol.Buffer));
status = IoGetDeviceObjectPointer(&symbol,
FILE_READ_DATA,
&pDiskFileObject,
&pDiskDeviceObject);
My driver is next-lower-level of \\Device\\Harddisk1\\Partition1.
When I call IoGetDeviceObjectPointer it will fail and no status returns and it not continue do remaining code.
When I use windbg debug this, it will break with a intelpm.sys;
If I change the objectname to "\\Device\\Harddisk1\\Partition2" (the partition2 is really existing), it will success call
If I change objectname to "\\Device\\Harddisk1\\Partition3", (the partition3 is not existing), it failed and return status = 0xc0000034, mean objectname is not existing.
Does anybody know why when I use object "\\Device\\Harddisk1\\Partition1" it fails and no return status? thanks very much!
First and foremost: what are you trying to achieve and what driver model are you using? What bitness, what OS versions are targeted and on which OS version does it fail? Furthermore: you are at the correct IRQL for the call and is running inside a system thread, right? From which of your driver's entry points (IRP_MJ_*, DriverEntry ...) are you calling this code?
Anyway, was re-reading the docs on this function. Noting in particular the part:
The IoGetDeviceObjectPointer routine returns a pointer to the top object in the named device object's stack and a pointer to the
corresponding file object, if the requested access to the objects can
be granted.
and:
IoGetDeviceObjectPointer establishes a "connection" between the caller
and the next-lower-level driver. A successful caller can use the
returned device object pointer to initialize its own device objects.
It can also be used as as an argument to IoAttachDeviceToDeviceStack,
IoCallDriver, and any routine that creates IRPs for lower drivers. The
returned pointer is a required argument to IoCallDriver.
You don't say, but if you are doing this on a 32bit system, it may be worthwhile tracking down what's going on with IrpTracker. However, my guess is that said "connection" or rather the request for it gets somehow swallowed by the next-lower-level driver or so.
It is also hard to say what kind of driver you are writing here (and yes, this can be important).
Try not just breaking at a particular point before or after the fact but rather follow the stack that the IRP would travel downwards in the target device object's stack.
But thinking about it, you probably aren't attached to the stack at all (for whatever reason). Could it be that you actually should be using IoGetDiskDeviceObject instead, in order to get the actual underlying device object (at the bottom of the stack) and not a reference to the top-level object attached?
Last but not least: don't forget you can also ask this question over on the OSR mailing lists. There are plenty of seasoned professionals there who may have run into the exact same problem (assuming you are doing all of the things correct that I asked about).
thanks everyone , I solve this problem; what cause this problem is it becoming synchronous; when I
call IoGetDeviceObjectPointer , it will generate an new Irp IRP_MJ_WRITER which pass though from high level, when this irp reach my driver, my thread which handle IRP is the same thread whilch call IoGetDeviceObjectPointer ,so it become drop-dead halt;

How to get the program call stack trace?

My program can be started in 2 ways:
the START OF SELECTION event that calls a MAIN function from one of my local classes.
the ZAVGTTA4 transaction that calls the same method.
at PAI, for the BACK event, when calling LEAVE TO SCREEN '0'., my program behaves in 2 ways according to how it was started. I want to get back to the selection screen (1000).
I thought about querying the stack, where i'm sure to find how my program was called. I can see that the stack trace is different, but i don't know how to acces my stack from the program. I've heard about the RTTI that i think might be able to help me.
You may try SYSTEM_CALLSTACK.
DATA:
abap_callstack_line TYPE abap_callstack_line,
callstack TYPE abap_callstack.
CALL FUNCTION 'SYSTEM_CALLSTACK'
EXPORTING
max_level = 4
IMPORTING
callstack = callstack.
But in your case I would prefer an additional parameter and the calling place can fill this entry. I would not call the parameter called_by but something like behaviour or mode.

Windows Client graphics written off the window to upper-left of screen

I have a Windows WinMain() window in which I write simple graphics -- merely LineTo() and FillRect(). The rectangles move around. After about an hour, the output that used o go to the main window, all of a sudden goes to the upper left corner of my screen -- as if client coordinates were being interpreted as screen coordinates. My GetDC()'s and ReleaseDC()'s seem to be balanced, and I even checked the return value from ReleaseDC(), make sure it is not 0 (per MSDN). Sometimes the output moves back to my main window. When I got to the debugger (VS 2010), my coordinates do not seem amiss--but output is going to the wrong place. I handle WM_PAINT, WM_CREATE, WM_TIMER, and a few others. I do not know how to debug this. Any help would be appreciated.
This has 'not checking return values' written all over it. Pretty crucial in raw Win32 programming, most every API function returns a boolean or a handle where FALSE or NULL indicates failure. GetLastError() provides the error code.
A cheap way to check for this without modifying code is by using the debugger to look at the EAX register value after the API call. A 0 indicates failure. In Visual Studio you can do so by using the #eax and #err pseudo variables in the Watch window, respectively the function return value and the GetLastError value.
This goes bad once Windows starts failing API calls, probably because of a resource leak. You can see it with TaskMgr.exe, Processes tab. View + Select Columns and tick Handles, USER objects and GDI objects. It is usually the latter, restoring the device context and releasing drawing objects is very easy to fumble. You don't have to wait until it fails, a steadily climbing number in one of those columns is the giveaway. It goes belly-up when the value hits 10,000
You must be calling GetDC(NULL) somewhere by mistake, which would get the DC for the entire desktop.
You could make all your GetDC calls call a wrapper function which asserts if the argument is NULL to help track this down:
#include <assert.h>
HDC GetDCAssert(HWND hWnd)
{
assert(hWnd);
return ::GetDC(hWnd);
}

Resources