From a0516e2c2a3377dadd28cdd3172b36d921550838 Mon Sep 17 00:00:00 2001 From: James Jones Date: Sat, 16 Apr 2022 21:11:21 -0700 Subject: [PATCH] Handle absolute BSS segment location of 'xt' 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 | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/rln.c b/rln.c index e451f45..78ed410 100644 --- 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 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 add contents of to command line\n"); printf(" -d wait for key after link\n"); -- 2.37.2