Parse ld65 map file for symbolic debugging.

This commit is contained in:
Lawrence Kesteloot 2018-08-02 16:07:42 -07:00
parent 14a84bdb6a
commit bfe64192a3
1 changed files with 97 additions and 2 deletions

View File

@ -45,6 +45,9 @@ APPLE2Einterface::ModeHistory mode_history;
const float paddle_max_pulse_seconds = .00282;
// Map from memory address to name of function (from the ld65 map file).
static map<int,string> address_to_function_name;
typedef unsigned long long clk_t;
struct system_clock
{
@ -86,6 +89,73 @@ bool read_blob(char *name, unsigned char *b, size_t sz)
return true;
}
/**
* Parse a map entry from an ld65 map file and add it to the address_to_function_name map.
*/
static void add_map_entry(char *line)
{
// Find end of function name and terminate it.
char *s = line;
while (*s != ' ') {
s++;
}
*s = '\0';
string function_name = string(line);
// Parse hex address.
int address = strtol(line + 26, NULL, 16);
// See if we have a duplicate. We define our own symbols (like _pushax) as aliases
// to cc65-defined ones (like pushax) so we can access them from C.
string old_function_name = address_to_function_name[address];
if (old_function_name.size() != 0 && old_function_name.size() < function_name.size()) {
// Skip this one, we already have one that's shorter (probably without
// leading underscore).
} else {
// Add to map.
address_to_function_name[address] = line;
}
}
/**
* Read a map file generated by ld65. Puts symbols into the address_to_function_name map.
*/
static bool read_map(char *name)
{
char line[100];
FILE *fp = fopen(name, "r");
int state = 0;
while (state != 3 && fgets(line, sizeof(line), fp) != NULL) {
switch (state) {
case 0:
if (strncmp(line, "Exports list by name:", 21) == 0) {
// Found header.
state = 1;
}
break;
case 1:
// Skip line with dashes.
state = 2;
break;
case 2:
// Parse table.
if (strlen(line) <= 76) {
// End of table.
state = 3;
}
add_map_entry(line);
add_map_entry(line + 40);
break;
}
}
fclose(fp);
return true;
}
struct SoftSwitch
{
string name;
@ -1051,6 +1121,7 @@ struct MAINboard : board_base
disassemble_buffer = new unsigned char[data];
disassemble_size = data;
disassemble_index = 0;
printf("Size of buffer: %d bytes\n", disassemble_size);
}
return true;
} else if (addr == 0xBFFF) {
@ -1063,7 +1134,17 @@ struct MAINboard : board_base
string dis;
for (int i = 0; i < disassemble_size; i += bytes) {
tie(bytes, dis) = disassemble_6502(i, disassemble_buffer + i);
printf("%s\n", dis.c_str());
printf("%-32s", dis.c_str());
if (bytes == 3) {
// Print function name if we have it.
int address = disassemble_buffer[i + 1] +
(disassemble_buffer[i + 2] << 8);
auto search = address_to_function_name.find(address);
if (search != address_to_function_name.end()) {
printf(" ; %s", search->second.c_str());
}
}
printf("\n");
}
printf("---\n");
delete[] disassemble_buffer;
@ -2695,7 +2776,7 @@ struct CPU6502
void usage(char *progname)
{
printf("\n");
printf("usage: %s [-debugger] [-fast] ROM.bin\n", progname);
printf("usage: %s [-debugger] [-fast] [-map ld65.map] ROM.bin\n", progname);
printf("\n");
printf("\n");
}
@ -2933,6 +3014,7 @@ int main(int argc, char **argv)
argc -= 1;
argv += 1;
char *diskII_rom_name = NULL, *floppy1_name = NULL, *floppy2_name = NULL;
char *map_name = NULL;
while((argc > 0) && (argv[0][0] == '-')) {
if(strcmp(argv[0], "-debugger") == 0) {
@ -2965,6 +3047,14 @@ int main(int argc, char **argv)
}
argv += 2;
argc -= 2;
} else if(strcmp(argv[0], "-map") == 0) {
if(argc < 2) {
fprintf(stderr, "-map option requires an ld65 map filename.\n");
exit(EXIT_FAILURE);
}
map_name = argv[1];
argv += 2;
argc -= 2;
} else if(
(strcmp(argv[0], "-help") == 0) ||
(strcmp(argv[0], "-h") == 0) ||
@ -2996,6 +3086,11 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if(map_name != NULL) {
if(!read_map(map_name))
exit(EXIT_FAILURE);
}
system_clock clk;
MAINboard* mainboard;