Add NewDebugSymbol(): stabs symbol factory

This function, currently unused, generates a stabs
debugging symbol, as documented here:

https://sourceware.org/gdb/onlinedocs/stabs.html

It can be used to process stabs directives, also
documented at the above URL, generated by HLL
compilers such as GCC, as well as to generate line
number and file name debug symbols when assembling
hand-coded assembly files with the -g option.

v2:
-Don't double-init stabs symbol fields
-Consistently use tabs, not spaces
This commit is contained in:
James Jones 2022-07-17 23:20:21 -07:00 committed by Shamus Hammons
parent 3bdb75018b
commit e8f9d55bc7
4 changed files with 85 additions and 24 deletions

View File

@ -180,29 +180,49 @@ _________________________________________________
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;
}
// 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)
else
{
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
}
// Translate rmac symbol attributes to an a.out symbol type.
if (w1 & EQUATED)
{
z = 0x02000000; // Set equated flag
}
if (globflag)
z |= 0x01000000; // Set global flag if requested
// 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
}
if (globflag)
z |= 0x01000000; // Set global flag if requested
}
D_long(z); // Deposit symbol attribute
z = sym->svalue; // Obtain symbol value
@ -214,8 +234,11 @@ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
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

1
rmac.h
View File

@ -222,6 +222,7 @@ PTR
#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

View File

@ -88,7 +88,7 @@ SYM * NewSymbol(uint8_t * name, int type, int envno)
}
// 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!
@ -99,14 +99,22 @@ SYM * NewSymbol(uint8_t * name, int type, int envno)
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)
@ -235,7 +243,16 @@ uint32_t AssignSymbolNos(uint8_t * buf, uint8_t *(* construct)())
// 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;
@ -547,3 +564,19 @@ int symtable(void)
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;
}

View File

@ -37,6 +37,9 @@ SYM
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
@ -54,6 +57,7 @@ uint32_t AssignSymbolNos(uint8_t *, uint8_t *(*)());
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__