X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=rln.c;h=da8fb781ef61c6c6ddf4da633c9521db458ded10;hb=35f3e59d5c26e96743cd77315ae1d466b13e9427;hp=1f09e61348b0b933ffab239f70612040e214cf91;hpb=e1ddda6e4088b0f201fb3524909df29c8c3a3477;p=rln diff --git a/rln.c b/rln.c index 1f09e61..da8fb78 100644 --- a/rln.c +++ b/rln.c @@ -20,8 +20,9 @@ unsigned oflag = 0; // Output filename specified unsigned rflag = 0; // Segment alignment size flag unsigned sflag = 0; // Output only global symbols unsigned vflag = 0; // Verbose flag +unsigned wflag = 0; // Show warnings flag unsigned zflag = 0; // Suppress banner flag -unsigned pflag, uflag, wflag = 1; // Unimplemented flags +unsigned pflag, uflag; // Unimplemented flags unsigned hd = 0; // Index of next file handle to fill unsigned secalign = 7; // Section Alignment (8=phrase) unsigned tbase = 0; // TEXT base address @@ -67,18 +68,22 @@ char * oststr_end; // Output string table; end pointer int ost_index = 0; // Index of next ost addition int endian; // Processor endianess +// Some human readable defines for endianess +#define ENDIANNESS_BIG 1 +#define ENDIANNESS_LITTLE 0 + // // Get a Long Word from Memory // -unsigned getlong(char * src) +uint32_t getlong(uint8_t * src) { - unsigned temp; - char * out; + uint32_t temp; + uint8_t * out; - out = (char *)&temp; + out = (uint8_t *)&temp; - if (endian == 1) + if (endian == ENDIANNESS_BIG) { *out++ = src[0]; *out++ = src[1]; @@ -100,28 +105,43 @@ unsigned getlong(char * src) // // Put a Long Word into Memory // -void putlong(char * dest, unsigned val) +void putlong(uint8_t * dest, uint32_t val) { - *dest++ = (char)(val >> 24); - *dest++ = (char)(val >> 16); - *dest++ = (char)(val >> 8); - *dest = (char)val; + *dest++ = (uint8_t)(val >> 24); + *dest++ = (uint8_t)(val >> 16); + *dest++ = (uint8_t)(val >> 8); + *dest = (uint8_t)val; } // // Get a Word from Memory // -int getword(char * src) +uint16_t getword(uint8_t * src) { - unsigned temp; - char * out; + uint16_t temp; + uint8_t * out; - out = (char *)&temp; + out = (uint8_t *)&temp; +#if 0 + // Shamus: This assumes little endian... *out++ = src[1]; *out++ = src[0]; - *out++ = 0; - *out = 0; +// Shamus: And *why* do this as a uint32_t??? +// *out++ = 0; +// *out = 0; +#else + if (endian == ENDIANNESS_BIG) + { + out[0] = src[0]; + out[1] = src[1]; + } + else + { + out[0] = src[1]; + out[1] = src[0]; + } +#endif return temp; } @@ -130,10 +150,10 @@ int getword(char * src) // // Put a Word into Memory // -void putword(char * dest, int val) +void putword(uint8_t * dest, uint16_t val) { - *dest++ = (char)(val >> 8); - *dest = (char)val; + *dest++ = (uint8_t)(val >> 8); + *dest = (uint8_t)val; } @@ -392,8 +412,8 @@ void hash_free(void) // long docommon(void) { - struct HREC * hptr; // Hash record pointer - int i; // Iterator + struct HREC * hptr; // Hash record pointer + int i; // Iterator for(i=0; ih_type)) { if (hptr->h_type == 0x03000000) - hptr->h_type = 0x02000000; // Absolutes can't be externals + hptr->h_type = 0x02000000; // Absolutes can't be externals if (ost_add(hptr->h_sym, hptr->h_type, hptr->h_value) == -1) return -1; @@ -420,9 +440,9 @@ long docommon(void) // int ost_add(char * name, int type, long value) { - int ost_offset_p, ost_offset_e = 0; // OST table offsets for position calcs - int slen = 0; // Symbol string length - int ostresult; // OST index result + int ost_offset_p, ost_offset_e = 0; // OST table offsets for position calcs + int slen = 0; // Symbol string length + int ostresult; // OST index result slen = strlen(name); @@ -455,8 +475,9 @@ int ost_add(char * name, int type, long value) ost_offset_p = (ost_ptr - ost); ost_offset_e = (ost_end - ost); + // 3 x int (12) if ((ost_ptr + 12) > ost_end) - { // 3 x int (12) + { if ((ost = realloc(ost, (unsigned)(ost_end + OST_BLOCK))) == NULL) { printf("OST memory reallocation error.\n"); @@ -470,7 +491,7 @@ int ost_add(char * name, int type, long value) ost_offset_p = (oststr_ptr - oststr); ost_offset_e = (oststr_end - oststr); - if ((oststr_ptr + (slen+1+4)) > oststr_end) + if ((oststr_ptr + (slen + 1 + 4)) > oststr_end) { if ((oststr = realloc(oststr, (unsigned)(oststr_end + OST_BLOCK))) == NULL) { @@ -483,7 +504,8 @@ int ost_add(char * name, int type, long value) } } - // If this is a debug symbol and the include debug symbol flag (-g) is not set then do nothing + // If this is a debug symbol and the include debug symbol flag (-g) is not + // set then do nothing if ((type & 0xF0000000) && !gflag) { // Do nothing @@ -491,11 +513,13 @@ int ost_add(char * name, int type, long value) else { ostresult = ost_lookup(name); // Get symbol index in OST - // If the symbol is in the output symbol table and the bflag is set (don't remove multiply - // defined locals) and this is not an external/global symbol *** OR *** the symbol is not - // in the output symbol table then add it. + + // If the symbol is in the output symbol table and the bflag is set + // (don't remove multiply defined locals) and this is not an + // external/global symbol *** OR *** the symbol is not in the output + // symbol table then add it. if (((ostresult != -1) && bflag && !(type & 0x01000000)) - || ((ostresult != -1) && gflag && (type & 0xF0000000)) || (ostresult == -1)) + || ((ostresult != -1) && gflag && (type & 0xF0000000)) || (ostresult == -1)) { if ((type & 0xF0000000) == 0x40000000) putlong(ost_ptr, 0x00000000); // Zero string table offset for dbg line @@ -506,8 +530,8 @@ int ost_add(char * name, int type, long value) putlong(ost_ptr + 8, value); ost_ptr += 12; - // If the symbol type is anything but a debug line information symbol then write - // the symbol string to the string table + // If the symbol type is anything but a debug line information + // symbol then write the symbol string to the string table if ((type & 0xF0000000) != 0x40000000) { strcpy(oststr_ptr, name); // Put symbol name in string table @@ -521,7 +545,8 @@ int ost_add(char * name, int type, long value) } } - return 0; // not sure about this as it could affect return indices. needed to stop return error. + // not sure about this as it could affect return indices. needed to stop return error. + return 0; } @@ -535,10 +560,10 @@ int ost_lookup(char * sym) for(i=0; ih_sym, T_EXT, 0L) == -1) return 1; -printf("dounresolved(): added %s\n",hptr->h_sym); + +//printf("dounresolved(): added %s\n",hptr->h_sym); htemp = hptr->h_next; // Temporarily get ptr to next record free(hptr); // Free current record hptr = htemp; // Make next record ptr, current @@ -757,9 +783,15 @@ int reloc_segment(struct OFILE * ofile, int flag) } // Shamus: Let's output some info to aid in debugging this crap - if (vflag) + if (vflag > 1) { - printf("reloc_segment(%d): %s, $%08X: $%08X => $%08X\n",i, (glblreloc ? sym : "(LOCAL)"), addr, olddata, getlong(sptr + addr)); + char ssiString[128]; + ssiString[0] = 0; + + if (glblreloc) + sprintf(ssiString, " [ssi:%i]", ssidx); + + printf("reloc_segment($%08X): %s, $%08X: $%08X => $%08X%s\n", rflg, (glblreloc ? sym : "(LOCAL)"), addr, olddata, getlong(sptr + addr), ssiString); } rptr += 8; // Point to the next relocation record @@ -890,7 +922,7 @@ ok: void put_name(struct OFILE * p) { int flag = *(p->o_arname); - printf("%s%s%s", flag ? p->o_arname : "", flag ? ":" : "", p->o_name); + printf("%s%s%s", (flag ? (char *)(p->o_arname) : ""), (flag ? ":" : ""), p->o_name); } @@ -1638,6 +1670,12 @@ int add_to_hlist(struct HREC ** hptr, char * sym, struct OFILE * ofile, long val return 1; } + // Shamus: Moar testing... + if (vflag > 1) + { + printf("add_to_hlist(): hptr=$%08X, sym=\"%s\", ofile=$%08X, value=%li, type=%i", (unsigned int)hptr, sym, (unsigned int)ofile, value, type); + } + for(i=0; ih_sym[i] = '\0'; @@ -1688,8 +1726,9 @@ struct HREC * lookup(char * sym) while (hptr != NULL) { - // if (symcmp(symbol, hptr->h_sym)) <-- left here for giggles :D - LinkoVitch - if (strcmp(symbol,hptr->h_sym)==0) +//This is utter failure... +// if (symcmp(symbol, hptr->h_sym)) <-- left here for giggles :D - LinkoVitch + if (strcmp(symbol, hptr->h_sym) == 0) return hptr; hptr = hptr->h_next; // Return hash pointer if found @@ -2434,278 +2473,285 @@ int docmdfile(char * fname) // int doargs(int argc, char * argv[]) { - int i = 1; // Iterator - int c; // Command line character - char * ifile, * isym; // File name and symbol name for -i - - while (i < argc) - { // Parse through option switches & files - if (argv[i][0] == '-') - { // Process command line switches - if (!argv[i][1]) - { - printf("Illegal option argument: %s\n\n", argv[i]); - display_help(); - return 1; - } - - c = argv[i++][1]; // Get next character in command line - - switch (c) - { // Process command line switch - case '?': // Display usage information - case 'h': + int i = 1; // Iterator + int c; // Command line character + char * ifile, * isym; // File name and symbol name for -i + + while (i < argc) + { // Parse through option switches & files + if (argv[i][0] == '-') + { // Process command line switches + if (!argv[i][1]) + { + printf("Illegal option argument: %s\n\n", argv[i]); + display_help(); + return 1; + } + + c = argv[i++][1]; // Get next character in command line + + switch (c) + { // Process command line switch + case '?': // Display usage information + case 'h': case 'H': - display_version(); - display_help(); - return 1; - case 'a': + display_version(); + display_help(); + return 1; + case 'a': case 'A': // Set absolute linking on - if (aflag) - warn('a', 1); - - if (i + 2 >= argc) - { - printf("Not enough arguments to -a\n"); - return 1; - } - - aflag = 1; // Set abs link flag - // Segment order is TEXT, DATA, BSS - // Text segment can be 'r', 'x' or a value - ttype = 0; - - if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) - { - ttype = -1; // TEXT segment is relocatable - } - else if ((*argv[i] == 'x' || *argv[i] == 'X')) - { - printf("Error in text-segment address: cannot be contiguous\n"); - return 1; - } - else if ((ttype = 0), getval(argv[i], &tval)) - { - printf("Error in text-segment address: %s is not 'r', 'x' or an address.", argv[i]); - return 1; - } - - i++; - // Data segment can be 'r', 'x' or a value - dtype = 0; - - if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) - { - dtype = -1; // DATA segment is relocatable - } - else if ((*argv[i] == 'x' || *argv[i] == 'X')) - { - dtype = -2; // DATA follows TEXT - } - else if ((dtype = 0), getval(argv[i],&dval)) - { - printf("Error in data-segment address: %s is not 'r', 'x' or an address.", argv[i]); - return 1; - } - - i++; - btype = 0; - - // BSS segment can be 'r', 'x' or a value - if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) - { - btype = -1; // BSS segment is relocatable - } - else if ((*argv[i] == 'x' || *argv[i] == 'X')) - { - btype = -3; // BSS follows DATA - } - else if ((btype = 0), getval(argv[i],&bval)) - { - printf("Error in bss-segment address: %s is not 'r', 'x[td]', or an address.", argv[i]); - return 1; - } - - i++; - break; - case 'b': + if (aflag) + warn('a', 1); + + if (i + 2 >= argc) + { + printf("Not enough arguments to -a\n"); + return 1; + } + + aflag = 1; // Set abs link flag + // Segment order is TEXT, DATA, BSS + // Text segment can be 'r', 'x' or a value + ttype = 0; + + if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) + { + ttype = -1; // TEXT segment is relocatable + } + else if ((*argv[i] == 'x' || *argv[i] == 'X')) + { + printf("Error in text-segment address: cannot be contiguous\n"); + return 1; + } + else if ((ttype = 0), getval(argv[i], &tval)) + { + printf("Error in text-segment address: %s is not 'r', 'x' or an address.", argv[i]); + return 1; + } + + i++; + // Data segment can be 'r', 'x' or a value + dtype = 0; + + if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) + { + dtype = -1; // DATA segment is relocatable + } + else if ((*argv[i] == 'x' || *argv[i] == 'X')) + { + dtype = -2; // DATA follows TEXT + } + else if ((dtype = 0), getval(argv[i],&dval)) + { + printf("Error in data-segment address: %s is not 'r', 'x' or an address.", argv[i]); + return 1; + } + + i++; + btype = 0; + + // BSS segment can be 'r', 'x' or a value + if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) + { + btype = -1; // BSS segment is relocatable + } + else if ((*argv[i] == 'x' || *argv[i] == 'X')) + { + btype = -3; // BSS follows DATA + } + else if ((btype = 0), getval(argv[i],&bval)) + { + printf("Error in bss-segment address: %s is not 'r', 'x[td]', or an address.", argv[i]); + return 1; + } + + i++; + break; + case 'b': case 'B': // Don't remove muliply defined locals - if (bflag) - warn('b', 1); + if (bflag) + warn('b', 1); - bflag = 1; - break; - case 'c': + bflag = 1; + break; + case 'c': case 'C': // Process a command file - if (i == argc) - { - printf("Not enough arguments to -c\n"); - return 1; - } - - if (docmdfile(argv[i++])) - { - return 1; - } - - break; - case 'd': + if (i == argc) + { + printf("Not enough arguments to -c\n"); + return 1; + } + + if (docmdfile(argv[i++])) + { + return 1; + } + + break; + case 'd': case 'D': // Wait for "return" before exiting - if (dflag) - warn('d', 0); + if (dflag) + warn('d', 0); - dflag = 1; - waitflag = 1; - break; - case 'e': + dflag = 1; + waitflag = 1; + break; + case 'e': case 'E': // Output COFF (absolute only) - cflag = 1; - break; - case 'g': + cflag = 1; + break; + case 'g': case 'G': // Output source level debugging - printf("\'g\' flag not currently implemented\n"); - gflag = 0; - /* - if (gflag) warn('g', 1); - gflag = 1; - */ - break; - case 'i': + printf("\'g\' flag not currently implemented\n"); + gflag = 0; + /* + if (gflag) warn('g', 1); + gflag = 1; + */ + break; + case 'i': case 'I': // Include binary file - if (i + 2 > argc) - { - printf("Not enough arguments to -i\n"); - return 1; - } - - ifile = argv[i++]; - isym = argv[i++]; - - if ((argv[i-3][2] == 'i') || (argv[i-3][2] == 'I')) - { // handle -ii (No truncation) - if (!cflag) - printf("warning: (-ii) COFF format output not specified\n"); - } - else - { // handle -i (Truncation) - if (strlen(isym) > 7) - isym[7] = '\0'; - } - - // Place include files in the DATA segment only - if (dofile(ifile, DSTSEG_D, isym)) - return 1; - - break; - case 'l': + if (i + 2 > argc) + { + printf("Not enough arguments to -i\n"); + return 1; + } + + ifile = argv[i++]; + isym = argv[i++]; + + if ((argv[i-3][2] == 'i') || (argv[i-3][2] == 'I')) + { // handle -ii (No truncation) + if (!cflag) + printf("warning: (-ii) COFF format output not specified\n"); + } + else + { // handle -i (Truncation) + if (strlen(isym) > 7) + isym[7] = '\0'; + } + + // Place include files in the DATA segment only + if (dofile(ifile, DSTSEG_D, isym)) + return 1; + + break; + case 'l': case 'L': // Add local symbols - if (lflag) - warn('l', 1); + if (lflag) + warn('l', 1); - lflag = 1; - break; - case 'm': + lflag = 1; + break; + case 'm': case 'M': // Produce load symbol map - if (mflag) - warn('m', 1); + if (mflag) + warn('m', 1); - mflag = 1; - break; - case 'n': + mflag = 1; + break; + case 'n': case 'N': // Output no header to .abs file - if (noheaderflag) - warn('n', 1); + if (noheaderflag) + warn('n', 1); - noheaderflag = 1; - break; - case 'o': + noheaderflag = 1; + break; + case 'o': case 'O': // Specify an output file - if (oflag) - warn('o', 1); - - oflag = 1; - - if (i >= argc) - { - printf("No output filename following -o switch\n"); - return 1; - } - - if (strlen(argv[i]) > FARGSIZE - 5) - { - printf("Output file name too long (sorry!)\n"); - return 1; - } - - strcpy(ofile, argv[i++]); - break; - case 'r': + if (oflag) + warn('o', 1); + + oflag = 1; + + if (i >= argc) + { + printf("No output filename following -o switch\n"); + return 1; + } + + if (strlen(argv[i]) > FARGSIZE - 5) + { + printf("Output file name too long (sorry!)\n"); + return 1; + } + + strcpy(ofile, argv[i++]); + break; + case 'r': case 'R': // Section alignment size - if (rflag) - warn('r', 1); - - rflag = 1; - - switch (argv[i-1][2]) - { - case 'w': case 'W': secalign = 1; break; // Word alignment - case 'l': case 'L': secalign = 3; break; // Long alignment - case 'p': case 'P': secalign = 7; break; // Phrase alignment - case 'd': case 'D': secalign = 15; break; // Double phrase alignment - case 'q': case 'Q': secalign = 31; break; // Quad phrase alignment - default: secalign = 7; break; // Default phrase alignment - } - - break; - case 's': + if (rflag) + warn('r', 1); + + rflag = 1; + + switch (argv[i-1][2]) + { + case 'w': case 'W': secalign = 1; break; // Word alignment + case 'l': case 'L': secalign = 3; break; // Long alignment + case 'p': case 'P': secalign = 7; break; // Phrase alignment + case 'd': case 'D': secalign = 15; break; // Double phrase alignment + case 'q': case 'Q': secalign = 31; break; // Quad phrase alignment + default: secalign = 7; break; // Default phrase alignment + } + + break; + case 's': case 'S': // Output only global symbols - if (sflag) - warn('s', 1); + if (sflag) + warn('s', 1); - sflag = 1; - break; - case 'v': + sflag = 1; + break; + case 'v': case 'V': // Verbose information - if (!vflag && !versflag) - { - display_version(); - } - - vflag++; - break; - case 'z': + if (!vflag && !versflag) + { + display_version(); + } + + vflag++; + break; + case 'w': + case 'W': // Show warnings flag + if (wflag) + warn('w', 1); + + wflag = 1; + break; + case 'z': case 'Z': // Suppress banner flag - if (zflag) - warn('z', 1); - - zflag = 1; - break; - default: - printf("unknown option argument `%c'\n", c); - return 1; - } - } - else - { // Not a switch, then process as a file - if (dofile(argv[i++], 0, NULL)) - return 1; - } - - } - - if (!oflag && vflag) - { - strcpy(ofile, "output"); - printf("Output file is %s[.ext]\n", ofile); - } - - if (oflag && vflag) - printf("Output file is %s\n", ofile); - - if (sflag) - lflag = 0; - - return 0; // No problems encountered + if (zflag) + warn('z', 1); + + zflag = 1; + break; + default: + printf("unknown option argument `%c'\n", c); + return 1; + } + } + else + { // Not a switch, then process as a file + if (dofile(argv[i++], 0, NULL)) + return 1; + } + + } + + if (!oflag && vflag) + { + strcpy(ofile, "output"); + printf("Output file is %s[.ext]\n", ofile); + } + + if (oflag && vflag) + printf("Output file is %s\n", ofile); + + if (sflag) + lflag = 0; + + return 0; // No problems encountered } @@ -2755,6 +2801,7 @@ void display_help(void) printf(" q: quad phrase (32 bytes)\n"); printf(" -s output only global symbols\n"); printf(" -v set verbose mode\n"); + printf(" -w show linker warnings\n"); printf(" -z suppress banner\n"); printf("\n"); } @@ -2774,7 +2821,7 @@ void rln_exit(void) // Wait for return key if requested if (waitflag) { - printf("\nPress the key to continue. "); + printf("\nPress the [RETURN] key to continue. "); fgets(tempbuf, 128, stdin); } @@ -2791,9 +2838,9 @@ int get_endianess(void) char * p = (char *)&i; if (p[0] == 1) - return 0; // LITTLE + return ENDIANNESS_LITTLE; - return 1; // BIG + return ENDIANNESS_BIG; } @@ -2902,9 +2949,9 @@ int main(int argc, char * argv[]) printf("Absolute linking "); if (cflag) - printf("(COF)\n"); + printf("(COF)\n"); else - printf("(ABS)\n"); + printf("(ABS)\n"); } if (vflag > 1) @@ -2929,6 +2976,8 @@ int main(int argc, char * argv[]) printf("+---------+----------+----------+----------+\n\n"); } +//printf("BIG_ENDIAN = %i, LITTLE_ENDIAN = %i\n", BIG_ENDIAN, LITTLE_ENDIAN); + free(header); // Free allocated memory rln_exit(); // Perform application exit }