From 5a747783ce25605a562c9a43cda92fb51478ac74 Mon Sep 17 00:00:00 2001 From: James Jones Date: Sun, 17 Jul 2022 23:20:21 -0700 Subject: [PATCH 1/2] 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. --- object.c | 55 +++++++++++++++++++++++++++++++++++++++---------------- rmac.h | 1 + symbol.c | 46 +++++++++++++++++++++++++++++++++++++++------- symbol.h | 4 ++++ 4 files changed, 83 insertions(+), 23 deletions(-) diff --git a/object.c b/object.c index 31690ae..ddc0187 100644 --- a/object.c +++ b/object.c @@ -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; } + 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 @@ -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 diff --git a/rmac.h b/rmac.h index 0dd9865..39f908e 100644 --- a/rmac.h +++ b/rmac.h @@ -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 diff --git a/symbol.c b/symbol.c index 0a50eeb..3b6e906 100644 --- a/symbol.c +++ b/symbol.c @@ -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,21 @@ SYM * NewSymbol(uint8_t * name, int type, int envno) symbol->svalue = 0; symbol->sorder = NULL; symbol->uid = currentUID++; + // st_desc and st_other are only used by stabs debug symbols + symbol->st_desc = 0; + symbol->st_other = 0; - // 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 +242,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 +563,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; +} diff --git a/symbol.h b/symbol.h index 1a27a6b..c10d71b 100644 --- a/symbol.h +++ b/symbol.h @@ -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__ -- 2.34.1