Skip to content

Latest commit

 

History

History
1093 lines (996 loc) · 29.3 KB

symbols.c

File metadata and controls

1093 lines (996 loc) · 29.3 KB
 
1
2
3
/*
* Hatari - symbols.c
*
Apr 23, 2024
Apr 23, 2024
4
* Copyright (C) 2010-2024 by Eero Tamminen
Sep 1, 2012
Sep 1, 2012
6
7
* This file is distributed under the GNU General Public License, version 2
* or at your option any later version. Read the file gpl.txt for details.
8
9
10
11
*
* symbols.c - Hatari debugger symbol/address handling; parsing, sorting,
* matching, TAB completion support etc.
*
Apr 4, 2013
Apr 4, 2013
12
* Symbol/address information is read either from:
Sep 17, 2023
Sep 17, 2023
13
* - A program file's symbol table (in DRI/GST, a.out, or ELF format), or
Apr 4, 2013
Apr 4, 2013
14
15
16
17
18
* - ASCII file which contents are subset of "nm" output i.e. composed of
* a hexadecimal addresses followed by a space, letter indicating symbol
* type (T = text/code, D = data, B = BSS), space and the symbol name.
* Empty lines and lines starting with '#' are ignored. It's AHCC SYM
* output compatible.
Oct 16, 2020
Oct 16, 2020
20
const char Symbols_fileid[] = "Hatari symbols.c";
21
22
23
24
25
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
Jan 17, 2010
Jan 17, 2010
26
#include "main.h"
May 2, 2015
May 2, 2015
27
28
#include "file.h"
#include "options.h"
29
#include "symbols.h"
Jan 17, 2010
Jan 17, 2010
30
31
#include "debugui.h"
#include "debug_priv.h"
Apr 4, 2013
Apr 4, 2013
32
#include "debugInfo.h"
Apr 30, 2010
Apr 30, 2010
33
#include "evaluate.h"
Dec 19, 2014
Dec 19, 2014
34
#include "configuration.h"
Nov 6, 2017
Nov 6, 2017
35
#include "a.out.h"
Oct 1, 2022
Oct 1, 2022
36
#include "maccess.h"
Jan 17, 2010
Jan 17, 2010
37
May 4, 2021
May 4, 2021
38
39
#include "symbols-common.c"
40
/* how many characters the symbol name can have.
Feb 19, 2023
Feb 19, 2023
41
42
43
*
* While DRI/GST symbols are at max only couple of dozen
* chars long, C++/a.out symbols can be almost of any size.
Feb 19, 2023
Feb 19, 2023
45
46
#define MAX_SYM_SIZE 1024
#define MAX_SYM_SIZE_S "1024"
Jan 17, 2010
Jan 17, 2010
48
49
50
51
/* TODO: add symbol name/address file names to configuration? */
static symbol_list_t *CpuSymbolsList;
static symbol_list_t *DspSymbolsList;
May 2, 2014
May 2, 2014
52
53
/* path for last loaded program (through GEMDOS HD emulation) */
static char *CurrentProgramPath;
Nov 15, 2017
Nov 15, 2017
54
/* prevent repeated failing on every debugger invocation */
Jun 12, 2014
Jun 12, 2014
55
static bool AutoLoadFailed;
May 2, 2014
May 2, 2014
56
Apr 23, 2024
Apr 23, 2024
57
58
59
60
61
62
63
typedef enum {
SYMBOLS_FOR_NONE,
SYMBOLS_FOR_USER,
/* autoload facilities */
SYMBOLS_FOR_TOS,
SYMBOLS_FOR_PROGRAM,
} symbols_for_t;
Apr 23, 2024
Apr 23, 2024
64
65
66
/* what triggered current CPU symbols to be loaded */
static symbols_for_t CpuSymbolsAreFor = SYMBOLS_FOR_NONE;
Apr 23, 2024
Apr 23, 2024
67
Jan 17, 2010
Jan 17, 2010
68
Apr 4, 2013
Apr 4, 2013
69
70
71
72
73
/**
* Load symbols of given type and the symbol address addresses from
* the given ASCII file and add given offsets to the addresses.
* Return symbols list or NULL for failure.
*/
Aug 23, 2023
Aug 23, 2023
74
75
static symbol_list_t* symbols_load_ascii(FILE *fp, uint32_t *offsets, uint32_t maxaddr,
symtype_t gettype, const symbol_opts_t *opts)
76
77
{
symbol_list_t *list;
Feb 19, 2023
Feb 19, 2023
78
79
char symchar, name[MAX_SYM_SIZE+1];
char *buf, buffer[MAX_SYM_SIZE+64];
Aug 23, 2023
Aug 23, 2023
80
int count, line, symbols;
Sep 25, 2022
Sep 25, 2022
81
uint32_t address, offset;
Aug 23, 2023
Aug 23, 2023
82
ignore_counts_t ignore;
83
84
85
symtype_t symtype;
/* count content lines */
Nov 12, 2017
Nov 12, 2017
86
line = symbols = 0;
87
while (fgets(buffer, sizeof(buffer), fp)) {
Nov 12, 2017
Nov 12, 2017
88
89
line++;
Sep 18, 2011
Sep 18, 2011
90
91
/* skip comments (AHCC SYM file comments start with '*') */
if (*buffer == '#' || *buffer == '*') {
92
93
94
continue;
}
/* skip empty lines */
Jun 17, 2014
Jun 17, 2014
95
for (buf = buffer; isspace((unsigned char)*buf); buf++);
96
97
98
if (!*buf) {
continue;
}
Oct 4, 2020
Oct 4, 2020
99
if (!isxdigit((unsigned char)*buf)) {
Nov 12, 2017
Nov 12, 2017
100
101
102
fprintf(stderr, "ERROR: line %d doesn't start with an address.\n", line);
return NULL;
}
Jun 12, 2014
Jun 12, 2014
105
106
if (!symbols) {
fprintf(stderr, "ERROR: no symbols.\n");
Nov 12, 2017
Nov 12, 2017
107
return NULL;
Jun 12, 2014
Jun 12, 2014
108
109
}
110
111
fseek(fp, 0, SEEK_SET);
Apr 4, 2013
Apr 4, 2013
112
113
/* allocate space for symbol list & names */
if (!(list = symbol_list_alloc(symbols))) {
114
115
116
return NULL;
}
Aug 23, 2023
Aug 23, 2023
117
118
119
count = 0;
memset(&ignore, 0, sizeof(ignore));
120
121
/* read symbols */
for (line = 1; fgets(buffer, sizeof(buffer), fp); line++) {
Sep 18, 2011
Sep 18, 2011
122
123
/* skip comments (AHCC SYM file comments start with '*') */
if (*buffer == '#' || *buffer == '*') {
124
125
126
continue;
}
/* skip empty lines */
Jun 17, 2014
Jun 17, 2014
127
for (buf = buffer; isspace((unsigned char)*buf); buf++);
128
129
130
if (!*buf) {
continue;
}
Feb 19, 2023
Feb 19, 2023
131
132
133
134
/* file not modified in meanwhile? */
assert(count < symbols);
/* C++ symbols can contain almost any characters */
if (sscanf(buffer, "%x %c %"MAX_SYM_SIZE_S"[^$?@;\n]\n", &address, &symchar, name) != 3) {
Apr 4, 2013
Apr 4, 2013
135
fprintf(stderr, "WARNING: syntax error on line %d, skipping.\n", line);
Jan 17, 2010
Jan 17, 2010
136
137
continue;
}
Jun 17, 2014
Jun 17, 2014
138
switch (toupper((unsigned char)symchar)) {
Jan 29, 2013
Jan 29, 2013
139
140
141
142
case 'T':
symtype = SYMTYPE_TEXT;
offset = offsets[0];
break;
Aug 23, 2023
Aug 23, 2023
143
144
145
146
case 'W': /* ELF 'nm' code symbol type, weak */
symtype = SYMTYPE_WEAK;
offset = offsets[0];
break;
Jan 29, 2013
Jan 29, 2013
147
case 'O': /* AHCC type for _StkSize etc */
Aug 23, 2023
Aug 23, 2023
148
149
case 'V': /* ELF 'nm' data symbol type, weak */
case 'R': /* ELF 'nm' data symbol type, read only */
Jan 29, 2013
Jan 29, 2013
150
151
152
153
154
155
156
157
case 'D':
symtype = SYMTYPE_DATA;
offset = offsets[1];
break;
case 'B':
symtype = SYMTYPE_BSS;
offset = offsets[2];
break;
May 23, 2017
May 23, 2017
158
case 'A':
Mar 23, 2024
Mar 23, 2024
159
/* absolute address or arbitrary constant value */
May 23, 2017
May 23, 2017
160
161
162
symtype = SYMTYPE_ABS;
offset = 0;
break;
Apr 4, 2013
Apr 4, 2013
164
fprintf(stderr, "WARNING: unrecognized symbol type '%c' on line %d, skipping.\n", symchar, line);
Aug 23, 2023
Aug 23, 2023
165
ignore.invalid++;
Feb 4, 2010
Feb 4, 2010
168
if (!(gettype & symtype)) {
Jan 29, 2013
Jan 29, 2013
171
address += offset;
Mar 23, 2024
Mar 23, 2024
172
if (address > maxaddr && symtype != SYMTYPE_ABS) {
Apr 4, 2013
Apr 4, 2013
173
fprintf(stderr, "WARNING: invalid address 0x%x on line %d, skipping.\n", address, line);
Aug 23, 2023
Aug 23, 2023
174
175
176
177
178
ignore.invalid++;
continue;
}
/* whether to ignore symbol based on options and its name & type */
if (ignore_symbol(name, symtype, opts, &ignore)) {
Jan 29, 2013
Jan 29, 2013
179
180
continue;
}
Jan 17, 2010
Jan 17, 2010
181
list->names[count].address = address;
182
183
list->names[count].type = symtype;
list->names[count].name = strdup(name);
Aug 28, 2023
Aug 28, 2023
184
list->names[count].name_allocated = true;
185
186
187
assert(list->names[count].name);
count++;
}
Aug 23, 2023
Aug 23, 2023
188
show_ignored(&ignore);
Apr 4, 2013
Apr 4, 2013
189
list->symbols = symbols;
Nov 14, 2017
Nov 14, 2017
190
list->namecount = count;
Apr 4, 2013
Apr 4, 2013
191
192
193
return list;
}
Sep 17, 2023
Sep 17, 2023
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/**
* Return true if symbol name has (C++) data symbol prefix
*/
static bool is_cpp_data_symbol(const char *name)
{
static const char *cpp_data[] = {
"typeinfo ",
"vtable ",
"VTT "
};
int i;
for (i = 0; i < ARRAY_SIZE(cpp_data); i++) {
size_t len = strlen(cpp_data[i]);
if (strncmp(name, cpp_data[i], len) == 0) {
return true;
}
}
return false;
}
/**
* (C++) compiler can put certain data members to text section, and
* some of the weak (C++) symbols are for data. For C++, these can be
* recognized by their name. This changes their type to data, to
* speed up text symbol searches in profiler.
*/
static int fix_symbol_types(symbol_list_t* list)
{
symbol_t *sym = list->names;
int i, count, changed = 0;
count = list->namecount;
for (i = 0; i < count; i++) {
if (!(sym[i].type & SYMTYPE_CODE)) {
continue;
}
if (is_cpp_data_symbol(sym[i].name)) {
sym[i].type = SYMTYPE_DATA;
changed++;
}
/* TODO: add check also for C++ data member
* names, similar to profiler post-processor
* (requires using regex)?
*/
}
return changed;
}
Nov 14, 2017
Nov 14, 2017
242
/**
Aug 23, 2023
Aug 23, 2023
243
* Separate code symbols from other symbols in address list.
Nov 14, 2017
Nov 14, 2017
244
*/
Aug 28, 2023
Aug 28, 2023
245
static void symbols_split_addresses(symbol_list_t* list)
Nov 14, 2017
Nov 14, 2017
246
247
{
symbol_t *sym = list->addresses;
Aug 23, 2023
Aug 23, 2023
248
uint32_t prev = 0;
Nov 14, 2017
Nov 14, 2017
249
250
251
int i;
for (i = 0; i < list->namecount; i++) {
Aug 28, 2023
Aug 28, 2023
252
253
254
if (sym[i].type & ~SYMTYPE_CODE) {
break;
}
Aug 23, 2023
Aug 23, 2023
255
if (sym[i].address < prev) {
Aug 28, 2023
Aug 28, 2023
256
257
258
char stype = symbol_char(sym[i].type);
fprintf(stderr, "INTERNAL ERROR: %c symbol %d/%d ('%s') at %x < %x (prev addr)\n",
stype, i, list->namecount, sym[i].name, sym[i].address, prev);
Aug 23, 2023
Aug 23, 2023
259
260
261
exit(1);
}
prev = sym[i].address;
Nov 14, 2017
Nov 14, 2017
262
}
Nov 18, 2017
Nov 18, 2017
263
264
list->codecount = i;
list->datacount = list->namecount - i;
Nov 14, 2017
Nov 14, 2017
265
266
}
May 4, 2021
May 4, 2021
267
268
269
270
271
272
273
274
/**
* Set sections to match running process by adding TEXT/DATA/BSS
* start addresses to section offsets and ends, and return true if
* results match it.
*/
static bool update_sections(prg_section_t *sections)
{
/* offsets & max sizes for running program TEXT/DATA/BSS section symbols */
Sep 25, 2022
Sep 25, 2022
275
uint32_t start = DebugInfo_GetTEXT();
May 4, 2021
May 4, 2021
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
if (!start) {
fprintf(stderr, "ERROR: no valid program basepage!\n");
return false;
}
sections[0].offset = start;
sections[0].end += start;
if (DebugInfo_GetTEXTEnd() != sections[0].end) {
fprintf(stderr, "ERROR: given program TEXT section size differs from one in RAM!\n");
return false;
}
start = DebugInfo_GetDATA();
sections[1].offset = start;
if (sections[1].offset != sections[0].end) {
fprintf(stderr, "WARNING: DATA start doesn't match TEXT start + size!\n");
}
sections[1].end += start;
start = DebugInfo_GetBSS();
sections[2].offset = start;
if (sections[2].offset != sections[1].end) {
fprintf(stderr, "WARNING: BSS start doesn't match DATA start + size!\n");
}
sections[2].end += start;
return true;
}
Apr 4, 2013
Apr 4, 2013
304
305
306
307
308
/**
* Load symbols of given type and the symbol address addresses from
* the given file and add given offsets to the addresses.
* Return symbols list or NULL for failure.
*/
Feb 19, 2023
Feb 19, 2023
309
static symbol_list_t* Symbols_Load(const char *filename, uint32_t *offsets, uint32_t maxaddr, symtype_t gettype)
Apr 4, 2013
Apr 4, 2013
310
311
{
symbol_list_t *list;
Aug 23, 2023
Aug 23, 2023
312
symbol_opts_t opts;
Sep 17, 2023
Sep 17, 2023
313
int changed, dups;
Apr 4, 2013
Apr 4, 2013
314
FILE *fp;
May 2, 2015
May 2, 2015
316
317
if (!File_Exists(filename)) {
fprintf(stderr, "ERROR: file '%s' doesn't exist or isn't readable!\n", filename);
Apr 4, 2013
Apr 4, 2013
318
319
return NULL;
}
Aug 23, 2023
Aug 23, 2023
320
321
322
memset(&opts, 0, sizeof(opts));
opts.no_gccint = true;
opts.no_local = true;
Sep 6, 2023
Sep 6, 2023
323
opts.no_dups = true;
Aug 23, 2023
Aug 23, 2023
324
May 2, 2015
May 2, 2015
325
if (Opt_IsAtariProgram(filename)) {
May 2, 2014
May 2, 2014
326
const char *last = CurrentProgramPath;
Aug 24, 2013
Aug 24, 2013
327
328
329
330
331
if (!last) {
/* "pc=text" breakpoint used as point for loading program symbols gives false hits during bootup */
fprintf(stderr, "WARNING: no program loaded yet (through GEMDOS HD emu)!\n");
} else if (strcmp(last, filename) != 0) {
fprintf(stderr, "WARNING: given program doesn't match last program executed by GEMDOS HD emulation:\n\t%s\n", last);
Apr 4, 2013
Apr 4, 2013
332
}
Aug 24, 2013
Aug 24, 2013
333
fprintf(stderr, "Reading symbols from program '%s' symbol table...\n", filename);
May 2, 2015
May 2, 2015
334
fp = fopen(filename, "rb");
May 4, 2021
May 4, 2021
335
list = symbols_load_binary(fp, &opts, update_sections);
Apr 4, 2013
Apr 4, 2013
336
337
} else {
fprintf(stderr, "Reading 'nm' style ASCII symbols from '%s'...\n", filename);
May 2, 2015
May 2, 2015
338
fp = fopen(filename, "r");
Aug 23, 2023
Aug 23, 2023
339
list = symbols_load_ascii(fp, offsets, maxaddr, gettype, &opts);
Apr 4, 2013
Apr 4, 2013
340
}
Apr 19, 2013
Apr 19, 2013
341
342
fclose(fp);
Apr 4, 2013
Apr 4, 2013
343
if (!list) {
Jun 12, 2014
Jun 12, 2014
344
fprintf(stderr, "ERROR: reading symbols from '%s' failed!\n", filename);
Apr 4, 2013
Apr 4, 2013
345
346
347
return NULL;
}
Nov 14, 2017
Nov 14, 2017
348
349
350
351
352
353
if (!list->namecount) {
fprintf(stderr, "ERROR: no valid symbols in '%s', loading failed!\n", filename);
symbol_list_free(list);
return NULL;
}
Sep 17, 2023
Sep 17, 2023
354
355
356
357
if ((changed = fix_symbol_types(list))) {
fprintf(stderr, "Corrected type for %d symbols (text->data).\n", changed);
}
Sep 6, 2023
Sep 6, 2023
358
359
360
361
362
363
364
365
366
/* first sort symbols by address, _with_ code symbols being first */
qsort(list->names, list->namecount, sizeof(symbol_t), symbols_by_address);
/* remove symbols with duplicate addresses? */
if (opts.no_dups) {
if ((dups = symbols_trim_names(list))) {
fprintf(stderr, "Removed %d symbols in same addresses as other symbols.\n", dups);
}
}
Nov 14, 2017
Nov 14, 2017
367
368
/* copy name list to address list */
Nov 14, 2017
Nov 14, 2017
369
list->addresses = malloc(list->namecount * sizeof(symbol_t));
370
assert(list->addresses);
Nov 14, 2017
Nov 14, 2017
371
memcpy(list->addresses, list->names, list->namecount * sizeof(symbol_t));
Sep 6, 2023
Sep 6, 2023
373
/* "split" address list to code and other symbols */
Aug 28, 2023
Aug 28, 2023
374
symbols_split_addresses(list);
Sep 6, 2023
Sep 6, 2023
376
377
378
379
/* finally, sort name list by names */
qsort(list->names, list->namecount, sizeof(symbol_t), symbols_by_name);
/* skip more verbose output when symbols are auto-loaded */
Dec 21, 2019
Dec 21, 2019
380
if (ConfigureParams.Debugger.bSymbolsAutoLoad) {
Sep 6, 2023
Sep 6, 2023
381
fprintf(stderr, "Skipping detailed duplicate symbols reporting when autoload is enabled.\n");
Dec 21, 2019
Dec 21, 2019
382
} else {
Sep 6, 2023
Sep 6, 2023
383
384
385
386
387
/* check for duplicate addresses? */
if (!opts.no_dups) {
if ((dups = symbols_check_addresses(list->addresses, list->namecount))) {
fprintf(stderr, "%d symbols in same addresses as other symbols.\n", dups);
}
Nov 18, 2017
Nov 18, 2017
388
}
Sep 6, 2023
Sep 6, 2023
389
390
391
392
393
394
/* report duplicate names */
if ((dups = symbols_check_names(list->names, list->namecount))) {
fprintf(stderr, "%d symbols having multiple addresses for the same name.\n"
"Symbol expansion will match only one of the addresses for them!\n",
dups);
Nov 17, 2017
Nov 17, 2017
395
}
Nov 13, 2017
Nov 13, 2017
396
}
Nov 6, 2017
Nov 6, 2017
397
Aug 23, 2023
Aug 23, 2023
398
fprintf(stderr, "Loaded %d symbols (%d for code) from '%s'.\n",
Nov 18, 2017
Nov 18, 2017
399
list->namecount, list->codecount, filename);
400
401
402
403
return list;
}
Jan 17, 2010
Jan 17, 2010
404
405
406
407
408
/**
* Free read symbols.
*/
static void Symbols_Free(symbol_list_t* list)
{
May 2, 2021
May 2, 2021
409
symbol_list_free(list);
Jan 17, 2010
Jan 17, 2010
410
411
}
Aug 28, 2023
Aug 28, 2023
412
413
414
415
416
417
418
419
/**
* Free all symbols (at exit).
*/
void Symbols_FreeAll(void)
{
symbol_list_free(CpuSymbolsList);
symbol_list_free(DspSymbolsList);
}
Jan 17, 2010
Jan 17, 2010
420
421
422
/* ---------------- symbol name completion support ------------------ */
423
424
425
/**
* Helper for symbol name completion and finding their addresses.
* STATE = 0 -> different text from previous one.
Jan 17, 2010
Jan 17, 2010
426
* Return (copy of) next name or NULL if no matches.
Jan 17, 2010
Jan 17, 2010
428
static char* Symbols_MatchByName(symbol_list_t* list, symtype_t symtype, const char *text, int state)
Mar 17, 2013
Mar 17, 2013
430
static int i, len;
Jan 17, 2010
Jan 17, 2010
431
const symbol_t *entry;
Jan 17, 2010
Jan 17, 2010
433
434
435
436
437
if (!list) {
return NULL;
}
if (!state) {
438
439
440
441
442
443
/* first match */
len = strlen(text);
i = 0;
}
/* next match */
Jan 17, 2010
Jan 17, 2010
444
entry = list->names;
Nov 14, 2017
Nov 14, 2017
445
while (i < list->namecount) {
Feb 4, 2010
Feb 4, 2010
446
if ((entry[i].type & symtype) &&
447
strncmp(entry[i].name, text, len) == 0) {
Jan 17, 2010
Jan 17, 2010
448
return strdup(entry[i++].name);
449
450
451
452
453
454
455
} else {
i++;
}
}
return NULL;
}
Jan 17, 2010
Jan 17, 2010
456
/**
Feb 16, 2010
Feb 16, 2010
457
* Readline match callbacks for CPU symbol name completion.
Jan 17, 2010
Jan 17, 2010
458
459
460
461
* STATE = 0 -> different text from previous one.
* Return next match or NULL if no matches.
*/
char* Symbols_MatchCpuAddress(const char *text, int state)
Feb 5, 2010
Feb 5, 2010
462
463
464
465
{
return Symbols_MatchByName(CpuSymbolsList, SYMTYPE_ALL, text, state);
}
char* Symbols_MatchCpuCodeAddress(const char *text, int state)
Jan 17, 2010
Jan 17, 2010
466
{
Jan 6, 2018
Jan 6, 2018
467
468
469
if (ConfigureParams.Debugger.bMatchAllSymbols) {
return Symbols_MatchByName(CpuSymbolsList, SYMTYPE_ALL, text, state);
} else {
Aug 23, 2023
Aug 23, 2023
470
return Symbols_MatchByName(CpuSymbolsList, SYMTYPE_CODE, text, state);
Jan 6, 2018
Jan 6, 2018
471
}
Jan 17, 2010
Jan 17, 2010
472
}
Feb 5, 2010
Feb 5, 2010
473
474
char* Symbols_MatchCpuDataAddress(const char *text, int state)
{
Jan 6, 2018
Jan 6, 2018
475
476
477
478
479
if (ConfigureParams.Debugger.bMatchAllSymbols) {
return Symbols_MatchByName(CpuSymbolsList, SYMTYPE_ALL, text, state);
} else {
return Symbols_MatchByName(CpuSymbolsList, SYMTYPE_DATA|SYMTYPE_BSS, text, state);
}
Feb 5, 2010
Feb 5, 2010
480
}
Jan 17, 2010
Jan 17, 2010
483
484
485
486
487
* Readline match callback for DSP symbol name completion.
* STATE = 0 -> different text from previous one.
* Return next match or NULL if no matches.
*/
char* Symbols_MatchDspAddress(const char *text, int state)
Feb 5, 2010
Feb 5, 2010
488
489
490
491
{
return Symbols_MatchByName(DspSymbolsList, SYMTYPE_ALL, text, state);
}
char* Symbols_MatchDspCodeAddress(const char *text, int state)
Jan 17, 2010
Jan 17, 2010
492
{
Aug 23, 2023
Aug 23, 2023
493
return Symbols_MatchByName(DspSymbolsList, SYMTYPE_CODE, text, state);
Jan 17, 2010
Jan 17, 2010
494
}
Feb 5, 2010
Feb 5, 2010
495
496
497
498
char* Symbols_MatchDspDataAddress(const char *text, int state)
{
return Symbols_MatchByName(DspSymbolsList, SYMTYPE_DATA|SYMTYPE_BSS, text, state);
}
Jan 17, 2010
Jan 17, 2010
499
500
501
502
503
/* ---------------- symbol name -> address search ------------------ */
/**
Nov 18, 2017
Nov 18, 2017
504
* Binary search symbol of given type by name.
Jan 17, 2010
Jan 17, 2010
505
506
* Return symbol if name matches, zero otherwise.
*/
Nov 18, 2017
Nov 18, 2017
507
static const symbol_t* Symbols_SearchByName(symbol_t* entries, int count, symtype_t symtype, const char *name)
Jan 17, 2010
Jan 17, 2010
508
509
510
511
512
513
{
/* left, right, middle */
int l, r, m, dir;
/* bisect */
l = 0;
Nov 18, 2017
Nov 18, 2017
514
r = count - 1;
Jan 17, 2010
Jan 17, 2010
515
516
517
do {
m = (l+r) >> 1;
dir = strcmp(entries[m].name, name);
Feb 4, 2010
Feb 4, 2010
518
if (dir == 0 && (entries[m].type & symtype)) {
Jan 17, 2010
Jan 17, 2010
519
520
521
522
523
524
525
526
527
528
529
530
return &(entries[m]);
}
if (dir > 0) {
r = m-1;
} else {
l = m+1;
}
} while (l <= r);
return NULL;
}
/**
Nov 18, 2017
Nov 18, 2017
531
532
* Set given symbol's address to variable and return true if one
* was found from given list.
Jan 17, 2010
Jan 17, 2010
533
*/
Sep 25, 2022
Sep 25, 2022
534
static bool Symbols_GetAddress(symbol_list_t* list, symtype_t symtype, const char *name, uint32_t *addr)
Jan 17, 2010
Jan 17, 2010
535
536
{
const symbol_t *entry;
Nov 18, 2017
Nov 18, 2017
537
538
539
540
if (!(list && list->names)) {
return false;
}
entry = Symbols_SearchByName(list->names, list->namecount, symtype, name);
Jan 17, 2010
Jan 17, 2010
541
542
543
544
545
546
if (entry) {
*addr = entry->address;
return true;
}
return false;
}
Sep 25, 2022
Sep 25, 2022
547
bool Symbols_GetCpuAddress(symtype_t symtype, const char *name, uint32_t *addr)
Nov 18, 2017
Nov 18, 2017
548
549
550
{
return Symbols_GetAddress(CpuSymbolsList, symtype, name, addr);
}
Sep 25, 2022
Sep 25, 2022
551
bool Symbols_GetDspAddress(symtype_t symtype, const char *name, uint32_t *addr)
Jan 17, 2010
Jan 17, 2010
552
{
Nov 18, 2017
Nov 18, 2017
553
return Symbols_GetAddress(DspSymbolsList, symtype, name, addr);
Jan 17, 2010
Jan 17, 2010
554
555
556
557
558
}
/* ---------------- symbol address -> name search ------------------ */
May 13, 2019
May 13, 2019
559
/**
Aug 23, 2023
Aug 23, 2023
560
* Binary search code symbol by address in given sorted list.
May 28, 2019
May 28, 2019
561
* Return index for symbol which address matches or precedes
May 13, 2019
May 13, 2019
562
563
* the given one.
*/
Sep 25, 2022
Sep 25, 2022
564
static int Symbols_SearchBeforeAddress(symbol_t* entries, int count, uint32_t addr)
May 13, 2019
May 13, 2019
565
566
567
{
/* left, right, middle */
int l, r, m;
Sep 25, 2022
Sep 25, 2022
568
uint32_t curr;
May 13, 2019
May 13, 2019
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
/* bisect */
l = 0;
r = count - 1;
do {
m = (l+r) >> 1;
curr = entries[m].address;
if (curr == addr) {
return m;
}
if (curr > addr) {
r = m-1;
} else {
l = m+1;
}
} while (l <= r);
return r;
}
Sep 25, 2022
Sep 25, 2022
588
static const char* Symbols_GetBeforeAddress(symbol_list_t *list, uint32_t *addr)
May 13, 2019
May 13, 2019
589
590
591
592
593
594
595
596
597
598
599
{
if (!(list && list->addresses)) {
return NULL;
}
int i = Symbols_SearchBeforeAddress(list->addresses, list->codecount, *addr);
if (i >= 0) {
*addr = list->addresses[i].address;
return list->addresses[i].name;
}
return NULL;
}
Sep 25, 2022
Sep 25, 2022
600
const char* Symbols_GetBeforeCpuAddress(uint32_t *addr)
May 13, 2019
May 13, 2019
601
602
603
{
return Symbols_GetBeforeAddress(CpuSymbolsList, addr);
}
Sep 25, 2022
Sep 25, 2022
604
const char* Symbols_GetBeforeDspAddress(uint32_t *addr)
May 13, 2019
May 13, 2019
605
606
607
608
{
return Symbols_GetBeforeAddress(DspSymbolsList, addr);
}
Jan 17, 2010
Jan 17, 2010
609
/**
Nov 18, 2017
Nov 18, 2017
610
* Binary search symbol by address in given sorted list.
Feb 5, 2013
Feb 5, 2013
611
* Return symbol index if address matches, -1 otherwise.
May 13, 2019
May 13, 2019
612
613
614
*
* Performance critical, called on every instruction
* when profiling is enabled.
Sep 25, 2022
Sep 25, 2022
616
static int Symbols_SearchByAddress(symbol_t* entries, int count, uint32_t addr)
617
618
619
{
/* left, right, middle */
int l, r, m;
Sep 25, 2022
Sep 25, 2022
620
uint32_t curr;
621
622
623
/* bisect */
l = 0;
Nov 18, 2017
Nov 18, 2017
624
r = count - 1;
625
626
627
628
do {
m = (l+r) >> 1;
curr = entries[m].address;
if (curr == addr) {
Feb 5, 2013
Feb 5, 2013
629
return m;
630
631
632
633
634
635
636
}
if (curr > addr) {
r = m-1;
} else {
l = m+1;
}
} while (l <= r);
Feb 5, 2013
Feb 5, 2013
637
return -1;
Nov 18, 2017
Nov 18, 2017
641
642
* Search symbol in given list by type & address.
* Return symbol name if there's a match, NULL otherwise.
Aug 23, 2023
Aug 23, 2023
643
* Code symbols will be matched before other symbol types.
Jan 17, 2010
Jan 17, 2010
644
* Returned name is valid only until next Symbols_* function call.
Sep 25, 2022
Sep 25, 2022
646
static const char* Symbols_GetByAddress(symbol_list_t* list, uint32_t addr, symtype_t type)
Nov 18, 2017
Nov 18, 2017
648
if (!(list && list->addresses)) {
Feb 5, 2013
Feb 5, 2013
649
650
return NULL;
}
Aug 23, 2023
Aug 23, 2023
651
if (type & SYMTYPE_CODE) {
Nov 18, 2017
Nov 18, 2017
652
653
654
655
656
int i = Symbols_SearchByAddress(list->addresses, list->codecount, addr);
if (i >= 0) {
return list->addresses[i].name;
}
}
Aug 23, 2023
Aug 23, 2023
657
if (type & ~SYMTYPE_CODE) {
Nov 18, 2017
Nov 18, 2017
658
659
660
661
662
663
int i = Symbols_SearchByAddress(list->addresses + list->codecount, list->datacount, addr);
if (i >= 0) {
return list->addresses[list->codecount + i].name;
}
}
return NULL;
Jan 17, 2010
Jan 17, 2010
664
}
Sep 25, 2022
Sep 25, 2022
665
const char* Symbols_GetByCpuAddress(uint32_t addr, symtype_t type)
Feb 5, 2013
Feb 5, 2013
666
{
Nov 18, 2017
Nov 18, 2017
667
return Symbols_GetByAddress(CpuSymbolsList, addr, type);
Feb 5, 2013
Feb 5, 2013
668
}
Sep 25, 2022
Sep 25, 2022
669
const char* Symbols_GetByDspAddress(uint32_t addr, symtype_t type)
Jan 17, 2010
Jan 17, 2010
670
{
Nov 18, 2017
Nov 18, 2017
671
return Symbols_GetByAddress(DspSymbolsList, addr, type);
Feb 5, 2013
Feb 5, 2013
674
/**
Aug 23, 2023
Aug 23, 2023
675
* Search given list for code symbol by address.
Feb 5, 2013
Feb 5, 2013
676
677
* Return symbol index if address matches, -1 otherwise.
*/
Sep 25, 2022
Sep 25, 2022
678
static int Symbols_GetCodeIndex(symbol_list_t* list, uint32_t addr)
Nov 18, 2017
Nov 18, 2017
679
680
681
682
683
684
{
if (!list) {
return -1;
}
return Symbols_SearchByAddress(list->addresses, list->codecount, addr);
}
Sep 25, 2022
Sep 25, 2022
685
int Symbols_GetCpuCodeIndex(uint32_t addr)
Feb 5, 2013
Feb 5, 2013
686
{
Nov 18, 2017
Nov 18, 2017
687
688
return Symbols_GetCodeIndex(CpuSymbolsList, addr);
}
Sep 25, 2022
Sep 25, 2022
689
int Symbols_GetDspCodeIndex(uint32_t addr)
Nov 18, 2017
Nov 18, 2017
690
691
{
return Symbols_GetCodeIndex(DspSymbolsList, addr);
Feb 5, 2013
Feb 5, 2013
692
693
694
}
/**
Nov 18, 2017
Nov 18, 2017
695
* Return how many TEXT symbols are loaded/available
Feb 5, 2013
Feb 5, 2013
696
*/
Nov 18, 2017
Nov 18, 2017
697
int Symbols_CpuCodeCount(void)
Feb 5, 2013
Feb 5, 2013
698
{
Nov 18, 2017
Nov 18, 2017
699
return (CpuSymbolsList ? CpuSymbolsList->codecount : 0);
Feb 5, 2013
Feb 5, 2013
700
}
Nov 18, 2017
Nov 18, 2017
701
int Symbols_DspCodeCount(void)
Feb 5, 2013
Feb 5, 2013
702
{
Nov 18, 2017
Nov 18, 2017
703
return (DspSymbolsList ? DspSymbolsList->codecount : 0);
Feb 5, 2013
Feb 5, 2013
704
}
Jan 17, 2010
Jan 17, 2010
705
May 2, 2014
May 2, 2014
706
/* ---------------- symbol showing ------------------ */
Jan 17, 2010
Jan 17, 2010
707
May 9, 2023
May 9, 2023
709
710
* Show symbols matching (optional) 'find' string from given list,
* using paging.
May 9, 2023
May 9, 2023
712
static void Symbols_Show(symbol_list_t* list, const char *sortcmd, const char *find)
Jan 17, 2010
Jan 17, 2010
714
symbol_t *entry, *entries;
Nov 18, 2017
Nov 18, 2017
715
const char *symtype, *sorttype;
May 9, 2023
May 9, 2023
716
int i, row, rows, count, matches;
Feb 4, 2010
Feb 4, 2010
717
char symchar;
Nov 8, 2017
Nov 8, 2017
718
char line[80];
Feb 4, 2010
Feb 4, 2010
719
720
721
722
723
if (!list) {
fprintf(stderr, "No symbols!\n");
return;
}
Feb 4, 2010
Feb 4, 2010
724
Nov 18, 2017
Nov 18, 2017
725
726
if (strcmp("code", sortcmd) == 0) {
sorttype = "address";
Jan 17, 2010
Jan 17, 2010
727
entries = list->addresses;
Nov 18, 2017
Nov 18, 2017
728
count = list->codecount;
Aug 23, 2023
Aug 23, 2023
729
symtype = " TEXT/WEAK";
Nov 18, 2017
Nov 18, 2017
730
731
732
733
734
} else if (strcmp("data", sortcmd) == 0) {
sorttype = "address";
entries = list->addresses + list->codecount;
count = list->datacount;
symtype = " DATA/BSS/ABS";
Jan 17, 2010
Jan 17, 2010
735
} else {
Nov 18, 2017
Nov 18, 2017
736
sorttype = "name";
Jan 17, 2010
Jan 17, 2010
737
entries = list->names;
Nov 14, 2017
Nov 14, 2017
738
739
count = list->namecount;
symtype = "";
Jan 17, 2010
Jan 17, 2010
740
}
Nov 12, 2017
Nov 12, 2017
741
rows = DebugUI_GetPageLines(ConfigureParams.Debugger.nSymbolLines, 20);
May 9, 2023
May 9, 2023
742
row = matches = 0;
Nov 8, 2017
Nov 8, 2017
743
Nov 14, 2017
Nov 14, 2017
744
for (entry = entries, i = 0; i < count; i++, entry++) {
May 9, 2023
May 9, 2023
745
746
747
748
749
if (find && !strstr(entry->name, find)) {
continue;
}
matches++;
Apr 24, 2014
Apr 24, 2014
750
symchar = symbol_char(entry->type);
Feb 25, 2010
Feb 25, 2010
751
752
fprintf(stderr, "0x%08x %c %s\n",
entry->address, symchar, entry->name);
May 9, 2023
May 9, 2023
753
754
755
756
row++;
if (row >= rows) {
row = 0;
Jan 17, 2010
Jan 17, 2010
757
fprintf(stderr, "--- q to exit listing, just enter to continue --- ");
Nov 6, 2017
Nov 6, 2017
758
759
if (fgets(line, sizeof(line), stdin) == NULL ||
toupper(line[0]) == 'Q') {
Nov 18, 2017
Nov 18, 2017
760
break;
Jan 17, 2010
Jan 17, 2010
761
762
}
}
May 9, 2023
May 9, 2023
764
765
fprintf(stderr, "%d %s%s symbols (of %d) sorted by %s.\n",
matches, (list == CpuSymbolsList ? "CPU" : "DSP"),
Nov 18, 2017
Nov 18, 2017
766
symtype, count, sorttype);
May 2, 2014
May 2, 2014
769
770
771
/* ---------------- binary load handling ------------------ */
/**
Dec 21, 2019
Dec 21, 2019
772
773
* If autoloading is enabled and program symbols are present,
* remove them along with program path.
Nov 15, 2017
Nov 15, 2017
774
775
776
*
* Called on GEMDOS reset and when program terminates
* (unless terminated with Ptermres()).
May 2, 2014
May 2, 2014
777
778
779
780
781
782
783
*/
void Symbols_RemoveCurrentProgram(void)
{
if (CurrentProgramPath) {
free(CurrentProgramPath);
CurrentProgramPath = NULL;
Apr 23, 2024
Apr 23, 2024
784
if (CpuSymbolsList && CpuSymbolsAreFor == SYMBOLS_FOR_PROGRAM &&
Apr 23, 2024
Apr 23, 2024
785
ConfigureParams.Debugger.bSymbolsAutoLoad) {
May 2, 2014
May 2, 2014
786
Symbols_Free(CpuSymbolsList);
Nov 14, 2017
Nov 14, 2017
787
fprintf(stderr, "Program exit, removing its symbols.\n");
Apr 23, 2024
Apr 23, 2024
788
CpuSymbolsAreFor = SYMBOLS_FOR_NONE;
May 2, 2014
May 2, 2014
789
790
791
CpuSymbolsList = NULL;
}
}
Jun 12, 2014
Jun 12, 2014
792
AutoLoadFailed = false;
May 2, 2014
May 2, 2014
793
794
795
}
/**
Dec 21, 2019
Dec 21, 2019
796
797
* Call Symbols_RemoveCurrentProgram() and
* set last opened program path.
Nov 15, 2017
Nov 15, 2017
798
799
*
* Called on first Fopen() after Pexec().
May 2, 2014
May 2, 2014
800
*/
May 2, 2015
May 2, 2015
801
void Symbols_ChangeCurrentProgram(const char *path)
May 2, 2014
May 2, 2014
802
{
May 2, 2015
May 2, 2015
803
if (Opt_IsAtariProgram(path)) {
Dec 21, 2019
Dec 21, 2019
804
Symbols_RemoveCurrentProgram();
May 2, 2014
May 2, 2014
805
806
807
808
CurrentProgramPath = strdup(path);
}
}
Oct 8, 2019
Oct 8, 2019
809
810
811
812
813
814
815
816
/*
* Show currently set program path
*/
void Symbols_ShowCurrentProgramPath(FILE *fp)
{
if (CurrentProgramPath) {
fprintf(fp, "Current program path: %s\n", CurrentProgramPath);
} else {
Dec 21, 2019
Dec 21, 2019
817
fputs("No program has been loaded (through GEMDOS HD).\n", fp);
Oct 8, 2019
Oct 8, 2019
818
819
820
}
}
Apr 23, 2024
Apr 23, 2024
821
/**
Apr 23, 2024
Apr 23, 2024
822
823
824
* Autoload helper. Given the base file name with .XXX extension,
* if there's another file with .sym extension, load symbols from it,
* and return them.
Apr 23, 2024
Apr 23, 2024
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
*
* Assumes all (relevant) sections use the same load address.
*/
static symbol_list_t *loadSymFile(const char *path, symtype_t symtype,
uint32_t loadaddr, uint32_t maxaddr)
{
int len = strlen(path);
char symfile[len+1];
if (len <= 3 || path[len-4] != '.') {
return NULL;
}
strcpy(symfile, path);
strcpy(symfile + len - 3, "sym");
fprintf(stderr, "Checking: %s\n", symfile);
if (!File_Exists(symfile)) {
return NULL;
}
uint32_t offsets[3] = { loadaddr, loadaddr, loadaddr };
return Symbols_Load(symfile, offsets, maxaddr, symtype);
}
May 2, 2014
May 2, 2014
849
/**
Dec 21, 2019
Dec 21, 2019
850
* Load symbols for last opened program when symbol autoloading is enabled.
Feb 19, 2023
Feb 19, 2023
851
852
853
854
855
*
* If there's file with same name as the program, but with '.sym'
* extension, that overrides / is loaded instead of the symbol table
* in the program.
*
Nov 15, 2017
Nov 15, 2017
856
* Called when debugger is invoked.
May 2, 2014
May 2, 2014
857
858
859
*/
void Symbols_LoadCurrentProgram(void)
{
Dec 21, 2019
Dec 21, 2019
860
861
862
if (!ConfigureParams.Debugger.bSymbolsAutoLoad) {
return;
}
Apr 23, 2024
Apr 23, 2024
863
864
/* program path missing or previous load failed? */
if (!CurrentProgramPath || AutoLoadFailed) {
May 2, 2014
May 2, 2014
865
866
return;
}
Apr 23, 2024
Apr 23, 2024
867
/* do not override manually loaded symbols, or
Apr 23, 2024
Apr 23, 2024
868
869
* load new symbols if previous program did not terminate.
* Autoloaded TOS symbols could be overridden though
Feb 19, 2023
Feb 19, 2023
870
*/
Apr 23, 2024
Apr 23, 2024
871
if (CpuSymbolsList && CpuSymbolsAreFor != SYMBOLS_FOR_TOS) {
Apr 23, 2024
Apr 23, 2024
872
return;
Feb 19, 2023
Feb 19, 2023
873
}
Apr 23, 2024
Apr 23, 2024
874
875
876
877
878
879
880
881
882
uint32_t loadaddr = DebugInfo_GetTEXT();
uint32_t maxaddr = DebugInfo_GetTEXTEnd();
symbol_list_t *symbols;
symbols = loadSymFile(CurrentProgramPath, SYMTYPE_CODE, loadaddr, maxaddr);
if (symbols) {
fprintf(stderr, "Symbols override loaded for: %s\n", CurrentProgramPath);
} else {
Aug 23, 2023
Aug 23, 2023
883
884
symbols = Symbols_Load(CurrentProgramPath, NULL, 0,
SYMTYPE_CODE);
Feb 19, 2023
Feb 19, 2023
885
886
}
if (!symbols) {
Jun 12, 2014
Jun 12, 2014
887
AutoLoadFailed = true;
Apr 23, 2024
Apr 23, 2024
888
return;
May 2, 2014
May 2, 2014
889
}
Apr 23, 2024
Apr 23, 2024
890
891
892
AutoLoadFailed = false;
CpuSymbolsAreFor = SYMBOLS_FOR_PROGRAM;
Feb 19, 2023
Feb 19, 2023
893
CpuSymbolsList = symbols;
May 2, 2014
May 2, 2014
894
895
}
Apr 23, 2024
Apr 23, 2024
896
897
898
899
900
901
902
903
904
905
906
/**
* If autoloading enabled and no symbols are present, load symbols
* for <tos>.img file from <tos>.sym file, if one exists.
*
* Called whenever TOS is loaded.
*/
void Symbols_LoadTOS(const char *path, uint32_t maxaddr)
{
if (!ConfigureParams.Debugger.bSymbolsAutoLoad) {
return;
}
Apr 23, 2024
Apr 23, 2024
907
908
/* do not override manually loaded symbols */
if (CpuSymbolsList && CpuSymbolsAreFor == SYMBOLS_FOR_USER) {
Apr 23, 2024
Apr 23, 2024
909
910
911
912
913
return;
}
CpuSymbolsList = loadSymFile(path, SYMTYPE_ALL, 0, maxaddr);
if (CpuSymbolsList) {
fprintf(stderr, "Loaded symbols for TOS: %s\n", path);
Apr 23, 2024
Apr 23, 2024
914
CpuSymbolsAreFor = SYMBOLS_FOR_TOS;
Apr 23, 2024
Apr 23, 2024
915
916
917
}
}
May 2, 2014
May 2, 2014
918
919
/* ---------------- command parsing ------------------ */
Apr 24, 2014
Apr 24, 2014
920
921
922
923
924
925
926
927
/**
* Readline match callback to list symbols subcommands.
* STATE = 0 -> different text from previous one.
* Return next match or NULL if no matches.
*/
char *Symbols_MatchCommand(const char *text, int state)
{
static const char* subs[] = {
Dec 21, 2019
Dec 21, 2019
928
"autoload", "code", "data", "free", "match", "name", "prg"
Apr 24, 2014
Apr 24, 2014
929
};
May 9, 2023
May 9, 2023
930
931
932
933
934
char *ret = DebugUI_MatchHelper(subs, ARRAY_SIZE(subs), text, state);
if (ret) {
return ret;
}
return Symbols_MatchCpuAddress(text, state);
Apr 24, 2014
Apr 24, 2014
935
936
}
Feb 14, 2010
Feb 14, 2010
937
const char Symbols_Description[] =
May 9, 2023
May 9, 2023
938
"<code|data|name> [find] -- list symbols containing 'find'\n"
Jan 6, 2018
Jan 6, 2018
939
"\tsymbols <prg|free> -- load/free symbols\n"
Dec 21, 2019
Dec 21, 2019
940
941
"\t <filename> [<T offset> [<D offset> <B offset>]]\n"
"\tsymbols <autoload|match> -- toggle symbol options\n"
Jan 6, 2018
Jan 6, 2018
942
943
944
"\n"
"\t'name' command lists the currently loaded symbols, sorted by name.\n"
"\t'code' and 'data' commands list them sorted by address; 'code' lists\n"
Aug 23, 2023
Aug 23, 2023
945
946
"\tonly TEXT/WEAK symbols, 'data' lists DATA/BSS/ABS symbols. If 'find'\n"
"\tis given, only symbols with that substring are listed.\n"
Nov 15, 2017
Nov 15, 2017
947
948
"\n"
"\tBy default, symbols are loaded from the currently executing program's\n"
Jan 6, 2018
Jan 6, 2018
949
950
"\tbinary when entering the debugger, IF program is started through\n"
"\tGEMDOS HD, and they're freed when that program terminates.\n"
Apr 4, 2013
Apr 4, 2013
951
"\n"
Jan 6, 2018
Jan 6, 2018
952
"\tThat corresponds to 'prg' command which loads (DRI/GST or a.out\n"
Nov 9, 2017
Nov 9, 2017
953
954
"\tformat) symbol table from the last program executed through\n"
"\tthe GEMDOS HD emulation.\n"
Jan 29, 2013
Jan 29, 2013
955
"\n"
Jan 6, 2018
Jan 6, 2018
956
"\t'free' command removes the loaded symbols.\n"
Jan 6, 2018
Jan 6, 2018
957
"\n"
Nov 15, 2017
Nov 15, 2017
958
"\tIf program lacks symbols, or it's not run through the GEMDOS HD\n"
Jan 6, 2018
Jan 6, 2018
959
960
961
"\temulation, user can ask symbols to be loaded from a file that's\n"
"\tan unstripped version of the binary. Or from an ASCII symbols file\n"
"\tproduced by the 'nm' and (Hatari) 'gst2ascii' tools.\n"
Nov 15, 2017
Nov 15, 2017
962
"\n"
Jan 6, 2018
Jan 6, 2018
963
964
965
"\tWith ASCII symbols files, given non-zero offset(s) are added to\n"
"\tthe text (T), data (D) and BSS (B) symbols. Typically one uses\n"
"\tTEXT variable, sometimes also DATA & BSS, variables for this.\n"
Nov 14, 2017
Nov 14, 2017
966
"\n"
Dec 21, 2019
Dec 21, 2019
967
968
969
970
971
"\t'autoload [on|off]' command toggle/set whether debugger will load\n"
"\tsymbols for currently executing (GEMDOS HD) program automatically\n"
"\ton entering the debugger (i.e. replace earlier loaded symbols),\n"
"\tand free them when program terminates. It needs to be disabled\n"
"\tto debug memory-resident programs used by other programs.\n"
Apr 4, 2013
Apr 4, 2013
972
"\n"
Jan 6, 2018
Jan 6, 2018
973
974
975
"\t'match' command toggles whether TAB completion matches all symbols,\n"
"\tor only symbol types that should be relevant for given command.";
Jan 17, 2010
Jan 17, 2010
978
* Handle debugger 'symbols' command and its arguments
Jan 17, 2010
Jan 17, 2010
980
int Symbols_Command(int nArgc, char *psArgs[])
Nov 13, 2017
Nov 13, 2017
982
enum { TYPE_CPU, TYPE_DSP } listtype;
Sep 25, 2022
Sep 25, 2022
983
uint32_t offsets[3], maxaddr;
Jan 17, 2010
Jan 17, 2010
984
symbol_list_t *list;
Feb 4, 2010
Feb 4, 2010
985
const char *file;
Jan 29, 2013
Jan 29, 2013
986
int i;
Jan 17, 2010
Jan 17, 2010
988
989
990
if (strcmp("dspsymbols", psArgs[0]) == 0) {
listtype = TYPE_DSP;
maxaddr = 0xFFFF;
Nov 13, 2017
Nov 13, 2017
991
} else {
Jan 17, 2010
Jan 17, 2010
992
listtype = TYPE_CPU;
Dec 19, 2014
Dec 19, 2014
993
994
995
996
if ( ConfigureParams.System.bAddressSpace24 )
maxaddr = 0x00FFFFFF;
else
maxaddr = 0xFFFFFFFF;
Nov 13, 2017
Nov 13, 2017
998
999
1000
if (nArgc < 2) {
file = "name";
} else {