]> Shamusworld >> Repos - rmac/blobdiff - symbol.c
Support -g debug info generation
[rmac] / symbol.c
index 490d4f077fb388ae5c1508fb4454a505846b7f72..c9c34a4f6c729f34bedb94cc9ecf8204befe2a19 100644 (file)
--- a/symbol.c
+++ b/symbol.c
@@ -58,7 +58,7 @@ void InitSymbolTable(void)
 //
 // Hash the ASCII name and enviroment number
 //
-int HashSymbol(uint8_t * name, int envno)
+int HashSymbol(const uint8_t * name, int envno)
 {
        int sum = envno, k = 0;
 
@@ -76,7 +76,7 @@ int HashSymbol(uint8_t * name, int envno)
 //
 // Make a new symbol of type 'type' in enviroment 'envno'
 //
-SYM * NewSymbol(uint8_t * name, int type, int envno)
+SYM * NewSymbol(const uint8_t * name, int type, int envno)
 {
        // Allocate the symbol
        SYM * symbol = malloc(sizeof(SYM));
@@ -565,12 +565,12 @@ int symtable(void)
        return 0;
 }
 
-SYM * NewDebugSymbol(uint8_t * str, uint8_t type, uint8_t other, uint16_t desc)
+SYM * NewDebugSymbol(const uint8_t * str, uint8_t type, uint8_t other, uint16_t desc)
 {
        SYM * symbol = NewSymbol(str, DBGSYM, 0);
 
        if (NULL == symbol)
-               return NULL;
+               fatal("Could not allocate space for debug symbol");
 
        AddToSymbolDeclarationList(symbol);
 
@@ -580,3 +580,101 @@ SYM * NewDebugSymbol(uint8_t * str, uint8_t type, uint8_t other, uint16_t desc)
 
        return symbol;
 }
+
+char *FilePath(const char * fname)
+{
+       char buf1[256];
+       char * fpath;
+       int i, j;
+
+       if ((fpath = realpath(fname, NULL)) != NULL)
+               return fpath;
+
+       for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++)
+       {
+               j = strlen(buf1);
+
+               // Append path char if necessary
+               if (j > 0 && buf1[j - 1] != SLASHCHAR)
+                       strcat(buf1, SLASHSTRING);
+
+               strcat(buf1, fname);
+
+               if ((fpath = realpath(buf1, NULL)) != NULL)
+                       return fpath;
+       }
+
+       return NULL;
+}
+
+static void GenFileSym(const char * fname, uint8_t type, uint32_t addr, uint32_t sattr)
+{
+       char *fpath;
+
+       if (!(fpath = FilePath(fname)))
+       {
+               // Don't treat this as an error. Any file rmac can read is valid enough.
+               // Just use the relative filename in place of an absolute path for the
+               // debug information.
+               fpath = strdup(fname);
+
+               if (!fpath)
+                       fatal("Could not allocate memory for fake path name");
+       }
+
+       SYM * symbol = NewDebugSymbol(fpath, type, 0, 0);
+
+       free(fpath);
+
+       symbol->svalue = addr;
+       symbol->sattr |= sattr;
+}
+
+void GenMainFileSym(const char * fname)
+{
+       GenFileSym(fname, 0x64 /* N_SO */, 0, DEFINED | TEXT);
+}
+
+void GenLineNoSym(void)
+{
+       uint32_t addr;
+       uint32_t sattr;
+       uint8_t type;
+       SYM * symbol;
+
+       static uint16_t prevlineno = -1;
+       static uint32_t prevaddr = -1;
+       static uint16_t prevfileno = 0;
+
+       if (orgactive)
+       {
+               addr = orgaddr;
+               sattr = ABS | DEFINED | EQUATED;
+               // 0x4c is N_FLINE, function start/body/end line number, repurposed by
+               // MADMAC/ALN for ABS line numbers.
+               type = 0x4c;
+       }
+       else
+       {
+               addr = pcloc;
+               sattr = DEFINED | cursect;
+               type = 0x44; // N_SLINE, text section line number
+       }
+
+       if ((addr == prevaddr) || ((curlineno == prevlineno) && (prevfileno == cfileno)))
+               return;
+
+       prevaddr = addr;
+       prevlineno = curlineno;
+
+       if (prevfileno != cfileno)
+               GenFileSym(curfname, 0x84 /* N_SOL */, addr, sattr);
+
+       prevfileno = cfileno;
+
+       /* MADMAC counts lines starting at 0. Offset curlineno accordingly */
+       symbol = NewDebugSymbol(NULL, type, 0, curlineno - 1);
+
+       symbol->svalue = addr;
+       symbol->sattr |= sattr;
+}