User:Superleaf1995: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
Content added Content deleted
mNo edit summary
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Hello I'm Superleaf1995, a C and Assembly coder that has build a lot of MS-DOS programs.
Hello I'm Superleaf1995, a C and Assembly coder that has build a lot of MS-DOS programs.
I'm currently making [[User:Superleaf1995/LeafOS|LeafDOS]], because my username. And participating in [https://gitlab.com/plutonium-os/plutonium Plutonium]

I'm available on IRC (superleaf on chat.freenode.net) and matrix (superleaf1995:chat.endl.site OR superleaf1995:matrix.org).


Userpages:
Userpages:
Line 9: Line 6:
* [[User:Superleaf1995/PCI in assembly|Code of PCI article translated into Intel Assembly]]
* [[User:Superleaf1995/PCI in assembly|Code of PCI article translated into Intel Assembly]]
* [[User:Superleaf1995/lowFS|lowFS specification]]
* [[User:Superleaf1995/lowFS|lowFS specification]]
* [[User:Superleaf1995/Compile GCCMVS under MVS3.8j|Compile GCCMVS under MVS3.8j]]


Send a happy face to COM1:
Send a happy face to COM1:
<source lang="c">
<syntaxhighlight lang="c">
typedef int i;typedef void v;typedef char c;i z(){return inb(0x3F8+5)&32;}w(c a){while(!z()){}outb(0x3F8,a);}u(){w(':');w(')');}
typedef int i;typedef void v;typedef char c;i z(){return inb(0x3F8+5)&32;}w(c a){while(!z()){}outb(0x3F8,a);}u(){w(':');w(')');}
</syntaxhighlight>
</source>

== 390 Bits ==

stack preparation for thread switching:
<syntaxhighlight lang="c">
/* follows MVS calling convention (used by gccmvs) */
void SchedPrepareThreadStack(struct thread* thread)
{
/* R13 is used as a stack pointer, now we have to setup a few things up */
thread->context.r15 = (unsigned int)thread->stack + stack_size;

/* stack+76 should point to stack+180 (because this would be the next frame!) */
*((uint32_t *)(&((uint8_t *)thread->stack)[76])) = (&((uint8_t *)thread->stack)[180]);
*((uint32_t *)(&((uint8_t *)thread->stack)[8])) = (&((uint8_t *)thread->stack)[180]);

/* Set backchain to 0 for stack unwinding */
*((uint32_t *)(&((uint8_t *)thread->stack)[4])) = NULL;
*((uint32_t *)(&((uint8_t *)thread->stack)[8])) = NULL;
return;
}
</syntaxhighlight>

stack unwinding:
<syntaxhighlight lang="c">
int DbgUnwindStack(cpu_context *ctx_frame)
{
extern uint32_t __stack[1024]; /* your kernel stack*/
uint8_t *frame = (uint8_t *)ctx_frame->r13;

/* Corrupt stack pointer? */
if((ptrdiff_t)frame < (ptrdiff_t)&__stack) {
KeDebugPrint("Potentially corrupt stack, (SP=%x)\r\n", (unsigned int)frame);
frame = (uint8_t *)&__stack;
}

/* Pointer to top of the stack */
while(frame != NULL) {
/* R14 is stored on frame+12; and holds the address of the return point of the caller */
uint32_t retaddr = *((uint32_t *)&frame[12]);
struct DebugSymData *retsym = DbgGetSymbol((void *)retaddr);
/* And R15 is also stored on frame+16, and contains the branching/base address of the callee */
uint32_t calladdr = *((uint32_t *)&frame[16]);
struct DebugSymData *callsym = DbgGetSymbol((void *)calladdr);

if(retsym != NULL) {
KeDebugPrint("RET=(%i=%s:%i)\r\n", (unsigned int)retaddr, retsym->name, (int)((ptrdiff_t)retaddr - (ptrdiff_t)retsym->addr));
}

if(callsym != NULL) {
KeDebugPrint("CALL=(%x=%s:%i)\r\n", (unsigned int)calladdr, callsym->name, (int)((ptrdiff_t)calladdr - (ptrdiff_t)callsym->addr));
}

/* Get the forward chain */
KeDebugPrint("%p\r\n", (unsigned int)frame);
frame = *((uint8_t **)(&frame[8]));
}
return 0;
}
</syntaxhighlight>

Latest revision as of 07:18, 9 June 2024

Hello I'm Superleaf1995, a C and Assembly coder that has build a lot of MS-DOS programs.

Userpages:

Send a happy face to COM1:

typedef int i;typedef void v;typedef char c;i z(){return inb(0x3F8+5)&32;}w(c a){while(!z()){}outb(0x3F8,a);}u(){w(':');w(')');}

390 Bits

stack preparation for thread switching:

/* follows MVS calling convention (used by gccmvs) */
void SchedPrepareThreadStack(struct thread* thread)
{
    /* R13 is used as a stack pointer, now we have to setup a few things up */
    thread->context.r15 = (unsigned int)thread->stack + stack_size;

    /* stack+76 should point to stack+180 (because this would be the next frame!) */
    *((uint32_t *)(&((uint8_t *)thread->stack)[76])) = (&((uint8_t *)thread->stack)[180]);
    *((uint32_t *)(&((uint8_t *)thread->stack)[8])) = (&((uint8_t *)thread->stack)[180]);

    /* Set backchain to 0 for stack unwinding */
    *((uint32_t *)(&((uint8_t *)thread->stack)[4])) = NULL;
    *((uint32_t *)(&((uint8_t *)thread->stack)[8])) = NULL;
    return;
}

stack unwinding:

int DbgUnwindStack(cpu_context *ctx_frame)
{
    extern uint32_t __stack[1024]; /* your kernel stack*/
    uint8_t *frame = (uint8_t *)ctx_frame->r13;

    /* Corrupt stack pointer? */
    if((ptrdiff_t)frame < (ptrdiff_t)&__stack) {
        KeDebugPrint("Potentially corrupt stack, (SP=%x)\r\n", (unsigned int)frame);
        frame = (uint8_t *)&__stack;
    }

    /* Pointer to top of the stack */
    while(frame != NULL) {
        /* R14 is stored on frame+12; and holds the address of the return point of the caller */
        uint32_t retaddr = *((uint32_t *)&frame[12]);
        struct DebugSymData *retsym = DbgGetSymbol((void *)retaddr);
        /* And R15 is also stored on frame+16, and contains the branching/base address of the callee */
        uint32_t calladdr = *((uint32_t *)&frame[16]);
        struct DebugSymData *callsym = DbgGetSymbol((void *)calladdr);

        if(retsym != NULL) {
            KeDebugPrint("RET=(%i=%s:%i)\r\n", (unsigned int)retaddr, retsym->name, (int)((ptrdiff_t)retaddr - (ptrdiff_t)retsym->addr));
        }

        if(callsym != NULL) {
            KeDebugPrint("CALL=(%x=%s:%i)\r\n", (unsigned int)calladdr, callsym->name, (int)((ptrdiff_t)calladdr - (ptrdiff_t)callsym->addr));
        }

        /* Get the forward chain */
        KeDebugPrint("%p\r\n", (unsigned int)frame);
        frame = *((uint8_t **)(&frame[8]));
    }
    return 0;
}