Bug 173 - Compiling bpeg.s produces non-functional code, works with mac
Summary: Compiling bpeg.s produces non-functional code, works with mac
Status: RESOLVED FIXED
Alias: None
Product: RMAC
Classification: Unclassified
Component: Core (show other bugs)
Version: unspecified
Hardware: PC Linux
: Normal enhancement
Assignee: Shamus Hammons
URL:
Depends on:
Blocks:
 
Reported: 2020-08-30 13:09 CDT by James Jones
Modified: 2021-06-08 19:18 CDT (History)
2 users (show)

See Also:


Attachments
Source file that fails to compile (46.93 KB, text/plain)
2020-08-30 13:09 CDT, James Jones
Details
bpeg.s compiled by mac to an a.out object file (7.02 KB, application/octet-stream)
2020-08-30 13:13 CDT, James Jones
Details
bpeg.s compiled by rmac to an a.out object file (7.17 KB, application/octet-stream)
2020-08-30 13:13 CDT, James Jones
Details
Hex dump (xxd) of bpeg.mac.o for easier diffing (29.87 KB, text/plain)
2020-08-30 13:14 CDT, James Jones
Details
Hex dump (xxd) of bpeg.rmac.o for easier diffing (30.47 KB, text/plain)
2020-08-30 13:15 CDT, James Jones
Details
The patches! (16.77 KB, patch)
2020-09-01 01:51 CDT, ggn
Details
Additions to the regression suite (58.62 KB, application/x-zip-compressed)
2020-09-01 01:55 CDT, ggn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description James Jones 2020-08-30 13:09:55 CDT
Created attachment 139 [details]
Source file that fails to compile

I'm trying to compile the bpeg demo program from the Atari SDK files, and it's not working with rmac.  The difference seems to be that some expressions get marked relocatable in rmac, whereas they don't in mac.  This is the first one:

 lea ZZQTLMatrix-BPEGStartUp(a5),a3

ZZQTLMatrix and BPEGStartUp are both labels in a GPU code segment with a .org directive active.  Regardless, I'm assuming mac detects that the difference between two relocatable symbols (Even though these are ABS symbols in practice due to the .org directive, both mac and rmac seem to ignore that for whatever reason), is an absolute value rather than a relocatable value, while rmac doesn't realize it can perform that cancelation and incorrectly records that the result of the expression should be relocated at link time (I haven't verified rln/aln are actually relocating this as mentioned, just that it's in the relocation table in the .o rmac produces, and not there in the .o mac produces).

I've spent a few hours digging on this, and I'm still not sure how to fix it, so I figured I'd just post the bug up for the experts to consider.  Hopefully it's not just another unsolvable instance of bug 148!

Here's the backtrace from where the incorrect relocation is marked:

#0  MarkRelocatable (section=1, loc=130, to=1, flags=0, symbol=0x0) at mark.c:79
#1  0x00005555555987e9 in ResolveFixups (sno=1) at sect.c:714
#2  0x0000555555599116 in ResolveAllFixups () at sect.c:988
#3  0x00005555555972ba in Process (argc=3, argv=0x7fffffffe1a0) at rmac.c:720
#4  0x00005555555974ec in main (argc=4, argv=0x7fffffffe198) at rmac.c:794

I'm using rmac at commit 357c51c8d2512a72b371ea7b259f0ef64de832e0 plus the 3 patches I have for outstanding issues here (56k symbol + keyword collisions, and RMACPATH handling), but it reproduces without my local patches as well.
Comment 1 James Jones 2020-08-30 13:13:06 CDT
Created attachment 140 [details]
bpeg.s compiled by mac to an a.out object file
Comment 2 James Jones 2020-08-30 13:13:41 CDT
Created attachment 141 [details]
bpeg.s compiled by rmac to an a.out object file
Comment 3 James Jones 2020-08-30 13:14:38 CDT
Created attachment 142 [details]
Hex dump (xxd) of bpeg.mac.o for easier diffing
Comment 4 James Jones 2020-08-30 13:15:05 CDT
Created attachment 143 [details]
Hex dump (xxd) of bpeg.rmac.o for easier diffing
Comment 5 James Jones 2020-08-30 14:13:55 CDT
Linkovitch forced me to think about this a little harder, and I ended up finding that a work-around is possible.  Replacing this code in bpeg.s:
 

ZZQTLMatrix    .equ     *                      ; Luminance Quantization Matrix ($100 Bytes)
ZZQTCMatrix     .equ    *+$100                  ; Chrominance Quantization Matrix ($100 Bytes)
MCUBuffer       .equ    *+$200                  ; I/O MCU Buffer ($600 Bytes)
MCUTmpBuffer    .equ    *+$800                  ; Inv. DCT Temporary Buffer ($100 Bytes)

With this: 

