Re: [hatari-devel] Support for loading GNU-style symbols from a.out executables

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


On Montag, 6. November 2017 13:56:16 CET Thorsten Otto wrote:

Two more small patches that might be useful. The first uses the info from 
readline or environment to determine how many symbols to display. I also 
changed the getchar() to fgets(), because otherwise, if you stop the list, the 
next time that function is entered you will get the newline from the previous 
run.

The second delays the duplicate symbol check to after sorting. The current 
solution does it at part of the qsort() callback function, which results in 
the same symbol to be reported several times, when it is compared several 
times.

There are some small problems remaining. Ie. it currently always will report 
the linker generated symbols __edata and __bss_start, because they always will 
have the same address. It also will report local names from distinct modules 
as duplicates, because there is no distinction between local/global symbols.
And when using mintlib, it will also report some symbols that are deliberately 
set at aliases there, like memcpy & memmove.

Greetings
Thorsten
# HG changeset patch
# User Thorsten Otto <admin@xxxxxxxxxxx>
# Date 1510010929 -3600
#      Tue Nov 07 00:28:49 2017 +0100
# Node ID c59f72de4d5e4bcc663aaca547e0cdf70882c217
# Parent  4b81a2a3a39f367ae968bff67200beea1865d7a0
Use terminal lines to determine number of symbols to display

diff -r 4b81a2a3a39f -r c59f72de4d5e src/debug/debugui.c
--- a/src/debug/debugui.c	Mon Nov 06 13:45:32 2017 +0100
+++ b/src/debug/debugui.c	Tue Nov 07 00:28:49 2017 +0100
@@ -818,6 +818,14 @@
 	return Str_Trim(readline("> "));
 }
 
+/**
+ * Get readlines idea of the terminal size
+ */
+void DebugUI_GetScreenSize(int *rows, int *cols)
+{
+	rl_get_screen_size(rows, cols);
+}
+
 #else /* !HAVE_LIBREADLINE */
 
 /**
@@ -829,6 +837,21 @@
 }
 
 /**
+ * Get number of lines/columns for terminal output
+ */
+void DebugUI_GetScreenSize(int *rows, int *cols)
+{
+	const char *p;
+	
+	*rows = 24;
+	*cols = 80;
+	if ((p = getenv("LINES")) != NULL)
+		*rows = (int)strtol(p, NULL, 0);
+	if ((p = getenv("COLUMS")) != NULL)
+		*cols = (int)strtol(p, NULL, 0);
+}
+
+/**
  * Read a command line from the keyboard and return a pointer to the string.
  * Only string returned by this function can be given for it as argument!
  * @return	Pointer to the string which should be given back to this
diff -r 4b81a2a3a39f -r c59f72de4d5e src/debug/debugui.h
--- a/src/debug/debugui.h	Mon Nov 06 13:45:32 2017 +0100
+++ b/src/debug/debugui.h	Tue Nov 07 00:28:49 2017 +0100
@@ -35,5 +35,6 @@
 extern bool DebugUI_ParseLine(const char *input);
 extern bool DebugUI_SetParseFile(const char *input);
 extern void DebugUI_MemorySnapShot_Capture(const char *path, bool bSave);
+extern void DebugUI_GetScreenSize(int *rows, int *cols);
 
 #endif /* HATARI_DEBUGUI_H */
diff -r 4b81a2a3a39f -r c59f72de4d5e src/debug/symbols.c
--- a/src/debug/symbols.c	Mon Nov 06 13:45:32 2017 +0100
+++ b/src/debug/symbols.c	Tue Nov 07 00:28:49 2017 +0100
@@ -1156,6 +1156,8 @@
 	symbol_t *entry, *entries;
 	char symchar;
 	int i;
