diff --git a/README b/README index 37f2f9c..4f7a879 100644 --- a/README +++ b/README @@ -32,7 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. modified 2009 by Joerg Hoppe, -modified 2015-2017 by Olaf 'Rhialto' Seibert. +modified 2015-2017,2020 by Olaf 'Rhialto' Seibert. Files: macro11.c Command line parsing and driving the passes. diff --git a/assemble_aux.c b/assemble_aux.c index 5d784d1..22b0684 100644 --- a/assemble_aux.c +++ b/assemble_aux.c @@ -467,12 +467,18 @@ void mode_extension( } if (value->type == EX_LIT) { - if (mode->rel) /* PC-relative? */ - store_displaced_word(str, tr, 2, value->data.lit); - else + if (mode->rel) { /* PC-relative? */ + if (current_pc->section->flags & PSECT_REL) { + store_displaced_word(str, tr, 2, value->data.lit); + } else { + /* I can compute this myself. */ + store_word(str, tr, 2, value->data.lit - DOT - 2); + } + } else { store_word(str, tr, 2, value->data.lit); /* Just a known value. */ + } } else if (express_sym_offset(value, &sym, &offset)) { if ((sym->flags & (SYMBOLFLAG_GLOBAL | SYMBOLFLAG_DEFINITION)) == SYMBOLFLAG_GLOBAL) { /* Reference to a global symbol. */ diff --git a/macro11.c b/macro11.c index 409b1ae..a030a1d 100644 --- a/macro11.c +++ b/macro11.c @@ -80,7 +80,7 @@ static void print_version( fprintf(strm, " Version %s\n", VERSIONSTR); fprintf(strm, " Copyright 2001 Richard Krehbiel,\n"); fprintf(strm, " modified 2009 by Joerg Hoppe,\n"); - fprintf(strm, " modified 2015-2017 by Olaf 'Rhialto' Seibert.\n"); + fprintf(strm, " modified 2015-2017,2020 by Olaf 'Rhialto' Seibert.\n"); } static void append_env( diff --git a/tests/RunTests b/tests/RunTests index 2077424..8f8dddc 100755 --- a/tests/RunTests +++ b/tests/RunTests @@ -23,6 +23,7 @@ TESTS="test-asciz \ test-prec \ test-psect \ test-rad50 \ + test-reloc \ test-rept \ test-ua-pl \ test-undef \ diff --git a/tests/test-reloc.lst.ok b/tests/test-reloc.lst.ok new file mode 100644 index 0000000..f4ebeaa --- /dev/null +++ b/tests/test-reloc.lst.ok @@ -0,0 +1,89 @@ + 1 .TITLE Test references that need (no) relocation + 2 + 3 000000 .PSECT FOO,I,RW + 4 + 5 000000 000042 .WORD 42 + 6 000002 000000 Y: .WORD 0 + 7 + 8 ; absolute expression since the offset to the pc is a + 9 ; subtraction of the relative address of Y from the current + 10 ; position, both in the same psect. Such an operation renders + 11 ; an absolute value. + 12 000004 005067 177772 CLR Y + 13 + 14 ; relocatable, since the absolute address of Y is unknown because + 15 ; it's in a psect that can be moved around at link time. + 16 000010 005037 000002' CLR @#Y + 17 + 18 ; relocatable because even though X is at a known address, the + 19 ; address of the instruction is unknown and subject to the location + 20 ; of the psect, which is only decided at link time. + 21 000014 005067 001234' CLR X + 22 + 23 ; absolute since it is an expression only dependent on an + 24 ; absolute value. + 25 000020 005037 001234 CLR @#X + 26 + 27 ; Test AMA (uses absolute addresses rather than pc-relative) + 28 + 29 .enabl AMA + 30 + 31 ; Could be relative, as above, but AMA forces it to @#Y and + 32 ; then it needs relocation again, weirdly enough. + 33 000024 005037 000002' clr Y + 34 ; Same as @#X. + 35 000030 005037 001234 clr X + 36 + 37 .dsabl AMA + 38 + 39 000000 .ASECT + 40 001000 .=1000 + 41 + 42 001234 X=1234 + 43 ; relocatable because the address of Y is in another psect, and + 44 ; the subtraction of a relative address from an absolute renders + 45 ; a relative value. + 46 001000 005067 000002' CLR Y + 47 + 48 ; relocatable because the absolute address of Y is unknown. + 49 ; MACRO-11 only have a relative value of Y. + 50 001004 005037 000002' CLR @#Y + 51 + 52 ; absolute since the offset to the pc is an expression subtracting + 53 ; two absolute values which obviously have an absolute result. + 54 001010 005067 000220 CLR X + 55 + 56 ; absolute since it is an expression only dependent on an + 57 ; absolute value. + 58 001014 005037 001234 CLR @#X + 59 + 60 ; Note that all references to Y contains 000002. This is because + 61 ; that is the offset of Y within the psect. This is added to the + 62 ; base of the psect (the part that comes from this object file), + 63 ; which is all the linker will know about. + 64 + 65 ; Test AMA + 66 + 67 .enabl AMA + 68 + 69 ; Same as @#Y. + 70 001020 005037 000002' clr Y + 71 ; Same as @#X. + 72 001024 005037 001234 clr X + 73 + 74 .dsabl AMA + 75 + 76 .END + 76 + + +Symbol table + +. =****** X =001234 Y 000002R 002 + + +Program sections: + +. ABS. 001030 000 (RW,I,GBL,ABS,OVR,NOSAV) + 000000 001 (RW,I,LCL,REL,CON,NOSAV) +FOO 000034 002 (RW,I,LCL,REL,CON,NOSAV) diff --git a/tests/test-reloc.mac b/tests/test-reloc.mac new file mode 100644 index 0000000..2c34637 --- /dev/null +++ b/tests/test-reloc.mac @@ -0,0 +1,76 @@ + .TITLE Test references that need (no) relocation + + .PSECT FOO,I,RW + + .WORD 42 +Y: .WORD 0 + + ; absolute expression since the offset to the pc is a + ; subtraction of the relative address of Y from the current + ; position, both in the same psect. Such an operation renders + ; an absolute value. + CLR Y + + ; relocatable, since the absolute address of Y is unknown because + ; it's in a psect that can be moved around at link time. + CLR @#Y + + ; relocatable because even though X is at a known address, the + ; address of the instruction is unknown and subject to the location + ; of the psect, which is only decided at link time. + CLR X + + ; absolute since it is an expression only dependent on an + ; absolute value. + CLR @#X + + ; Test AMA (uses absolute addresses rather than pc-relative) + + .enabl AMA + + ; Could be relative, as above, but AMA forces it to @#Y and + ; then it needs relocation again, weirdly enough. + clr Y + ; Same as @#X. + clr X + + .dsabl AMA + + .ASECT + .=1000 + +X=1234 + ; relocatable because the address of Y is in another psect, and + ; the subtraction of a relative address from an absolute renders + ; a relative value. + CLR Y + + ; relocatable because the absolute address of Y is unknown. + ; MACRO-11 only have a relative value of Y. + CLR @#Y + + ; absolute since the offset to the pc is an expression subtracting + ; two absolute values which obviously have an absolute result. + CLR X + + ; absolute since it is an expression only dependent on an + ; absolute value. + CLR @#X + + ; Note that all references to Y contains 000002. This is because + ; that is the offset of Y within the psect. This is added to the + ; base of the psect (the part that comes from this object file), + ; which is all the linker will know about. + + ; Test AMA + + .enabl AMA + + ; Same as @#Y. + clr Y + ; Same as @#X. + clr X + + .dsabl AMA + + .END diff --git a/tests/test-reloc.objd.ok b/tests/test-reloc.objd.ok new file mode 100644 index 0000000..f1f46c2 --- /dev/null +++ b/tests/test-reloc.objd.ok @@ -0,0 +1,28 @@ +GSD: + MODNAME TEST =0 flags=0 + PSECT =0 CON RW REL LCL I flags=40 + PSECT . ABS.=1030 OVR RW ABS GBL I flags=104 + PSECT FOO =34 CON RW REL LCL I flags=40 + XFER . ABS.=1 flags=10 +ENDGSD +RLD + Location counter definition FOO+0 +TEXT ADDR=0 LEN=34 + 000000: 000042 000000 005067 177772 "...7... + 000010: 005037 000002 005067 001234 ....7... + 000020: 005037 001234 005037 000002 ........ + 000030: 005037 001234 .... +RLD + Internal 12=2 + Internal displaced 16=1234 + Internal 26=2 + Location counter definition . ABS.+1000 +TEXT ADDR=1000 LEN=30 + 001000: 005067 000002 005037 000002 7....... + 001010: 005067 000220 005037 001234 7....... + 001020: 005037 000002 005037 001234 ........ +RLD + PSECT plus offset displaced 1002=FOO+2 + PSECT plus offset 1006=FOO+2 + PSECT plus offset 1022=FOO+2 +ENDMOD