From 6ce2cc0b58dc2cb4f38c7da4d03fc56393a47831 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 10 Jul 2020 13:56:07 -0700 Subject: [PATCH] Fix label-trampling bug in reloc data handler If code accesses the high/low parts of a 32-bit address value with no label, it auto-generates labels for addr+2 and addr. The reloc handler was replacing the unformatted bytes with a single multi-byte format, hiding the label at addr+2. The easy fix is to have the reloc data handler skip the entry. This is less useful than other approaches, but much simpler. Added a test to 20212-reloc-data. --- SourceGen/DataAnalysis.cs | 8 +- SourceGen/SGTestData/20212-reloc-data | Bin 255 -> 282 bytes SourceGen/SGTestData/20212-reloc-data.dis65 | 72 ++++++++++++------ .../Expected/20212-reloc-data_64tass.S | 22 +++++- .../Expected/20212-reloc-data_Merlin32.S | 22 +++++- .../Expected/20212-reloc-data_acme.S | 11 +-- .../Expected/20212-reloc-data_cc65.S | 22 +++++- .../Expected/20212-reloc-data_cc65.cfg | 2 +- .../SGTestData/Source/20212-reloc-data-main.S | 24 ++++++ 9 files changed, 148 insertions(+), 35 deletions(-) diff --git a/SourceGen/DataAnalysis.cs b/SourceGen/DataAnalysis.cs index e2816ac..68bea15 100644 --- a/SourceGen/DataAnalysis.cs +++ b/SourceGen/DataAnalysis.cs @@ -254,11 +254,15 @@ namespace SourceGen { mProject.RelocList.TryGetValue(offset, out DisasmProject.RelocData reloc)) { // Byte is unformatted, but there's relocation data here. If the full - // range of bytes is unformatted, create a symbolic reference. + // range of bytes is unformatted and unlabeled, create a symbolic reference. + // TODO: we can do better here when a multi-byte reloc has an auto-generated + // label mid-way through: create multiple, smaller formats for the same sym. + // Or don't generate auto labels until all reloc-based formats are placed. bool allClear = true; for (int i = 1; i < reloc.Width; i++) { if (!mAnattribs[offset + i].IsUntyped || - mAnattribs[offset + i].DataDescriptor != null) { + mAnattribs[offset + i].DataDescriptor != null || + mAnattribs[offset + i].Symbol != null) { allClear = false; break; } diff --git a/SourceGen/SGTestData/20212-reloc-data b/SourceGen/SGTestData/20212-reloc-data index 05efc89d5f8623f2ab98164383652a4f281ee6d3..d3464a7920c94277b3e22b384dd8a15fbf75bc19 100644 GIT binary patch delta 36 scmey*IE!gQu9Wxcl?)7AT&wmrF?j54VDR|Bnc&L6%#h2#JTYf70O> 16 .long _L4FFE0 .byte $00 -_L3006D rts +_L3006D phk + plb + lda #$0000 + asl a + asl a + tax + lda @w_L30082 & $ffff,x + pha + lda @w_L30080 & $ffff,x + pha + beq _L30088 + rts + +_L30080 .byte $45 + .byte $00 +_L30082 .byte $03 + .byte $00 + .long _L3006D + .byte $00 + +_L30088 rts ;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 ' .logical $04ffe0 diff --git a/SourceGen/SGTestData/Expected/20212-reloc-data_Merlin32.S b/SourceGen/SGTestData/Expected/20212-reloc-data_Merlin32.S index 12c8d8f..772aded 100644 --- a/SourceGen/SGTestData/Expected/20212-reloc-data_Merlin32.S +++ b/SourceGen/SGTestData/Expected/20212-reloc-data_Merlin32.S @@ -48,7 +48,27 @@ L30000 clc adr :L4FFE0 dfb $00 -:L3006D rts +:L3006D phk + plb + lda #$0000 + asl A + asl A + tax + lda: :L30082,x + pha + lda: :L30080,x + pha + beq :L30088 + rts + +:L30080 dfb $45 + dfb $00 +:L30082 dfb $03 + dfb $00 + adr :L3006D + dfb $00 + +:L30088 rts ;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 ' org $04ffe0 diff --git a/SourceGen/SGTestData/Expected/20212-reloc-data_acme.S b/SourceGen/SGTestData/Expected/20212-reloc-data_acme.S index db1e891..accc0fd 100644 --- a/SourceGen/SGTestData/Expected/20212-reloc-data_acme.S +++ b/SourceGen/SGTestData/Expected/20212-reloc-data_acme.S @@ -4,9 +4,10 @@ !hex 18fbe230af000003ea2256340222000008af563402ad5634a956a934a902af19 !hex 0008ad1900a919a900a908eac230a91900a90008a90800eaa90f00a22600a05e !hex 34540208eaf40000f400f0f41900f40800f44500f40003f40300f45700f44510 - !hex ea4c6d00e0ffe0ff04e0ff040060e0ff0400000102030405060708090a0b0c0d - !hex 0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d - !hex 2e2faf563402206e346b00000000000000000000000000000000ea60af000008 - !hex ad1900eaaf000001af000002af000003af0000086b1900080056340200800010 - !hex 080054686973206973206120746573742e0068656c6c6f2c20776f726c6421 + !hex ea4c6d00e0ffe0ff04e0ff04004baba900000a0aaabd820048bd800048f00960 + !hex 450003006d00030060e0ff0400000102030405060708090a0b0c0d0e0f101112 + !hex 131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2faf5634 + !hex 02206e346b00000000000000000000000000000000ea60af000008ad1900eaaf + !hex 000001af000002af000003af0000086b19000800563402008000100800546869 + !hex 73206973206120746573742e0068656c6c6f2c20776f726c6421 } ;!pseudopc diff --git a/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.S b/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.S index 60537eb..c0398be 100644 --- a/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.S +++ b/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.S @@ -53,7 +53,27 @@ L30000: clc .faraddr @L4FFE0 .byte $00 -@L3006D: rts +@L3006D: phk + plb + lda #$0000 + asl A + asl A + tax + lda a:@L30082 & $ffff,x + pha + lda a:@L30080 & $ffff,x + pha + beq @L30088 + rts + +@L30080: .byte $45 + .byte $00 +@L30082: .byte $03 + .byte $00 + .faraddr @L3006D + .byte $00 + +@L30088: rts ;Segment 03: Kind=Data; Attrs=BankRel, Dynamic; Name='PosFFE0 ' ; .segment "SEG001" diff --git a/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.cfg b/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.cfg index 1772cf0..e65aa82 100644 --- a/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.cfg +++ b/SourceGen/SGTestData/Expected/20212-reloc-data_cc65.cfg @@ -1,7 +1,7 @@ # 6502bench SourceGen generated linker script for 20212-reloc-data MEMORY { MAIN: file=%O, start=%S, size=65536; -# MEM000: file=%O, start=$30000, size=110; +# MEM000: file=%O, start=$30000, size=137; # MEM001: file=%O, start=$4ffe0, size=32; # MEM002: file=%O, start=$50000, size=20; # MEM003: file=%O, start=$23456, size=26; diff --git a/SourceGen/SGTestData/Source/20212-reloc-data-main.S b/SourceGen/SGTestData/Source/20212-reloc-data-main.S index fd4f8d7..b9a41e0 100644 --- a/SourceGen/SGTestData/Source/20212-reloc-data-main.S +++ b/SourceGen/SGTestData/Source/20212-reloc-data-main.S @@ -77,4 +77,28 @@ check_pea adrl ADDR_FFE0 :skipdata + +; Check a situation where we block a relocation from being fully formed. +; The access to addr_dat+2 and addr_dat cause labels to be auto-generated. +; Because we access the high part first, there's no opportunity to find +; a pre-existing label nearby. If the reloc code generates a 3-byte or +; 4-byte data item at addr_dat, the label at addr_dat+2 will be hidden. + phk + plb + lda #$0000 + asl A + asl A + tax + lda addr_dat+2,X + pha + lda addr_dat,X + pha + beq :skip_ad + rts + +addr_dat + adrl check_pea + adrl :skipdata + +:skip_ad rts