+	int rows, cols;
+	char line[256];
 	
 	if (!list) {
 		fprintf(stderr, "No symbols!\n");
@@ -1170,13 +1172,18 @@
 	fprintf(stderr, "%s symbols sorted by %s:\n",
 		(list == CpuSymbolsList ? "CPU" : "DSP"), sorttype);
 
+	DebugUI_GetScreenSize(&rows, &cols);
+	if (rows < 20)
+		rows = 20;
+	rows--;
 	for (entry = entries, i = 0; i < list->count; i++, entry++) {
 		symchar = symbol_char(entry->type);
 		fprintf(stderr, "0x%08x %c %s\n",
 			entry->address, symchar, entry->name);
-		if (i && i % 20 == 0) {
+		if ((i + 1) % rows == 0) {
 			fprintf(stderr, "--- q to exit listing, just enter to continue --- ");
-			if (toupper(getchar()) == 'Q') {
+			if (fgets(line, sizeof(line), stdin) == NULL ||
+				toupper(line[0]) == 'Q') {
 				return;
 			}
 		}
# HG changeset patch
# User Thorsten Otto <admin@xxxxxxxxxxx>
# Date 1510012190 -3600
#      Tue Nov 07 00:49:50 2017 +0100
# Node ID 50838d5baafde51b8796978f3218b65478b551d2
# Parent  c59f72de4d5e4bcc663aaca547e0cdf70882c217
Check for duplicate symbols after sorting, to avoid reporting the same symbol several times

diff -r c59f72de4d5e -r 50838d5baafd src/debug/symbols.c
--- a/src/debug/symbols.c	Tue Nov 07 00:28:49 2017 +0100
+++ b/src/debug/symbols.c	Tue Nov 07 00:49:50 2017 +0100
@@ -90,8 +90,6 @@
 	if (addr1 > addr2) {
 		return 1;
 	}
-	fprintf(stderr, "WARNING: symbols '%s' & '%s' have the same 0x%x address.\n",
-		((const symbol_t*)s1)->name, ((const symbol_t*)s2)->name, addr1);
 	return 0;
 }
 
@@ -105,13 +103,42 @@
 	int ret;
 
 	ret = strcmp(name1, name2);
-	if (!ret) {
-		fprintf(stderr, "WARNING: addresses 0x%x & 0x%x have the same '%s' name.\n",
-			((const symbol_t*)s1)->address, ((const symbol_t*)s2)->address, name1);
-	}
 	return ret;
 }
 
+/**
+ * check for duplicate addresses in symbol list
+ */
+static void symbols_check_addresses(const symbol_t *syms, int count)
+{
+	int i, j;
+	
+	for (i = 0; i < (count - 1); i++)
+	{
+		for (j = i + 1; j < count && syms[i].address == syms[j].address; j++) {
+			fprintf(stderr, "WARNING: symbols '%s' & '%s' have the same 0x%x address.\n",
+				syms[i].name, syms[j].name, syms[i].address);
+			i = j;
+		}
+	}
+}
+
+/**
+ * check for duplicate names in symbol list
+ */
+static void symbols_check_names(const symbol_t *syms, int count)
+{
+	int i, j;
+	
+	for (i = 0; i < (count - 1); i++)
+	{
+		for (j = i + 1; j < count && strcmp(syms[i].name, syms[j].name) == 0; j++) {
+			fprintf(stderr, "WARNING: addresses 0x%x & 0x%x have the same '%s' name.\n",
+				syms[i].address, syms[j].address, syms[i].name);
+			i = j;
+		}
+	}
+}
 
 /**
  * Allocate symbol list & names for given number of items.
@@ -882,6 +909,12 @@
 	qsort(list->addresses, list->count, sizeof(symbol_t), symbols_by_address);
 	qsort(list->names, list->count, sizeof(symbol_t), symbols_by_name);
 
+	/* check for duplicate addresses */
+	symbols_check_addresses(list->addresses, list->count);
+	
+	/* check for duplicate names */
+	symbols_check_names(list->names, list->count);
+	
 	fprintf(stderr, "Loaded %d symbols from '%s'.\n", list->count, filename);
 	return list;
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/