]> Shamusworld >> Repos - rmac/commitdiff
Add NewDebugSymbol(): stabs symbol factory
authorJames Jones <atari@theinnocuous.com>
Mon, 18 Jul 2022 06:20:21 +0000 (23:20 -0700)
committerShamus Hammons <jlhamm@acm.org>
Tue, 16 Aug 2022 02:08:06 +0000 (21:08 -0500)
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

object.c
rmac.h
symbol.c
symbol.h

index 31690ae17f85fa57183cc05527e99eeafd12d02e..78c225fdd1e0e23e6f43d96dd961cecae3c497a5 100644 (file)
--- 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 0dd9865a512eac30789696a682d94b2684c60c60..39f908e0710c05232870140f7c2748c3e2b172fc 100644 (file)
--- 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
index 0a50eeb6c34c77ca39db4371e50fa171fcae7c24..490d4f077fb388ae5c1508fb4454a505846b7f72 100644 (file)
--- 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,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;
+}
index 1a27a6b02736f42a52abe311461bcc1242a4d48a..c10d71b189f080c64c14541f66806959566510b7 100644 (file)
--- 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__