uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
{
chptr = buf; // Point to buffer for depositing longs
- D_long(strindx); // Deposit the symbol string index
+ if (sym->sname)
+ {
+ D_long(strindx); // Deposit the symbol string index
+ }
+ else
+ {
+ D_long(0); // Deposit special NULL string index
+ }
uint16_t w1 = sym->sattr; // Obtain symbol attributes
uint32_t z = 0; // Initialize resulting symbol flags
- if (w1 & EQUATED)
+ if (sym->stype == DBGSYM)
{
- z = 0x02000000; // Set equated flag
+ // Debug symbols hard-code the a.out symbol type in the st_type field
+ // and can include additional type-specific data in the a.out symbol
+ // "other" and "description" fields, both packed into this same dword.
+ z = sym->st_type << 24;
+ z |= sym->st_other << 16;
+ z |= sym->st_desc;
}
+ else
+ {
+ // Translate rmac symbol attributes to an a.out symbol type.
+ if (w1 & EQUATED)
+ {
+ z = 0x02000000; // Set equated flag
+ }
- // If a symbol is both EQUd and flagged as TBD then we let the latter take
- // precedence. Otherwise the linker will not even bother trying to relocate
- // the address during link time.
+ // If a symbol is both EQUd and flagged as TBD then we let the latter
+ // take precedence. Otherwise the linker will not even bother trying to
+ // relocate the address during link time.
- switch (w1 & TDB)
- {
- case TEXT: z = 0x04000000; break; // Set TEXT segment flag
- case DATA: z = 0x06000000; break; // Set DATA segment flag
- case BSS : z = 0x08000000; break; // Set BSS segment flag
- }
+ switch (w1 & TDB)
+ {
+ case TEXT: z = 0x04000000; break; // Set TEXT segment flag
+ case DATA: z = 0x06000000; break; // Set DATA segment flag
+ case BSS : z = 0x08000000; break; // Set BSS segment flag
+ }
- if (globflag)
- z |= 0x01000000; // Set global flag if requested
+ if (globflag)
+ z |= 0x01000000; // Set global flag if requested
+ }
D_long(z); // Deposit symbol attribute
z = sym->svalue; // Obtain symbol value
z += sect[DATA].sloc; // If BSS add DATA segment size
D_long(z); // Deposit symbol value
- strcpy(strtable + strindx, sym->sname);
- strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate
+ if (sym->sname)
+ {
+ strcpy(strtable + strindx, sym->sname);
+ strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate
+ }
buf += 12; // Increment buffer to next record
symsize += 12; // Increment symbol table size
#define LABEL 0 // User-defined symbol
#define MACRO 1 // Macro definition
#define MACARG 2 // Macro argument
+#define DBGSYM 3 // stabs debug symbol
#define SY_UNDEF -1 // Undefined (lookup never matches it)
// Symbol and expression attributes
}
// Fill-in the symbol
- symbol->sname = strdup(name);
+ symbol->sname = name ? strdup(name) : NULL;
symbol->stype = (uint8_t)type;
symbol->senv = (uint16_t)envno;
// We don't set this as DEFINED, as it could be a forward reference!
symbol->svalue = 0;
symbol->sorder = NULL;
symbol->uid = currentUID++;
+ // We don't set st_type, st_desc, or st_other here because they are only
+ // used by stabs debug symbols, which are always initialized by
+ // NewDebugSymbol(), which always sets these fields. Hence, initializing
+ // them here would be redundant.
- // Record filename the symbol is defined (for now only used by macro error reporting)
+ // Record filename the symbol is defined (Used by macro error reporting and some debug symbols)
symbol->cfileno = cfileno;
- // Install symbol in the symbol table
- int hash = HashSymbol(name, envno);
- symbol->snext = symbolTable[hash];
- symbolTable[hash] = symbol;
+ // Don't hash debug symbols: they are never looked up and may have no name.
+ if (type != DBGSYM)
+ {
+ // Install symbol in the symbol table
+ int hash = HashSymbol(name, envno);
+ symbol->snext = symbolTable[hash];
+ symbolTable[hash] = symbol;
+ }
// Append symbol to the symbol-order list
if (sorder == NULL)
// them. We also pick which symbols should be global or not here.
for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
{
- // Skip non-labels
+ // Always export debug symbols. Don't force them global.
+ if (DBGSYM == sy->stype) {
+ sy->senv = scount++;
+
+ if (buf != NULL)
+ buf = construct(buf, sy, 0);
+ continue;
+ }
+
+ // Skip non-labels.
if (sy->stype != LABEL)
continue;
return 0;
}
+
+SYM * NewDebugSymbol(uint8_t * str, uint8_t type, uint8_t other, uint16_t desc)
+{
+ SYM * symbol = NewSymbol(str, DBGSYM, 0);
+
+ if (NULL == symbol)
+ return NULL;
+
+ AddToSymbolDeclarationList(symbol);
+
+ symbol->st_type = type;
+ symbol->st_other = other;
+ symbol->st_desc = desc;
+
+ return symbol;
+}
LLIST * last; // * -> end of macro linked list
uint16_t cfileno; // File the macro is defined in
uint32_t uid; // Symbol's unique ID
+ uint8_t st_type; // stabs debug symbol's "type" field
+ uint8_t st_other; // stabs debug symbol's "other" field
+ uint16_t st_desc; // stabs debug symbol's "description" field
};
// Exported variables
uint32_t AssignSymbolNosELF(uint8_t *, uint8_t *(*)());
void DumpLODSymbols(void);
uint8_t * GetSymbolNameByUID(uint32_t);
+SYM * NewDebugSymbol(uint8_t *, uint8_t, uint8_t, uint16_t);
#endif // __SYMBOL_H__