X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rln;a=blobdiff_plain;f=rln.c;fp=rln.c;h=4ae8d4435f75b6799ff9b9d59a2d609818735f22;hp=4a83410238337b3669ce8178ec012e56c7913d21;hb=0d71dcf00270f75a7692c788e2834e47231780ef;hpb=a63bf6807773cdcf9d5660bab8e0bc97645cf8b1 diff --git a/rln.c b/rln.c index 4a83410..4ae8d44 100644 --- a/rln.c +++ b/rln.c @@ -55,13 +55,12 @@ char * arPtr[512]; uint32_t arIndex = 0; struct HREC * htable[NBUCKETS]; // Hash table struct HREC * unresolved = NULL; // Pointer to unresolved hash list -char * ost; // Output symbol table -char * ost_ptr; // Output symbol table; current pointer -char * ost_end; // Output symbol table; end pointer -char * oststr; // Output string table -char * oststr_ptr; // Output string table; current pointer -char * oststr_end; // Output string table; end pointer -int ost_index = 0; // Index of next ost addition +struct SYMREC * ost; // Output symbol table +char * oststr = NULL; // Output string table +char * oststr_ptr = NULL; // Output string table; current pointer +char * oststr_end = NULL; // Output string table; end pointer +int ost_index = 0; // Index of next free ost entry +int ost_size = 0; // Size of ost uint8_t nullStr[1] = "\x00"; // Empty string struct HREC * arSymbol = NULL; // Pointer to AR symbol table @@ -139,6 +138,7 @@ int DoSymbols(struct OFILE * ofile) int type; long value; int index; + char *string; int j; struct HREC * hptr; uint32_t tsoSave, dsoSave, bsoSave; @@ -166,6 +166,7 @@ int DoSymbols(struct OFILE * ofile) index = GetLong(symptr + 0); // Obtain symbol string index type = GetLong(symptr + 4); // Obtain symbol type value = GetLong(symptr + 8); // Obtain symbol value + string = index ? symend + index : ""; // Global/External symbols have a pre-processing stage // N.B.: This destroys the t/d/bsegoffset discovered above. So if a @@ -176,21 +177,21 @@ int DoSymbols(struct OFILE * ofile) // Obtain the string table index for the relocation symbol, look // for it in the globals hash table to obtain information on that // symbol. - hptr = LookupHREC(symend + index); + hptr = LookupHREC(string); if (hptr == NULL) { // Try to find it in the OST - int ostIndex = OSTLookup(symend + index); + int ostIndex = OSTLookup(string); if (ostIndex == -1) { - printf("DoSymbols(): Symbol not found in hash table: '%s' (%s)\n", symend + index, ofile->o_name); + printf("DoSymbols(): Symbol not found in hash table: '%s' (%s)\n", string, ofile->o_name); return 1; } if (vflag > 1) - printf("DoSymbols(): Skipping symbol '%s' (%s) found in OST...\n", symend + index, ofile->o_name); + printf("DoSymbols(): Skipping symbol '%s' (%s) found in OST...\n", string, ofile->o_name); // 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 @@ -230,7 +231,7 @@ int DoSymbols(struct OFILE * ofile) break; default: if (vflag > 1) - printf("DoSymbols: No adjustment made for symbol: %s (%s) = %X\n", symend + index, ofile->o_name, hptr->h_value); + printf("DoSymbols: No adjustment made for symbol: %s (%s) = %X\n", string, ofile->o_name, hptr->h_value); } } } @@ -311,13 +312,13 @@ int DoSymbols(struct OFILE * ofile) if (isglobal(type) || lflag) { if (vflag > 1) - printf("DoSymbols: Adding symbol: %s (%s) to OST...\n", symend + index, ofile->o_name); + printf("DoSymbols: Adding symbol: %s (%s) to OST...\n", string, ofile->o_name); - index = OSTAdd(symend + index, type, value); + index = OSTAdd(index ? string : NULL, type, value); if (index == -1) { - printf("DoSymbols(): Failed to add symbol '%s' to OST!\n", symend + index); + printf("DoSymbols(): Failed to add symbol '%s' to OST!\n", string); return 1; } } @@ -394,127 +395,102 @@ long DoCommon(void) // int OSTAdd(char * name, int type, long value) { - int ost_offset_p, ost_offset_e = 0; // OST table offsets for position calcs + int ost_offset_p = 0, ost_offset_e; // OST table offsets for position calcs int ostresult; // OST index result - int slen = strlen(name); + int slen; // String length, including terminator - // If the OST or OST string table has not been initialised then do so - if (ost_index == 0) + // If this is a debug symbol and the include debug symbol flag (-g) is not + // set then do nothing + if ((type & 0xF0000000) && !gflag) { - ost = malloc(OST_BLOCK); - oststr = malloc(OST_BLOCK); - - if (ost == NULL) - { - printf("OST memory allocation error.\n"); - return -1; - } + // Do nothing + return 0; + } - if (oststr == NULL) - { - printf("OSTSTR memory allocation error.\n"); - return -1; - } + if (!name || !name[0]) + slen = 0; + else + slen = strlen(name) + 1; - ost_ptr = ost; // Set OST start pointer - ost_end = ost + OST_BLOCK; // Set OST end pointer + // Get symbol index in OST, if any (-1 if not found) + ostresult = slen ? OSTLookup(name) : -1; - 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 - oststr_end = oststr + OST_BLOCK; + // 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 gflag (output debug symbols) is + // set and this a debug symbol, *** OR *** the symbol is not in the + // output symbol table then add it. + if ((ostresult != -1) && !(bflag && !(type & 0x01000000)) + && !(gflag && (type & 0xF0000000))) + { + return ostresult; } - else + + // If the OST has not been initialised, or more space is needed, then + // allocate it. + if ((ost_index + 1) > ost_size) { - // If next symbol record exceeds current allocation then expand symbol - // table and/or symbol string table. - ost_offset_p = (ost_ptr - ost); - ost_offset_e = (ost_end - ost); + if (ost_size == 0) + ost_size = OST_SIZE_INIT; - // 3 x uint32_t (12 bytes) - if ((ost_ptr + 12) > ost_end) - { - // We want to allocate the current size of the OST + another block. - ost = realloc(ost, ost_offset_e + OST_BLOCK); + ost_size *= 2; - if (ost == NULL) - { - printf("OST memory reallocation error.\n"); - return -1; - } + ost = realloc(ost, ost_size * sizeof(ost[0])); - ost_ptr = ost + ost_offset_p; - ost_end = (ost + ost_offset_e) + OST_BLOCK; + if (ost == NULL) + { + printf("OST memory allocation error.\n"); + return -1; } + } + if (slen) + { 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) + // If the OST data has been exhausted, allocate another chunk. + if (((oststr_ptr + slen + 4) > oststr_end)) { - oststr = realloc(oststr, ost_offset_e + OST_BLOCK); - - if (oststr == NULL) + // string length + terminating NULL + uint32_t (terminal long) + if ((oststr_ptr + (slen + 1 + 4)) > oststr_end) { - printf("OSTSTR memory reallocation error.\n"); - return -1; - } + oststr = realloc(oststr, ost_offset_e + OST_BLOCK); - oststr_ptr = oststr + ost_offset_p; - oststr_end = (oststr + ost_offset_e) + OST_BLOCK; - } - } - - // 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 - return 0; - } + if (oststr == NULL) + { + printf("OSTSTR memory reallocation error.\n"); + return -1; + } - // Get symbol index in OST, if any (-1 if not found) - ostresult = OSTLookup(name); + oststr_ptr = oststr + ost_offset_p; + oststr_end = (oststr + ost_offset_e) + OST_BLOCK; - // 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 + // On the first alloc, reserve space for the string table + // size field. + if (ost_offset_e == 0) + oststr_ptr += 4; + } + } - PutLong(ost_ptr + 4, type); - PutLong(ost_ptr + 8, value); - ost_ptr += 12; + strcpy(oststr_ptr, name); // Put symbol name in string table + oststr_ptr += slen; + oststr_ptr[-1] = '\0'; // Add null terminating character + PutLong(oststr_ptr, 0x00000000); // Null terminating long + PutLong(oststr, (oststr_ptr - oststr)); // Update size of 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 - *(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 - } + ostresult = ost_index++; - if (vflag > 1) - printf("OSTAdd: (%s), type=$%08X, val=$%08lX\n", name, type, value); + ost[ostresult].s_idx = ost_offset_p; + ost[ostresult].s_type = type; + ost[ostresult].s_value = 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; - } + if (vflag > 1) + printf("OSTAdd: (%s), type=$%08X, val=$%08lX\n", + slen ? name : "", type, value); - return ostresult; + return ost_index; } @@ -525,14 +501,11 @@ int OSTAdd(char * name, int type, long value) int OSTLookup(char * sym) { int i; - int stro = 4; // Offset in string table for(i=0; issize) { - if (fwrite(ost, (ost_ptr - ost), 1, fd) != 1) - goto werror; + for (i = 0; i < ost_index; i++) + { + PutLong(symbol, ost[i].s_idx); + PutLong(symbol + 4, ost[i].s_type); + PutLong(symbol + 8, ost[i].s_value); + + if (fwrite(symbol, 12, 1, fd) != 1) + goto werror; + } if (fwrite(oststr, (oststr_ptr - oststr), 1, fd) != 1) goto werror; @@ -1288,32 +1266,16 @@ int WriteOutputFile(struct OHEADER * header) { memset(symbol, 0, 14); // Initialise symbol record abstype = 0; // Initialise ABS symbol type - slen = 0; // Initialise symbol string length - index = GetLong(ost + (i * 12)); // Get symbol index - type = GetLong((ost + (i * 12)) + 4); // Get symbol type // Skip debug symbols - if (type & 0xF0000000) + if (ost[i].s_type & 0xF0000000) continue; - // Get symbol value - value = GetLong((ost + (i * 12)) + 8); - slen = strlen(oststr + index); - // Get symbol string (maximum 8 chars) - if (slen > 8) - { - for(j=0; j<8; j++) - *(symbol + j) = *(oststr + index + j); - } - else - { - for(j=0; jtsize = 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->ssize = ost_index * 12; // Symbol table size + header->ostbase = NULL; // 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