+SYM * NewDebugSymbol(const uint8_t * str, uint8_t type, uint8_t other, uint16_t desc)
+{
+ SYM * symbol = NewSymbol(str, DBGSYM, 0);
+
+ if (NULL == symbol)
+ fatal("Could not allocate space for debug symbol");
+
+ AddToSymbolDeclarationList(symbol);
+
+ symbol->st_type = type;
+ symbol->st_other = other;
+ symbol->st_desc = 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;
+}