Skip to content
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

Possible memory corruption originating from libnix13 #84

Closed
mankeli opened this issue Jun 5, 2024 · 14 comments
Closed

Possible memory corruption originating from libnix13 #84

mankeli opened this issue Jun 5, 2024 · 14 comments

Comments

@mankeli
Copy link

mankeli commented Jun 5, 2024

A mystery blit corrupts chip memory before main() in binary compiled with bebbo-gcc. Investigation by a/b in this EAB thread suggests that there's DOS I/O calls happening when system is disabled.

The code in main() also disables system, but doesn't do any I/O afterwards. I've verified that the chip data is loaded into memory, but then gets stomped by the blit.

CFLAGS for compiling are -mcrt=nix13 -O2 -Wall -mtune=68000. I tried to look for obvious problem in libnix, but could find anything definitive. Stackswap seems to disable system for a short time, and command line parsing uses some Dos calls, and both are added to the libc init list, but not sure why the memory corruption happens.

@bebbo
Copy link
Owner

bebbo commented Jun 5, 2024

sorry, that's not enough info to do anything

@bebbo
Copy link
Owner

bebbo commented Jun 5, 2024

40a10b7c :   007c 4e5d            ORSR.W #$4e5d
40a10b80 :   4e75                 RTS.L
40a10b82 :   303c 0f0f            MOVE.W #$0f0f,d0
40a10b86 :   33c0 00df f180       MOVE.W d0,$00dff180
40a10b8c :   33c0 00df f180       MOVE.W d0,$00dff180
40a10b92 :   60f2                 BT.B #$f2
40a10b94 :   2f0a                 MOVE.L a2,-(a7) [40000014]
40a10b96 :   700a                 MOVE.L #$0a,d0
40a10b98 : * 21c0 0090            MOVE.L d0,$0090.w [00f80c4c]
40a10b9c :   4eb9 40a1 73c8       JSR.L $40a173c8
40a10ba2 :   33fc 7fff 00df f09a  MOVE.W #$7fff,$00dff09a
40a10baa :   33fc 7fff 00df f09c  MOVE.W #$7fff,$00dff09c
40a10bb2 :   33fc 7ff0 00df f096  MOVE.W #$7ff0,$00dff096
40a10bba :   33fc 0000 00df f102  MOVE.W #$0000,$00dff102
40a10bc2 :   3039 00df f004       MOVE.W $00dff004,d0
40a10bc8 :   0800 0000            BTST.L #$0000,d0
40a10bcc :   67f4                 BEQ.B #$f4

writing at address 0x00000090 is not part of libnix.

@mankeli
Copy link
Author

mankeli commented Jun 5, 2024

No, it most certainly is not part of libnix, but it should be safe to write there on Amiga. (68000 trap vector area)

It is there to get memwatch breakpoint triggered in the limited UAE debugger, to verify that the memory stomping indeed happens before any "user code" is reached. I'm gonna investigate it further, and possibly find a workaround. Just wanted to know if you have any thoughts about it.

@mankeli
Copy link
Author

mankeli commented Jun 6, 2024

adding void __nocommandline(){}; override to demo code seems to fix the wb startup!

@bebbo
Copy link
Owner

bebbo commented Jun 7, 2024

I guess you already disabled __initlibraries.

@mankeli
Copy link
Author

mankeli commented Jun 7, 2024

I guess you already disabled __initlibraries.

Yeah I tried - it gives "Software error - task held" error from both cli and wb

@bebbo
Copy link
Owner

bebbo commented Jun 8, 2024

I guess you already disabled __initlibraries.

Yeah I tried - it gives "Software error - task held" error from both cli and wb

You should only tinker with internal topics if you are familiar with them and know the consequences.

__nocommandline requires a valid DOSBase and is called before your main is called. It relies on the fact that __initlibraries run before.
And there are more functions which require the DOSBase or maybe a different library to be present already.

This isn't a bug in libnix, it's rather a wrong use of libnix.

@mankeli
Copy link
Author

mankeli commented Jun 12, 2024

Yeah I didn't try it [ what __initlibraries does ] very throughly, but I think the bug with cmd line parsing is real. Not sure what causes it though.

@bebbo
Copy link
Owner

bebbo commented Jun 12, 2024

An out of the box kick13 hello world runs without problems from CLI and Workbench. And it's calling __initlibraries plus __nocommandline.

Please provide some source with make instructions to prove your claim.

@bebbo bebbo closed this as completed Jun 21, 2024
@mankeli
Copy link
Author

mankeli commented Jun 27, 2024

Okay. Sorry for the delay, I've been busy. But finally took some time to strip down one of my programs to somewhat minimal test case. I've only tested it on 512/512 A500.

Compilation spell: /opt/amiga/bin/m68k-amigaos-gcc -mcrt=nix13 -O0 -Wall demo.c -o demo.exe

#include <stdio.h>
#include <clib/exec_protos.h>
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <stdbool.h>
extern volatile struct Custom custom;
#define CUSTO(__field)    (uint16_t)(uintptr_t)(&(((struct Custom *) 0)->__field))

//void __nocommandline(){};

void showred()
{
	while(1)
	{
		custom.color[0] = 0x830;
		custom.color[0] = 0x420;
		custom.color[0] = 0x820;
		custom.color[0] = 0x410;
		custom.color[0] = 0x810;
		custom.color[0] = 0x410;
		custom.color[0] = 0x800;
		custom.color[0] = 0x600;
		custom.color[0] = 0xC00;
		custom.color[0] = 0x800;
		custom.color[0] = 0xF00;
		custom.color[0] = 0x800;
		custom.color[0] = 0xC00;
		custom.color[0] = 0x600;
		custom.color[0] = 0x810;
		custom.color[0] = 0x420;
	}
}

