English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 09 December 2017, 17:06   #1
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,411
Vasm/Vlink odd issue linking

I've run into a bit of a snag. When I was writing a bootblock, at a certain point it stopped working and crashed the Amiga. I disassembled the code in WinUAE and saw something extremely odd.

Somewhere in my code, I had the following:

Code:
.node_loop
        cmp.b #NT_MEMORY,LN_TYPE(A1)
But for some reason, that didn't assemble/link correctly, an erroneous byte (IIRC it had value $08) was added, causing the remaining program to shift by one byte and things went badly.

I tried several variations on this, including

Code:
.node_loop
        moveq    #NT_MEMORY,d6
        cmp.b    LN_TYPE(a1),d6
This also didn't work, again, there was an extra byte (value $08 IIRC) introduced after the moveq command.

The following did work, but I found it very strange that this solved it:
Code:
.node_loop
        moveq    #NT_MEMORY-1,d6    ; Workaround
        addq    #$1,d6
        cmp.b    LN_TYPE(a1),d6
This happened using the following Vasm/Vlink options:
Vasm: -I$(MAINDIR) -I$(SYSTEMDIR) -I$(GFXDIR) -I$(SUPPORTDIR) -I$(PRESENTATIONDIR) -I$(GAMEDIR) -I$(DISKDIR) -kick1hunks -Fhunk -m68000 -allmp
Vlink: -L $(MAINDIR)\..\LIB -l amiga -brawbin1 -s -sc

The used version of Vasm is 1.8a and Vlink 0.16a. I even downloaded the source again and compiled Vasm and Vlink from scratch to see if I just had an old version

Originally I'd probably have just used the workaround posted above and continued work, but now another part of my source code shows the same problem, an added byte after a moveq #20,d6.

I'm really stumped here. It only seems to happen when I use Vlink -brawbin1 (or 2), it works fine when the result is a normal Amiga application. I also tried using -Fvobj instead of -Fhunk and that changed nothing. Same goes for adding -Z to the linker, which I also tried.

Do note it doesn't happen all the time, it seems to depend on the instruction stream before the immediate value, though I can't see what's going wrong.

Has anyone had the same problem? Is there a fix?
Or am I doing something wrong?

P.S. If more code is needed, I'm sure I can create an example assembly file which shows the problem.
roondar is offline  
Old 10 December 2017, 01:18   #2
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by roondar View Post
Code:
.node_loop
        cmp.b #NT_MEMORY,LN_TYPE(A1)
But for some reason, that didn't assemble/link correctly, an erroneous byte (IIRC it had value $08) was added, causing the remaining program to shift by one byte and things went badly.
Are you sure it was added/inserted, and didn't just overwrite something? Where exactly did it appear? Do you have some original disassembly or hexdump?

Quote:
Originally Posted by roondar
Code:
.node_loop
        moveq    #NT_MEMORY,d6
        cmp.b    LN_TYPE(a1),d6
This also didn't work, again, there was an extra byte (value $08 IIRC) introduced after the moveq command.
The MOVEQ and CMP instructions were still there? Just CMP moved by one byte?

Quote:
It only seems to happen when I use Vlink -brawbin1 (or 2), it works fine when the result is a normal Amiga application.
No output module inserts something, except for alignment reasons. And then it will usually insert 0-bytes and not a $08.


Quote:
I also tried using -Fvobj instead of -Fhunk and that changed nothing.
Did you disassemble the Hunk-format object file, to check whether it already includes the additional byte? Also using vobjdump on the VOBJ file could be interresting (to see relocs, etc.).

Your first step should be to determine whether the problem was introduced by vasm or by vlink.


Quote:
Or am I doing something wrong?
Hard to say at this point. I hope so...
At least I have never seen this bug before.

Quote:
P.S. If more code is needed, I'm sure I can create an example assembly file which shows the problem.
It probably won't suprise you when I say that I cannot reproduce your problem with the given information. A minimal example source with exact command line arguments would be nice (you can also send it by email).

The only hint might be that LN_TYPE is 8. So there definitely should be an 8 somewhere in the output.
phx is offline  
Old 10 December 2017, 09:34   #3
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,411
This whole thing didn't sit right with me, I've used vasm/vlink since 2014 now and never had any problems until I started messing with disks. So, after your post and a night of sleep, I decided to do some research using The Online Disassembler (https://onlinedisassembler.com/)...

Quote:
Originally Posted by phx View Post
Hard to say at this point. I hope so...
At least I have never seen this bug before.
Well, I have good news and err, strange news.

The good news is that it seems that Vasm/Vlink do the job correctly after all . However, my compiled-under-windows version of diskimage.c (from the Solid Gold Source) does very odd stuff.

Here is the output of vlink using -brawbin1:
Click image for larger version

Name:	test_vlinkbin.PNG
Views:	152
Size:	66.0 KB
ID:	55795

And here is the output as found in the .adf file as generated by diskimage.c:
Click image for larger version

Name:	test_dimg_out.PNG
Views:	133
Size:	65.3 KB
ID:	55796

And there's the problem!

So it seems the issue isn't with Vasm/Vlink at all, but either with diskimage.c, or (more likely) my MS Visual Studio compile of that sourcce.

No idea what that problem is yet, but now I know where to start looking!


----
Edit: Well, that was quick. The problem is that stdout on windows is not a binary stream. Any 0a it found got turned into <CR><LF>, and more of such nonsense. I've adapted the diskimage.c source to be compatible with windows by writing the output to a file directly instead of it using stdout. For reference, here are my changes:

Code:
int main(int argc, char *argv[])
{
	FILE *f,*out;
	int rc = 1;
	size_t len;

	if (argc == 3) {
		if (f = fopen(argv[1], "rb")) {
			len = fread(image, 1, DISKSIZE, f);
			if (len > 0) {
				if (len < DISKSIZE)
					memset(image + len, 0, DISKSIZE - len);
				boot_chksum(image);
				if (out=fopen(argv[2],"wb"))
				{
					fwrite(image, 1, DISKSIZE, out);
					fclose(out);
					rc = 0;
				}
				else
				{
					fprintf(stderr, "Image write error!\n");
				}
			}
			else
				fprintf(stderr, "Image read error!\n");
		}
		else
			fprintf(stderr, "Cannot open '%s'!\n", argv[0]);
	}
	else
		fprintf(stderr, "Usage: %s <image data> <output file>\n", argv[0]);

	return rc;
}
I haven't included the checksum code as nothing changed there.

Last edited by roondar; 10 December 2017 at 10:16. Reason: Found what went wrong and fixed it.
roondar is offline  
Old 10 December 2017, 10:10   #4
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 7,001
Quote:
Originally Posted by roondar View Post
However, my compiled-under-windows version of diskimage.c (from the Solid Gold Source) does very odd stuff.
I suppose it uses fopen(filename,"w"). This means that the contents is treated as text and on a DOS/Windows machine each newline character ($0a) gets a carriage return ($0d) added to it.

Change this to fopen(filename,"wb"), then the contents will be treated as binary and written as is.

The same is true for "r", then every $0d before a $0a will be filtered out. Change this to "rb", too.
thomas is offline  
Old 10 December 2017, 10:14   #5
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,411
Quote:
Originally Posted by thomas View Post
I suppose it uses fopen(filename,"w"). This means that the contents is treated as text and on a DOS/Windows machine each newline character ($0a) gets a carriage return ($0d) added to it.

Change this to fopen(filename,"wb"), then the contents will be treated as binary and written as is.

The same is true for "r", then every $0d before a $0a will be filtered out. Change this to "rb", too.
Ah, thanks..

I had just figured this out and updated my post to reflect that. Added an updated 'windows compatible' version of the main{} from diskimage.c as well
roondar is offline  
Old 10 December 2017, 13:31   #6
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Ok, then it's my fault in the end. Solid Gold's diskimage.c was not as portable as it should be.

Too bad. Now I have to fix most of my game tools, as I really liked to output binaries to stdout instead of opening a new file. Bad mistake.
phx is offline  
Old 10 December 2017, 17:07   #7
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,411
You might get away with less work, I was curious and googled it and apparently you can set stdout to be binary on windows as well. I haven't tried this myself, but see below.

https://stackoverflow.com/questions/...in-binary-mode

From there:
Quote:
You can use setmode(fileno(stdout), O_BINARY)
Wrap it in an ifdef if you want to keep it compatible with Linux.
roondar is offline  
Old 10 December 2017, 20:19   #8
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
setmode() is not portable. It is not in ANSI-C or C99.
I doesn't even appear to be POSIX.
phx is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Odd DNS issue using RoadShow chocsplease support.Apps 4 12 August 2017 13:22
Trying out vlink and vasm cla Coders. General 2 30 September 2016 20:30
vasm movem optimization issue? dalton Coders. Asm / Hardware 2 23 September 2016 14:02
VLINK multiple VASM objects roondar Coders. Asm / Hardware 2 24 April 2016 01:03
Help linking VASM object code clenched Coders. Asm / Hardware 2 24 May 2013 22:32

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 21:00.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08360 seconds with 14 queries