ZZQTLMatrix:                       ; Luminance Quantization Matrix ($100 Bytes)
ZZQTCMatrix     .equ    ZZQTLMatrix+$100                  ; Chrominance Quantization Matrix ($100 Bytes)
MCUBuffer       .equ    ZZQTLMatrix+$200                  ; I/O MCU Buffer ($600 Bytes)
MCUTmpBuffer    .equ    ZZQTLMatrix+$800                  ; Inv. DCT Temporary Buffer ($100 Bytes)

Causes both assemblers to generate identical object files.
Comment 6 ggn 2020-08-31 10:57:43 CDT
First of all, thanks a bunch for taking so much time to look into this and reporting it.

Now, I've been staring at this for most of the day in between other things and my brain is kind of foggy now, so I'll just state what's happening and the implications that follow the (so far) fix.

First of all, rmac did indeed assemble this file correctly. It was shipped with qUaKe and from that archive I saw that v1.1.1 used to assemble the file properly.

So after assembling the file using the old and new rmac I dumped both files' symbols using nm:

../../rmac.exe -lbpeg.lst -o bpeg.o a.S && m68k-atari-mint-nm.exe -p bpeg.o > bpeg_nm.txt
../../rmac.exe -lbpeg_ref.lst -o bpeg_ref.o a.S && m68k-atari-mint-nm.exe -p bpeg_ref.o > bpeg_nm_ref.txt

(a.s is just a file that includes jaguar.inc and bpeg.s)

This produced two files that were almost the same except for the following (left is current rmac, right is old rmac):

00f03608 t ZZQTLMatrix  | 00f03608 a ZZQTLMatrix 
00f03708 t ZZQTCMatrix  | 00f03708 a ZZQTCMatrix
00f03808 t MCUBuffer    | 00f03808 a MCUBuffer
00f03e08 t MCUTmpBuffer | 00f03e08 a MCUTmpBuffer 

According to https://sourceware.org/binutils/docs/binutils/nm.html "t" is a symbol belonging in text and "a" is an absolute symbol. So all that's written above is correct - rmac is now exporting symbols that are defined absolute as relative (inside text segment).

So yes, the problematic lines in bpeg.s are the following:

ZZQTLMatrix	.equ	*			; Luminance Quantization Matrix ($100 Bytes)

ZZQTCMatrix	.equ	*+$100			; Chrominance Quantization Matrix ($100 Bytes)

MCUBuffer	.equ	*+$200			; I/O MCU Buffer ($600 Bytes)

MCUTmpBuffer	.equ	*+$800			; Inv. DCT Temporary Buffer ($100 Bytes)


My fix so far was to modify AddBSDSymEntry in object.c from:

if (w1 & EQUATED)
...

switch (w1 & TDB)
...

to:

if (w1 & EQUATED)
...
else
switch (w1 & TDB)
...

so the exporter will stop when encountering an absolute symbol. This fixes the issue.

HOWEVER....

Remember bug #140? Yup, with this change the code in Removers' lib is breaking.

00000450 T _init_module
000006b0 T _play_module
00000660 T _clear_module
00000668 T _pause_module

With the "fix" the "T"s become "A"s, so that's no good!

I think the proper way to fix the issue would be to make AddBSDSymEntry realise that the symbols are defined and are assigned an absolute value, even though they are inside the TEXT segment. The thing is that this code is inside the .gpu code block, so that makes all symbols automatically fully defined as we know their addresses during assembly time and they're not going to change during link time.

So it's probably really easy to do but my brain just won't cooperate right now! So I'll go do something else for today and will think about this soon (tomorrow?)...
Comment 7 James Jones 2020-08-31 18:09:27 CDT
Thanks for taking a look.  That all make sense.  Somewhere in my rambling through the code, I found something like (Pseudo-code from memory, forgive me):

if (orgActive) {
   doPcIsAbsolute();
} else {
   doPcIsRelative();
}

I thought it was somewhere dealing with '*', but perhaps not.  I'll try to take another look as well after work & family time tonight.

I still haven't figured out how the expression evaluator converts the difference between two relative/non-absolute labels into an absolute value either though.  It does seem to work; I just don't know why, nor why it doesn't work for equates, as is the case here.  It seems like that should be fixed as well.
Comment 8 ggn 2020-09-01 01:51:07 CDT
Created attachment 144 [details]
The patches!

There we go, I knew I should have stopped last night as I was getting utterly useless!

So, the fix is simple: when calculating an expression that contains "*" if ORG mode is active then simply don't add any section to the symbol's attributes. Then during export time we read that and we know that the symbol is a "free agent" so we mark it as absolute.

Patch attached, and I'll add two more regression tests for the suite. These are good tripwires in case we decide to tinker with coff in the future!
Comment 9 ggn 2020-09-01 01:55:19 CDT
Created attachment 145 [details]
Additions to the regression suite
Comment 10 James Jones 2020-09-01 10:19:24 CDT
Thanks. Verified it works and produces an identical object file to mac. Looks like a fair amount of cruft removal made it in there as well!
Comment 11 Shamus Hammons 2021-06-08 19:18:21 CDT
Thanks for the patch!  :-)