void showgreen()
{
	while(1)
	{
		custom.color[0] = 0x083;
		custom.color[0] = 0x042;
		custom.color[0] = 0x082;
		custom.color[0] = 0x041;
		custom.color[0] = 0x081;
		custom.color[0] = 0x041;
		custom.color[0] = 0x080;
		custom.color[0] = 0x060;
		custom.color[0] = 0x0C0;
		custom.color[0] = 0x080;
		custom.color[0] = 0x0F0;
		custom.color[0] = 0x080;
		custom.color[0] = 0x0C0;
		custom.color[0] = 0x060;
		custom.color[0] = 0x081;
		custom.color[0] = 0x042;
	}
}

static __chip uint16_t copperlist1[] =
{
	0x01FE, 0x0000,
	CUSTO(bplpt[0])+0, 0x0000,
	CUSTO(bplpt[0])+2, 0x0000,
	CUSTO(bplpt[1])+0, 0x0000,
	CUSTO(bplpt[1])+2, 0x0000,
	CUSTO(bplpt[2])+0, 0x0000,
	CUSTO(bplpt[2])+2, 0x0000,
	CUSTO(bplpt[3])+0, 0x0000,
	CUSTO(bplpt[3])+2, 0x0000,

	CUSTO(bpl1mod), 3*40,
	CUSTO(bpl2mod), 3*40,

	CUSTO(bplcon0), 0x0000,

//	0x6001, 0xFFFE,
	CUSTO(bplcon0), 0x7800,
	CUSTO(bplcon1), 0x8800,

	CUSTO(color[0]), 0x0000,


	0x4e01, 0xFFFE,
	CUSTO(bplcon0), 0x0000,

	CUSTO(color[0]), 0x0000,
	0x4e01, 0xFFFE,
	CUSTO(color[0]), 0x0111,
	0x7d01, 0xFFFE,
	CUSTO(color[0]), 0x0222,
	0x7e01, 0xFFFE,
	CUSTO(color[0]), 0x0111,
	0x7f01, 0xFFFE,
	CUSTO(color[0]), 0x0222,
	0x8d01, 0xFFFE,
	CUSTO(color[0]), 0x0111,
	0x8e01, 0xFFFE,
	CUSTO(color[0]), 0x0222,
	0x8f01, 0xFFFE,
	CUSTO(color[0]), 0x0111,

	0xfe01, 0xFFFE,

	CUSTO(color[0]), 0x0000,
	CUSTO(bplcon0), 0x0000,

	CUSTO(bplpt[0])+0, 0x0000,
	CUSTO(bplpt[0])+2, 0x0000,
	CUSTO(bplpt[1])+0, 0x0000,
	CUSTO(bplpt[1])+2, 0x0000,
	CUSTO(bplpt[2])+0, 0x0000,
	CUSTO(bplpt[2])+2, 0x0000,
	CUSTO(bplpt[3])+0, 0x0000,
	CUSTO(bplpt[3])+2, 0x0000,
	CUSTO(bplpt[4])+0, 0x0000, // AGA
	CUSTO(bplpt[4])+2, 0x0000, // AGA
	CUSTO(bplpt[5])+0, 0x0000, // AGA
	CUSTO(bplpt[5])+2, 0x0000, // AGA

	0xff01, 0xFFFE,

	// vv do not move!

	CUSTO(ddfstrt), 0x0038,

	CUSTO(bplcon0), 0x7800,
	CUSTO(bplcon1), 0x0000,

	CUSTO(bpl1mod), 3*40,
	CUSTO(bpl2mod), 3*40,


	CUSTO(intreq), 0x8010,

	CUSTO(dmacon), 0x0400,

	0xff0b, 0xFFFE,

	0xffdf, 0xFFFE,

	0x0b01, 0xFFFE,
	CUSTO(dmacon), 0,

	0x2c01, 0xFFFE,
	CUSTO(color[0]), 0x0000,

	// 45 lines

	0xFFFF, 0xFFFE
};

bool searchforvalue()
{
	uintptr_t dmacon_addr = 0;

	for (int i = 0; i < sizeof(copperlist1)/2; i++)
	{
		if (copperlist1[i] == CUSTO(dmacon))
		{
			dmacon_addr = (uintptr_t)(&copperlist1[i])+3;
		}
	}

	return dmacon_addr != 0;
}



int main(void)
{
	Disable();

	custom.intena = 0x7FFF;
	custom.intreq = 0x7FFF;
	custom.dmacon = 0x7FFF;
	custom.bplcon1 = 0;

	if (searchforvalue())
		showgreen();
	else
		showred();

	return 0;
}

Precompiled testcase:
nixtestcase.zip

nixtestcase.adf contains demopack.exe which should show green screen. It shows red screen if the memory has been stomped. There's startup-sequence on disk, or you can launch it manually from cli and it should show green screen.

The included wbrig.adf can be also used. Insert wbrig.adf to df0 and nixtestcase.adf to df1. It should boot to green screen.
But if you move cli window during the "Waiting x" prints, the memory gets stomped and it shows the red screen. Same can be observed if you launch it from regular wb. It might also guru.

As I said before, enabling void __nocommandline(){}; seems to fix it.

@mankeli
Copy link
Author

mankeli commented Jun 28, 2024

@bebbo should this ticket be re-opened?

@bebbo
Copy link
Owner

bebbo commented Jun 28, 2024

@bebbo should this ticket be re-opened?

not needed, it's fixed now: The lock is null, which wasn't checked.

@mankeli
Copy link
Author

mankeli commented Jun 28, 2024

is it fixed in libnix13 too?

@bebbo
Copy link
Owner

bebbo commented Jun 29, 2024

is it fixed in libnix13 too?

yes, you need to run a make update && make libnix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants