X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=rln.c;h=a1ab13e57357995a6eb82b02fd75ec08eed2cc61;hb=65c5194d321a3a7ae8abc9ca1e34202788734801;hp=6ab46eecb592d9a2328ab72e8367fdcd397a11c4;hpb=5644d379564f7e2960154f5df7689314589e9d03;p=rln diff --git a/rln.c b/rln.c index 6ab46ee..a1ab13e 100644 --- a/rln.c +++ b/rln.c @@ -5,6 +5,7 @@ // #include "rln.h" +//#include unsigned errflag = 0; // Error flag, goes TRUE on error unsigned waitflag = 0; // Wait for any keypress flag @@ -22,7 +23,7 @@ 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; // Unimplemented flags +unsigned pflag = 0, uflag = 0; // 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 @@ -171,14 +172,14 @@ long FileSize(int fd) // For this object file, add symbols to the output symbol table after // relocating them. Returns TRUE if OSTLookup returns an error (-1). // -int DoSymbol(struct OFILE * ofile) +int DoSymbols(struct OFILE * ofile) { - int type; // Symbol type - long value; // Symbol value - int index; // Symbol index - int j; // Iterator - struct HREC * hptr; // Hash table pointer for globl/extrn - char sym[SYMLEN]; // String for symbol name/hash search + int type; + long value; + int index; + int j; + struct HREC * hptr; + unsigned tsoSave, dsoSave, bsoSave; // Point to first symbol record in the object file char * symptr = (ofile->o_image + 32 @@ -213,11 +214,15 @@ int DoSymbol(struct OFILE * ofile) if (ssidx == -1) { - printf("DoSymbol(): Cannot get object file segment size: %s\n", ofile->o_name); + printf("DoSymbols(): Object file missing from obj_fname: %s\n", + ofile->o_name); return 1; } - // Process each record in the symbol table + // Save segment vars, so we can restore them if needed + tsoSave = tsegoffset, dsoSave = dsegoffset, bsoSave = bsegoffset; + + // Process each record in the object's symbol table for(; symptr!=symend; symptr+=12) { index = getlong(symptr + 0); // Obtain symbol string index @@ -225,30 +230,38 @@ int DoSymbol(struct OFILE * ofile) value = getlong(symptr + 8); // Obtain symbol value // Global/External symbols have a pre-processing stage + // N.B.: This destroys the t/d/bsegoffset discovered above. So if a + // local symbol follows a global/exported one, it gets wrong + // info! [Should be FIXED now] if (type & 0x01000000) { // Obtain the string table index for the relocation symbol, look // for it in the globals hash table to obtain information on that // symbol. -#if 0 - memset(sym, 0, SYMLEN); - strcpy(sym, symend + index); - hptr = LookupHREC(sym); -#else hptr = LookupHREC(symend + index); -#endif if (hptr == NULL) { - printf("DoSymbol() : Cannot determine symbol : %s\n", sym); - return 1; + // Try to find it in the OST + int ostIndex = OSTLookup(symend + index); + + if (ostIndex == -1) + { + printf("DoSymbols(): Symbol not found in hash table: '%s' (%s)\n", symend + index, ofile->o_name); + return 1; + } + + // If the symbol is not in any .a or .o units, it must be one + // of the injected ones (_TEXT_E, _DATA_E, or _BSS_E), so skip + // it + continue; } // Search through object segment size table to obtain segment sizes // for the object that has the required external/global as a local // symbol. As each object is interrogated the segment sizes are // accumulated to ensure the correct offsets are used in the - // resulting COF file. This is effectively 'done again' only as we + // resulting COF file. This is effectively 'done again' only as we // are working with a different object file. ssidx = -1; tsegoffset = dsegoffset = bsegoffset = 0; @@ -270,7 +283,9 @@ int DoSymbol(struct OFILE * ofile) if (ssidx == -1) { - printf("DoSymbol() : Cannot get object file segment size : %s\n", ofile->o_name); + printf("DoSymbols(): Object file missing from obj_fname: '%s:%s' symbol: '%s' (%s)\n", + hptr->h_ofile->o_name, hptr->h_ofile->o_arname, + symend + index, ofile->o_name); return 1; } @@ -303,6 +318,9 @@ int DoSymbol(struct OFILE * ofile) } } } + // If *not* a global/external, use the info from passed in object + else + tsegoffset = tsoSave, dsegoffset = dsoSave, bsegoffset = bsoSave; // Process and update the value dependent on whether the symbol is a // debug symbol or not @@ -370,12 +388,15 @@ int DoSymbol(struct OFILE * ofile) } // Add to output symbol table if global/extern, or local flag is set - if (lflag || !islocal(type)) + if (isglobal(type) || lflag) { index = OSTAdd(symend + index, type, value); if (index == -1) + { + printf("DoSymbols(): Failed to add symbol '%s' to OST!\n", symend + index); return 1; + } } } @@ -429,6 +450,7 @@ long DoCommon(void) //if (hptr->h_ofile->isArchiveFile) // continue; +//Is this true? Couldn't an absolute be exported??? if (hptr->h_type == (T_EXT | T_ABS)) hptr->h_type = T_ABS; // Absolutes *can't* be externals @@ -443,35 +465,36 @@ long DoCommon(void) // -// Add a Symbol's Name, Type, and Value to the OST. -// Return the Index of the Symbol in OST, or -1 for Error. +// Add a symbol's name, type, and value to the OST. +// Returns the index of the symbol in OST, or -1 for error. // int OSTAdd(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 slen = strlen(name); - slen = strlen(name); - - // If the OST or OST String Table has not been initialised then do so + // If the OST or OST string table has not been initialised then do so if (ost_index == 0) { - if ((ost = malloc(OST_BLOCK)) == NULL) + ost = malloc(OST_BLOCK); + oststr = malloc(OST_BLOCK); + + if (ost == NULL) { - printf("OST memory allocation error (stringtable).\n"); + printf("OST memory allocation error.\n"); return -1; } - ost_ptr = ost; // Set OST start pointer - ost_end = ost + OST_BLOCK; // Set OST end pointer - - if ((oststr = malloc(OST_BLOCK)) == NULL) + if (oststr == NULL) { - printf("OST memory allocation error (string).\n"); + printf("OSTSTR memory allocation error.\n"); return -1; } + ost_ptr = ost; // Set OST start pointer + ost_end = ost + OST_BLOCK; // Set OST end pointer + putlong(oststr, 0x00000004); // Just null long for now oststr_ptr = oststr + 4; // Skip size of str table long (incl null long) putlong(oststr_ptr, 0x00000000); // Null terminating long @@ -480,15 +503,17 @@ int OSTAdd(char * name, int type, long value) else { // If next symbol record exceeds current allocation then expand symbol - // table. + // table and/or symbol string table. ost_offset_p = (ost_ptr - ost); ost_offset_e = (ost_end - ost); - // 3 x int (12) + // 3 x uint32_t (12 bytes) if ((ost_ptr + 12) > ost_end) { -#warning "!!! Bad logic in realloc call !!!" - if ((ost = realloc(ost, (ost_end + OST_BLOCK))) == NULL) + // We want to allocate the current size of the OST + another block. + ost = realloc(ost, ost_offset_e + OST_BLOCK); + + if (ost == NULL) { printf("OST memory reallocation error.\n"); return -1; @@ -501,10 +526,12 @@ int OSTAdd(char * name, int type, long value) ost_offset_p = (oststr_ptr - oststr); ost_offset_e = (oststr_end - oststr); + // string length + terminating NULL + uint32_t (terminal long) if ((oststr_ptr + (slen + 1 + 4)) > oststr_end) { -#warning "!!! Bad logic in realloc call !!!" - if ((oststr = realloc(oststr, (oststr_end + OST_BLOCK))) == NULL) + oststr = realloc(oststr, ost_offset_e + OST_BLOCK); + + if (oststr == NULL) { printf("OSTSTR memory reallocation error.\n"); return -1; @@ -520,55 +547,58 @@ int OSTAdd(char * name, int type, long value) if ((type & 0xF0000000) && !gflag) { // Do nothing + return 0; } - else - { - ostresult = OSTLookup(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 (((ostresult != -1) && bflag && !(type & 0x01000000)) - || ((ostresult != -1) && gflag && (type & 0xF0000000)) || (ostresult == -1)) - { - if ((type & 0xF0000000) == 0x40000000) - putlong(ost_ptr, 0x00000000); // Zero string table offset for dbg line - else - putlong(ost_ptr, (oststr_ptr - oststr)); // String table offset of symbol string + // Get symbol index in OST, if any (-1 if not found) + ostresult = OSTLookup(name); - putlong(ost_ptr + 4, type ); - putlong(ost_ptr + 8, value); - ost_ptr += 12; + // 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)) + { + if ((type & 0xF0000000) == 0x40000000) + putlong(ost_ptr, 0x00000000); // Zero string table offset for dbg line + else + putlong(ost_ptr, (oststr_ptr - oststr)); // String table offset of symbol string - // 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 - *(oststr_ptr + slen) = '\0'; // Add null terminating character - oststr_ptr += (slen + 1); - putlong(oststr_ptr, 0x00000000); // Null terminating long - putlong(oststr, (oststr_ptr - oststr)); // Update size of string table - } + putlong(ost_ptr + 4, type); + putlong(ost_ptr + 8, value); + ost_ptr += 12; - if (vflag > 1) - { - printf("OSTAdd: (%s), type=$%08X, val=$%08X\n", name, type, value); - } + // 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 + *(oststr_ptr + slen) = '\0'; // Add null terminating character + oststr_ptr += (slen + 1); + putlong(oststr_ptr, 0x00000000); // Null terminating long + putlong(oststr, (oststr_ptr - oststr)); // Update size of string table + } - return ost_index++; + if (vflag > 1) + { + printf("OSTAdd: (%s), type=$%08X, val=$%08lX\n", name, type, value); } + +// is ost_index pointing one past? +// does this return the same regardless of if its ++n or n++? +// no. it returns the value of ost_index *before* it's incremented. + return ++ost_index; } - // Not sure about this as it could affect return indices. Needed to stop - // return error. - return 0; + return ostresult; } // // Return the index of a symbol in the output symbol table +// N.B.: This is a 1-based index! (though there's no real reason for it to be) // int OSTLookup(char * sym) { @@ -589,6 +619,7 @@ int OSTLookup(char * sym) // // Add unresolved externs to the output symbol table +// N.B.: Only adds unresolved symbols *if* they're not already in the OST // int DoUnresolved(void) { @@ -601,7 +632,7 @@ int DoUnresolved(void) return 1; if (vflag > 1) - printf("DoUnresolved(): added %s\n", hptr->h_sym); + printf("DoUnresolved(): '%s' (%s:$%08X) in OST\n", hptr->h_sym, hptr->h_ofile->o_name, hptr->h_type); struct HREC * htemp = hptr->h_next; free(hptr); @@ -620,24 +651,24 @@ int DoUnresolved(void) // int RelocateSegment(struct OFILE * ofile, int flag) { - char * symtab; // Start of symbol table - char * symbols; // Start of symbols - char * sptr; // Start of segment data - char * rptr; // Start of segment relocation records - unsigned symidx; // Offset to symbol - unsigned addr; // Relocation address - unsigned rflg; // Relocation flags - unsigned olddata; // Old segment data at reloc address - unsigned newdata = 0; // New segment data at reloc address - unsigned pad; // Temporary to calculate phrase padding - int i; // Iterator - char sym[SYMLEN]; // String for symbol name/hash search - int ssidx; // Segment size table index - unsigned glblreloc; // Global relocation flag - unsigned absreloc; // Absolute relocation flag - unsigned relreloc; // Relative relocation flag - unsigned swcond; // Switch statement condition - unsigned relocsize; // Relocation record size + char * symtab; // Start of symbol table + char * symbols; // Start of symbols + char * sptr; // Start of segment data + char * rptr; // Start of segment relocation records + unsigned symidx; // Offset to symbol + unsigned addr; // Relocation address + unsigned rflg; // Relocation flags + unsigned olddata; // Old segment data at reloc address + unsigned newdata = 0; // New segment data at reloc address + unsigned pad; // Temporary to calculate phrase padding + int i; // Iterator + char sym[SYMLEN]; // String for symbol name/hash search + int ssidx; // Segment size table index + unsigned glblreloc; // Global relocation flag + unsigned absreloc; // Absolute relocation flag + unsigned relreloc; // Relative relocation flag + unsigned swcond; // Switch statement condition + unsigned relocsize; // Relocation record size // If there is no TEXT relocation data for the selected object file segment // then update the COF TEXT segment offset allowing for the phrase padding @@ -1051,10 +1082,9 @@ int DoFile(char * fname, int incFlag, char * sym) // int segmentpad(FILE * fd, long segsize, int value) { -// long padsize; // Number of pad bytes needed - int i; // Good 'ol iterator - char padarray[32]; // Array of padding bytes - char * padptr; // Pointer to array + int i; + char padarray[32]; + char * padptr; // Determine the number of padding bytes that are needed long padsize = (segsize + secalign) & ~secalign; @@ -1287,7 +1317,7 @@ int write_ofile(struct OHEADER * header) else { // The symbol and string table have been created as part of the - // DoSymbol() function and the output symbol and string tables are + // DoSymbols() function and the output symbol and string tables are // in COF format. For an ABS file we need to process through this // to create the 14 character long combined symbol and string // table. Format of symbol table in ABS: AAAAAAAATTVVVV, where @@ -1301,7 +1331,7 @@ int write_ofile(struct OHEADER * header) index = getlong(ost + (i * 12)); // Get symbol index type = getlong((ost + (i * 12)) + 4); // Get symbol type - // Not doing debug symbols + // Skip debug symbols if (type & 0xF0000000) continue; @@ -1508,9 +1538,9 @@ int GetHexValue(char * string, int * value) // struct OHEADER * make_ofile() { - unsigned tptr, dptr, bptr; // Bases in runtime model - int ret = 0; // Return value - struct OHEADER * header; // Output header pointer + unsigned tptr, dptr, bptr; // Bases in runtime model + int ret = 0; // Return value + struct OHEADER * header; // Output header pointer // Initialize cumulative segment sizes textsize = datasize = bsssize = 0; @@ -1545,8 +1575,6 @@ struct OHEADER * make_ofile() if (!ohold->isArchiveFile) free(ohold->o_image); -// free(ohold); - // Also need to remove them from the obj_* tables too :-P // N.B.: Would probably be worthwhile to remove crap like this // and stuff it into the OFILE structure... @@ -1584,48 +1612,39 @@ struct OHEADER * make_ofile() // Update base addresses and create symbols _TEXT_E, _DATA_E and _BSS_E tbase = tval; - OSTAdd("_TEXT_E", 0x05000000, tval + textsize); if (!dval) { // DATA follows TEXT dbase = tval + textsize; - OSTAdd("_DATA_E", 0x07000000, tval + textsize + datasize); if (!bval) - { // BSS follows DATA bbase = tval + textsize + datasize; - OSTAdd("_BSS_E", 0x09000000, tval + textsize + datasize + bsssize); - } else - { // BSS is independent of DATA bbase = bval; - OSTAdd("_BSS_E", 0x09000000, bval + bsssize); - } } else { // DATA is independant of TEXT dbase = dval; - OSTAdd("_DATA_E", 0x07000000, dval + datasize); if (!bval) - { // BSS follows DATA bbase = dval + datasize; - OSTAdd("_BSS_E", 0x09000000, dval + datasize + bsssize); - } else - { // BSS is independent of DATA bbase = bval; - OSTAdd("_BSS_E", 0x09000000, bval + bsssize); - } } + OSTAdd("_TEXT_E", 0x05000000, tbase + textsize); + OSTAdd("_DATA_E", 0x07000000, dbase + datasize); + OSTAdd("_BSS_E", 0x09000000, bbase + bsssize); + // Place each unresolved symbol in the output symbol table + // N.B.: It only gets here to do this if user passes in -u flag + // [Only used here, once] if (DoUnresolved()) return NULL; @@ -1654,7 +1673,8 @@ struct OHEADER * make_ofile() // For each symbol, (conditionally) add it to the ost // For ARCHIVE markers, this adds the symbol for the file & returns // (Shamus: N.B. it does no such thing ATM) - if (DoSymbol(otemp)) + // [Only used here, once] + if (DoSymbols(otemp)) return NULL; if (otemp->o_flags & O_ARCHIVE) @@ -1696,12 +1716,12 @@ struct OHEADER * make_ofile() // Fill in the output header. Does not match the actual output but values // used as reference - header->magic = 0x0150; // COF magic number - header->tsize = textsize; // TEXT segment size - header->dsize = datasize; // DATA segment size - header->bsize = bsssize; // BSS segment size - header->ssize = (ost_ptr - ost); // Symbol table size - header->ostbase = ost; // Output symbol table base address + header->magic = 0x0150; // COF magic number + header->tsize = textsize; // TEXT segment size + header->dsize = datasize; // DATA segment size + header->bsize = bsssize; // BSS segment size + header->ssize = (ost_ptr - ost); // Symbol table size + header->ostbase = ost; // Output symbol table base address // For each object file, relocate its TEXT and DATA segments. OR the result // into ret so all files get moved (and errors reported) before returning @@ -1820,9 +1840,9 @@ int AddARSymbol(char * sym, struct OFILE * ofile) int GetHash(char * s) { // For this to be consistent, the symbol MUST be zeroed out beforehand! - char c[SYMLEN]; - memset(c, 0, SYMLEN); - strcpy(c, s); + // N.B.: strncpy() pads zeroes for us, if the symbol is less than 15 chars. + char c[15]; + strncpy(c, s, 15); int i = (c[0] + c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10] + c[11] + c[12] + c[13] + c[14]) % NBUCKETS; @@ -1874,86 +1894,6 @@ struct HREC * LookupARHREC(char * symbol) } -// -// Add symbol to the hash table if it doesn't already exist, otherwise decide -// what to do since it's already defined in another unit. -// -int DealWithSymbol(char * sym, long type, long value, struct OFILE * ofile) -{ - if (vflag > 1) - { - printf("DealWithSymbol(%s,%s,%lx,", sym, ofile->o_name, value); - printf("%x,%s)\n", (unsigned int)type, (isglobal(type) ? "GLOBAL" : "COMMON")); - } - - struct HREC * hptr = LookupHREC(sym); - - if (hptr == NULL) - return AddSymbolToHashList(&htable[GetHash(sym)], sym, ofile, value, type); - - // Symbol is already in table... Figure out how to handle! - if (iscommon(type) && !iscommon(hptr->h_type)) - { - // Mismatch: global came first; warn and keep the global one - if (wflag) - { - printf("Warning: %s: global from ", sym); - put_name(hptr->h_ofile); - printf(" used, common from "); - put_name(ofile); - printf(" discarded.\n"); - } - - putword(sym + 8, ABST_EXTERN); - putlong(sym + 10, 0L); - } - else if (iscommon(hptr->h_type) && !iscommon(type)) - { - // Mismatch: common came first; warn and keep the global one - if (wflag) - { - printf("Warning: %s: global from ", sym); - put_name(ofile); - printf(" used, common from "); - put_name(hptr->h_ofile); - printf(" discarded.\n"); - } - - hptr->h_type = type; - hptr->h_ofile = ofile; - hptr->h_value = value; - } - // They're both global [WRONG! Passed in one is global] -// else if (!iscommon(type)) -//is this now right?? - else if (!iscommon(type) && !iscommon(hptr->h_type)) - { - // Global exported by another ofile; warn and make this one extern - if (wflag) - { - printf("Duplicate symbol %s: ", sym); - put_name(hptr->h_ofile); - printf(" used, "); - put_name(ofile); - printf(" discarded\n"); - } - - putword(sym + 8, ABST_EXTERN); - } - // They're both common - else - { - if (hptr->h_value < value) - { - hptr->h_value = value; - hptr->h_ofile = ofile; - } - } - - return 0; -} - - // // Add the imported symbols from this file to unresolved, and the global and // common (???) symbols to the exported hash table. @@ -1964,7 +1904,6 @@ int DealWithSymbol(char * sym, long type, long value, struct OFILE * ofile) int AddSymbols(struct OFILE * Ofile) { struct HREC * hptr; // Hash record pointer - char symbol[SYMLEN]; if (vflag > 1) printf("Add symbols for file %s\n", Ofile->o_name); @@ -1984,31 +1923,88 @@ int AddSymbols(struct OFILE * Ofile) long index = getlong(sfix); // Get symbol string index long type = getlong(sfix + 4); // Get symbol type long value = getlong(sfix + 8); // Get symbol value - memset(symbol, 0, SYMLEN); - strcpy(symbol, sstr + index); if ((Ofile->isArchiveFile) && !(Ofile->o_flags & O_USED)) { if ((type & T_EXT) && (type & (T_SEG | T_ABS))) - if (AddARSymbol(symbol, Ofile)) + if (AddARSymbol(sstr + index, Ofile)) return 1; } else if (type == T_EXT) { - // External symbal that is *not* in the current unit - hptr = LookupHREC(symbol); + // External symbol that is *not* in the current unit + hptr = LookupHREC(sstr + index); if (hptr != NULL) hptr->h_ofile->o_flags |= O_USED; // Mark .o file as used // Otherwise add to unresolved list - else if (AddUnresolvedSymbol(symbol, Ofile)) - return 1; // Error if addition failed + else + { + // Check for built-in externals... + if ((strcmp(sstr + index, "_TEXT_E") != 0) + && (strcmp(sstr + index, "_DATA_E") != 0) + && (strcmp(sstr + index, "_BSS_E") != 0)) + { + if (AddUnresolvedSymbol(sstr + index, Ofile)) + return 1; // Error if addition failed + } + } } else if ((type & T_EXT) && (type & (T_SEG | T_ABS))) { +#if 0 // Symbol in the current unit that is also EXPORTED - if (DealWithSymbol(symbol, type, value, Ofile)) + if (DealWithSymbol(sstr + index, type, value, Ofile)) return 1; // Error if addition failed +#else + hptr = LookupHREC(sstr + index); + + // Symbol isn't in the table, so try to add it: + if (hptr == NULL) + { + if (AddSymbolToHashList(&htable[GetHash(sstr + index)], + sstr + index, Ofile, value, type)) + return 1; + } + else + { + // Symbol already exists, decide what to do about it + if (iscommon(hptr->h_type)) + { + // Mismatch: common came first; warn and keep the global + if (wflag) + { + printf("Warning: %s: global from ", sstr + index); + put_name(Ofile); + printf(" used, common from "); + put_name(hptr->h_ofile); + printf(" discarded.\n"); + } + + hptr->h_ofile = Ofile; + hptr->h_type = type; + hptr->h_value = value; + } + else + { + // Global exported by another ofile; warn and make this one + // extern + if (wflag) + { + printf("Duplicate symbol %s: ", sstr + index); + put_name(hptr->h_ofile); + printf(" used, "); + put_name(Ofile); + printf(" discarded\n"); + } + + // Set the global in this unit to pure external + // (is this a good idea? what if the other one is a ref to + // this one???) + putlong(sfix + 4, T_EXT); + } + } +#endif } sfix += 12; // Increment symbol fixup pointer @@ -2213,6 +2209,7 @@ int ProcessLists(void) // char * path_tail(char * name) { + // Find last occurance of PATH_DELIMETER char * temp = strrchr(name, PATH_DELIMITER); // Return what was passed in if path delimiter was not found @@ -2290,20 +2287,15 @@ int AddToProcessingList(char * ptr, char * fname, char * arname, uint8_t arFile) // int LoadInclude(char * fname, int handle, char * sym1, char * sym2, int segment) { - long fsize, dsize, size; // File, DATA segment and image sizes - char * ptr, * sptr; // Data pointers - int i; // Iterators - int sym1len = 0; // Symbol 1 length - int sym2len = 0; // Symbol 2 length + char * ptr, * sptr; + int i; unsigned symtype = 0; - fsize = FileSize(handle); // Get size of include file - dsize = (fsize + secalign) & ~secalign; // Round up to a alignment boundary - - sym1len = strlen(sym1) + 1; // Get sym1 length + null termination - sym2len = strlen(sym2) + 1; // Get sym2 length + null termination - - size = 32 + dsize + 24 + 4 + sym1len + sym2len + 4; + long fsize = FileSize(handle); // Get size of include file + long dsize = (fsize + secalign) & ~secalign; // Align size to boundary + int sym1len = strlen(sym1) + 1; // Get sym1 length + null termination + int sym2len = strlen(sym2) + 1; // Get sym2 length + null termination + long size = 32 + dsize + 24 + 4 + sym1len + sym2len + 4; // Use calloc so the header & fixups initialize to zero // Allocate object image memory @@ -2542,6 +2534,13 @@ int LoadArchive(char * fname, int fd) } else if (HasDotOSuffix(objName)) { + + // Strip off any trailing forward slash at end of object name + int lastChar = strlen(objName) - 1; + + if (objName[lastChar] == '/') + objName[lastChar] = 0; + //printf("Processing object \"%s\" (size == %i, obj_index == %i)...\n", objName, atoi(objSize), obj_index); strcpy(obj_fname[obj_index], objName); obj_segsize[obj_index][0] = (getlong(ptr + 60 + 4) + secalign) & ~secalign; @@ -2590,8 +2589,8 @@ int ProcessFiles(void) lseek(handle[i], 0L, 0); // Reset to start of input file - // Look for RMAC/MAC/GCC ($20107) object files - if ((getlong(magic) == 0x00000107) || (getlong(magic) == 0x00020107)) + // Look for RMAC/MAC/GCC (a.out) object files + if ((getlong(magic) & 0xFFFF) == 0x0107) { // Process input object file if (LoadObject(name[i], handle[i], 0L)) @@ -2607,6 +2606,7 @@ int ProcessFiles(void) { // Close file and error printf("%s is not a supported object or archive file\n", name[i]); + printf("Magic == [%02X][%02X][%02X][%02X]\n", magic[0], magic[1], magic[2], magic[3]); close(handle[i]); return 1; } @@ -2830,10 +2830,9 @@ int doargs(int argc, char * argv[]) } aflag = 1; // Set abs link flag - // Segment order is TEXT, DATA, BSS - // Text segment can be 'r', 'x' or a value - ttype = 0; + // Segment order is TEXT, DATA, BSS + // Text segment can be 'r' or a value if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) { ttype = -1; // TEXT segment is relocatable @@ -2843,16 +2842,15 @@ int doargs(int argc, char * argv[]) printf("Error in text-segment address: cannot be contiguous\n"); return 1; } - else if ((ttype = 0), GetHexValue(argv[i], &tval)) + else if (GetHexValue(argv[i], &tval)) { - printf("Error in text-segment address: %s is not 'r', 'x' or an address.", argv[i]); + printf("Error in text-segment address: %s is not 'r' or an address.", argv[i]); return 1; } i++; - // Data segment can be 'r', 'x' or a value - dtype = 0; + // Data segment can be 'r', 'x' or a value if ((*argv[i] == 'r' || *argv[i] == 'R') && !argv[i][1]) { dtype = -1; // DATA segment is relocatable @@ -2861,14 +2859,13 @@ int doargs(int argc, char * argv[]) { dtype = -2; // DATA follows TEXT } - else if ((dtype = 0), GetHexValue(argv[i], &dval)) + else if (GetHexValue(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]) @@ -2879,7 +2876,7 @@ int doargs(int argc, char * argv[]) { btype = -3; // BSS follows DATA } - else if ((btype = 0), GetHexValue(argv[i], &bval)) + else if (GetHexValue(argv[i], &bval)) { printf("Error in bss-segment address: %s is not 'r', 'x[td]', or an address.", argv[i]); return 1; @@ -3025,6 +3022,10 @@ int doargs(int argc, char * argv[]) sflag = 1; break; + case 'u': + case 'U': // Undefined symbols + uflag++; + break; case 'v': case 'V': // Verbose information if (!vflag && !versflag) @@ -3123,6 +3124,7 @@ void display_help(void) printf(" d: double phrase (16 bytes)\n"); printf(" q: quad phrase (32 bytes)\n"); printf(" -s output only global symbols\n"); + printf(" -u allow unresolved symbols (experimental)\n"); printf(" -v set verbose mode\n"); printf(" -w show linker warnings\n"); printf(" -z suppress banner\n"); @@ -3136,6 +3138,7 @@ void display_help(void) void rln_exit(void) { char tempbuf[128]; + char * c; // Display link status if verbose mode if (vflag) @@ -3145,7 +3148,7 @@ void rln_exit(void) if (waitflag) { printf("\nPress the [RETURN] key to continue. "); - fgets(tempbuf, 128, stdin); + c = fgets(tempbuf, 128, stdin); } exit(errflag); @@ -3183,6 +3186,10 @@ int main(int argc, char * argv[]) if (s) // Attempt to obtain env variable strcpy(libdir, s); // Store it if found + // Initialize some vars + tval = dval = bval = 0; + ttype = dtype = btype = 0; + // Parse the command line if (doargs(argc, argv)) {