int enum_symbols (FILE * fp, long size, int (*func) (const char *sym, void *param), void *param) { long end; struct dbuf_s buf; struct dbuf_s symname; assert (func != NULL); dbuf_init (&buf, 512); dbuf_init (&symname, 32); end = (size >= 0) ? ftell (fp) + size : -1; /* * Read in the object file. Look for lines that * begin with "S" and end with "D". These are * symbol table definitions. If we find one, see * if it is our symbol. Make sure we only read in * our object file and don't go into the next one. */ while (end < 0 || ftell (fp) < end) { const char *p; dbuf_set_length (&buf, 0); if (dbuf_getline (&buf, fp) == 0) break; p = dbuf_c_str (&buf); if ('T' == p[0]) break; /* * Skip everything that's not a symbol record. */ if ('S' == p[0] && ' ' == p[1]) { dbuf_set_length (&symname, 0); for (p += 2; *p && ' ' != *p; ++p) dbuf_append_char (&symname, *p); /* If it's an actual symbol, record it */ if (' ' == p[0] && 'D' == p[1]) if (func != NULL) if ((*func) (dbuf_c_str (&symname), NULL)) return 1; } } dbuf_destroy (&buf); dbuf_destroy (&symname); return 0; }
int enum_symbols (FILE * fp, long size, int (*func) (const char *sym, void *param), void *param) { long end; struct dbuf_s buf; struct dbuf_s symname; assert (func != NULL); dbuf_init (&buf, 512); dbuf_init (&symname, 32); end = (size >= 0) ? ftell (fp) + size : -1; /* * Read in the object file. Look for lines that * begin with "S" and end with "D". These are * symbol table definitions. If we find one, see * if it is our symbol. Make sure we only read in * our object file and don't go into the next one. */ while (end < 0 || ftell (fp) < end) { const char *p; dbuf_set_length (&buf, 0); if (dbuf_getline (&buf, fp) == 0) break; p = dbuf_c_str (&buf); /* Skip whitespace */ while (isspace (*p)) p++; /* Skip local symbols or directives */ if ('.' == p[0]) continue; /* * Skip everything that's not a symbol. */ if (isalpha (*p) || '_' == *p) { bool found = false; dbuf_set_length (&symname, 0); while (isalnum (*p) || '_' == *p) dbuf_append_char (&symname, *p++); if (':' == *p) /* a label */ { if (':' == *++p) /* a global label */ found = true; } else /* no label */ { size_t i; /* Skip whitespace */ while (isspace (*p)) p++; for (found = false, i = 0; !found && i < sizeof(directives) / sizeof(symbol_t); i++) { if (0 == strncmp(p, directives[i].text, strlen(directives[i].text))) { switch (directives[i].subtype) { case stEQU: case stBYTE: case stWORD_BE: case stWORD_LE: case stLONG_BE: case stLONG_LE: case stBUFFER: case stTEXT: case stDS: case stDSIN: case stDSOUT: case stDSIO: case stDSROM: case stDSRAM: /* It's a symbol */ found = true; break; default: break; } } } } /* If it's an actual symbol, record it */ if (found) if (func != NULL) if ((*func) (dbuf_c_str (&symname), NULL)) return 1; } } dbuf_destroy (&buf); dbuf_destroy (&symname); return 0; }