]> Shamusworld >> Repos - rln/commitdiff
Handle absolute BSS segment location of 'xt'
authorJames Jones <atari@theinnocuous.com>
Sun, 17 Apr 2022 04:11:21 +0000 (21:11 -0700)
committerShamus Hammons <jlhamm@acm.org>
Tue, 16 Aug 2022 02:22:44 +0000 (21:22 -0500)
When linking an absolute executable, the data
segment and BSS segment can be assigned an
absolute address, or the special value 'x' to
indicate they are contiguous with the prior
segment (text for data, data for BSS). However,
RLN (like MAC) also accepts an optional segment
specifier after the special value 'x' that allows
explicitly specifying which segment the current
one is contiguous with. For data, the only valid
value is 'xt', meaning contiguous with text.
However, when the data segment is specified to
be at an explicit address rather than contiguous
with the text segment, it is valid to specify that
the BSS segment is contiguous with data ('xd') or
with text ('xt'). RLN was accepting these
additional 't' and 'd' values, but ignoring them.

This change causes RLN to correctly place the BSS
segment after the text segment when its location
is specified as 'xt' as long as the data segment
isn't also contiguous with the text segment.

rln.c

diff --git a/rln.c b/rln.c
index e451f4518e0916c2027d9611d994453eb1fbe10e..78ed41053bbc2a6f8b43d5a68c50f186987f2818 100644 (file)
--- a/rln.c
+++ b/rln.c
@@ -1572,11 +1572,19 @@ struct OHEADER * MakeOutputObject()
                dbase = dval;
 
                if (!bval)
-                       // BSS follows DATA
-                       bbase = dval + datasize;
+               {
+                       if (btype == -2)
+                               // BSS follows TEXT
+                               bbase = tval +  textsize;
+                       else
+                               // BSS follows DATA
+                               bbase = dval + datasize;
+               }
                else
+               {
                        // BSS is independent of DATA
                        bbase = bval;
+               }
        }
 
        // Inject segment end labels, for C compilers that expect this shite
@@ -2809,9 +2817,33 @@ int doargs(int argc, char * argv[])
                                }
                                else if ((*argv[i] == 'x' || *argv[i] == 'X'))
                                {
-                                       btype = -3;                     // BSS follows DATA
+                                       switch (argv[i][1])
+                                       {
+                                               case 'd': case 'D': case '\0':
+                                                       btype = -3;     // BSS follows DATA
+                                                       break;
+
+                                               case 't': case 'T':
+                                                       btype = -2;     // BSS follows TEXT
+                                                       if (btype == dtype)
+                                                       {
+                                                               printf("Error in bss-segment address: data-segment also follows text\n");
+                                                               return 1;
+                                                       }
+                                                       break;
+
+                                               default:
+                                                       btype = -4;     // Error
+                                                       break;
+                                       }
                                }
                                else if (GetHexValue(argv[i], &bval))
+                               {
+                                       btype = -4;
+                                       return 1;
+                               }
+
+                               if (btype == -4)
                                {
                                        printf("Error in bss-segment address: %s is not 'r', 'x[td]', or an address.", argv[i]);
                                        return 1;
@@ -3070,7 +3102,10 @@ void ShowHelp(void)
        printf("   -a <text> <data> <bss>  output absolute file (default: ABS)\n");
        printf("                           hex value: segment address\n");
        printf("                           r: relocatable segment\n");
-       printf("                           x: contiguous segment\n");
+       printf("                           x[dt]: contiguous segment\n");
+       printf("                           for contiguous bss:\n");
+       printf("                             d(default): follows data segment\n");
+       printf("                             t:          follows text segment\n");
        printf("   -b                      don't remove multiply defined local labels\n");
        printf("   -c <fname>              add contents of <fname> to command line\n");
        printf("   -d                      wait for key after link\n");