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
int type;
long value;
int index;
+ char *string;
int j;
struct HREC * hptr;
uint32_t tsoSave, dsoSave, bsoSave;
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
// 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
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);
}
}
}
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;
}
}
//
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;
}
int OSTLookup(char * sym)
{
int i;
- int stro = 4; // Offset in string table
for(i=0; i<ost_index; i++)
{
- if (strcmp(oststr + stro, sym) == 0)
+ if (ost[i].s_idx && (strcmp(oststr + ost[i].s_idx, sym) == 0))
return i + 1;
-
- stro += strlen(oststr + stro) + 1;
}
return -1;
strcpy(sym, symbols + symidx);
olddata = newdata = 0; // Initialise old and new segment data
ssidx = OSTLookup(sym);
- newdata = GetLong(ost + ((ssidx - 1) * 12) + 8);
+ newdata = ost[ssidx - 1].s_value;
}
// Obtain the existing long word (or word) segment data and flip words
int i, j; // Iterators
char himage[0x168]; // Header image (COF = 0xA8)
uint32_t tsoff, dsoff, bsoff; // Segment offset values
- unsigned index, type, value; // Symbol table index, type and value
short abstype; // ABS symbol type
- char symbol[14]; // Symbol record for ABS files
- int slen; // Symbol string length
+ char symbol[14]; // raw symbol record
symoffset = 0; // Initialise symbol offset
{
if (header->ssize)
{
- 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;
{
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; j<slen; j++)
- *(symbol + j) = *(oststr + index + j);
- }
+ strncpy(symbol, oststr + ost[i].s_idx, 8);
// Modify to ABS symbol type
- switch (type)
+ switch (ost[i].s_type)
{
case 0x02000000: abstype = (short)ABST_DEFINED; break;
case 0x04000000: abstype = (short)ABST_DEFINED | ABST_TEXT; break;
case 0x08000000: abstype = (short)ABST_DEFINED | ABST_BSS; break;
case 0x09000000: abstype = (short)ABST_DEFINED | ABST_GLOBAL | ABST_BSS; break;
default:
- printf("warning (WriteOutputFile): ABS, cannot determine symbol type ($%08X) [%s]\n", type, symbol);
+ printf("warning (WriteOutputFile): ABS, cannot determine symbol type ($%08X) [%s]\n", ost[i].s_type, symbol);
// type = 0;
break;
}
- PutWord(symbol + 8, abstype); // Write back new ABS type
- PutLong(symbol + 10, value); // Write back value
+ PutWord(symbol + 8, abstype); // Write back new ABS type
+ PutLong(symbol + 10, ost[i].s_value); // Write back value
// Write symbol record
if (fwrite(symbol, 14, 1, fd) != 1)
// Inner loop to process each record in the symbol table
for(i=0; i<(unsigned)ost_index; i++)
{
- index = GetLong(ost + (i * 12)); // Get symbol string index
- type = GetLong(ost + (i * 12) + 4); // Get symbol type
- value = GetLong(ost + (i * 12) + 8); // Get symbol value
- symbol = oststr + index; // Get symbol string
+ index = ost[i].s_idx; // Get symbol string index
+ type = ost[i].s_type; // Get symbol type
+ value = ost[i].s_value; // Get symbol value
+ symbol = index ? oststr + index : ""; // Get symbol string
// Display only three columns
if (c == 3)
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->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