]> Shamusworld >> Repos - rln/blobdiff - rln.c
Handle absolute BSS segment location of 'xt'
[rln] / rln.c
diff --git a/rln.c b/rln.c
index a117a86b27fc2e75fa0e4beb1ddf22230e4f57a3..78ed41053bbc2a6f8b43d5a68c50f186987f2818 100644 (file)
--- a/rln.c
+++ b/rln.c
@@ -1,6 +1,6 @@
 //
-// RLN - Reboot's Linker for the Atari Jaguar console system
-// Copyright (C) 199x, Allan K. Pratt, 2014-2018 Reboot & Friends
+// RLN - Renamed Linker for the Atari Jaguar console system
+// Copyright (C) 199x, Allan K. Pratt, 2014-2021 Reboot & Friends
 //
 
 #include "rln.h"
@@ -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
@@ -2448,7 +2456,8 @@ int LoadArchive(char * fname, int fd)
                }
 
                // Check to see if a long filename was requested
-               if (objName[0] == 0x20)
+               // N.B.: " " is for GNU archives, and "/" is for BSD archives
+               if ((objName[0] == 0x20) || (objName[0] == '/'))
                {
                        uint32_t fnSize = atoi(objName + 1);
 
@@ -2808,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;
@@ -2850,6 +2883,10 @@ int doargs(int argc, char * argv[])
                        case 'e':
                        case 'E':                                       // Output COFF (absolute only)
                                cflag = 1;
+
+                               if (noheaderflag)
+                                       printf("Warning: -e overridden by -n, output will be headerless\n");
+
                                break;
                        case 'g':
                        case 'G':                                       // Output source level debugging
@@ -2908,6 +2945,9 @@ int doargs(int argc, char * argv[])
                                if (noheaderflag)
                                        warn('n', 1);
 
+                               if (cflag)
+                                       printf("Warning: -e overridden by -n, output will be headerless\n");
+
                                noheaderflag = 1;
                                break;
                        case 'o':
@@ -2976,6 +3016,22 @@ int doargs(int argc, char * argv[])
 
                                wflag = 1;
                                break;
+                       case 'y':
+                       case 'Y':
+                               if (i >= argc)
+                               {
+                                       printf("No directory filename following -y switch\n");
+                                       return 1;
+                               }
+
+                               if (strlen(argv[i]) > FARGSIZE * 3)
+                               {
+                                       printf("Directory file name too long (sorry!)\n");
+                                       return 1;
+                               }
+
+                               strcpy(libdir, argv[i++]);
+                               break;
                        case 'z':
                        case 'Z':                                       // Suppress banner flag
                                if (zflag)
@@ -3026,8 +3082,8 @@ void ShowVersion(void)
                "| '__| | '_  \\\n"
                "| |  | | | | |\n"
                "|_|  |_|_| |_|\n"
-               "\nReboot's Linker for Atari Jaguar\n"
-               "Copyright (c) 199x Allan K. Pratt, 2014-2018 Reboot\n"
+               "\nRenamed Linker for Atari Jaguar\n"
+               "Copyright (c) 199x Allan K. Pratt, 2014-2021 Reboot & Friends\n"
                "V%i.%i.%i %s (%s)\n\n", MAJOR, MINOR, PATCH, __DATE__, PLATFORM);
        }
 }
@@ -3043,10 +3099,13 @@ void ShowHelp(void)
        printf("\n");
        printf("Options:\n");
        printf("   -? or -h                display usage information\n");
-       printf("   -a <text> <data> <bss>  output absolute file\n");
+       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");
@@ -3056,7 +3115,7 @@ void ShowHelp(void)
        printf("   -ii <fname> <label>     incbin <fname> and set <label> (no truncation)\n");
        printf("   -l                      add local symbols\n");
        printf("   -m                      produce load symbols map\n");
-       printf("   -n                      output no file header to absolute file\n");
+       printf("   -n                      output no file header to absolute file (overrides -e)\n");
        printf("   -o <fname>              set output name\n");
        printf("   -r<size>                section alignment size\n");
        printf("                           w: word (2 bytes)\n");
@@ -3068,6 +3127,7 @@ void ShowHelp(void)
        printf("   -u                      allow unresolved symbols (experimental)\n");
        printf("   -v                      set verbose mode\n");
        printf("   -w                      show linker warnings\n");
+       printf("   -y <fname>              set include path (also set by RLNPATH)\n");
        printf("   -z                      suppress banner\n");
        printf("\n");
 }
@@ -3114,6 +3174,21 @@ int main(int argc, char * argv[])
                ExitLinker();
        }
 
+       // Check to see if include paths actually exist
+       if (strlen(libdir) > 0)
+       {
+               DIR * test = opendir(libdir);
+
+               if (test == NULL)
+               {
+                       printf("Invalid include path: %s\n", libdir);
+                       errflag = 1;
+                       ExitLinker();
+               }
+
+               closedir(test);
+       }
+
        if (!zflag && !vflag)
        {
                ShowVersion();                          // Display version information