shithub: rgbds

Download patch

ref: 60b85298a945a07960249f15dab9ef72dbe30219
parent: 8bbafb72005ac35899f0a9a5bc7f92ec224f5b60
author: ISSOtm <[email protected]>
date: Mon May 3 08:43:41 EDT 2021

Fix all memory leaks in RGBLINK

At least all that were reported in the tests.
Partial fix for #709, that only leaves RGBASM to be fixed... oh boy!

--- a/include/link/patch.h
+++ b/include/link/patch.h
@@ -21,10 +21,7 @@
 	struct Patch patch;
 	// enum AssertionType type; The `patch`'s field is instead re-used
 	char *message;
-	/*
-	 * This would be redundant with `.section->fileSymbols`... but
-	 * `section` is sometimes NULL!
-	 */
+	// This would be redundant with `.section->fileSymbols`... but `section` is sometimes NULL!
 	struct Symbol **fileSymbols;
 
 	struct Assertion *next;
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -28,18 +28,6 @@
 #include "extern/getopt.h"
 #include "version.h"
 
-#ifdef __clang__
-#if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
-#define __SANITIZE_ADDRESS__
-#endif /* __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__) */
-#endif /* __clang__ */
-
-#ifdef __SANITIZE_ADDRESS__
-// There are known, non-trivial to fix leaks. We would still like to have `make develop'
-// detect memory corruption, though.
-const char *__asan_default_options(void) { return "detect_leaks=0"; }
-#endif
-
 bool isDmgMode;               /* -d */
 char       *linkerScriptName; /* -l */
 char const *mapFileName;      /* -m */
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -640,19 +640,33 @@
 	nodes = malloc(sizeof(*nodes) * nbFiles);
 }
 
+static void freeNode(struct FileStackNode *node)
+{
+	if (node->type == NODE_REPT)
+		free(node->iters);
+	else
+		free(node->name);
+}
+
 static void freeSection(struct Section *section, void *arg)
 {
 	(void)arg;
 
-	free(section->name);
-	if (sect_HasData(section->type)) {
-		free(section->data);
-		for (uint32_t i = 0; i < section->nbPatches; i++)
-			free(section->patches[i].rpnExpression);
-		free(section->patches);
-	}
-	free(section->symbols);
-	free(section);
+	do {
+		struct Section *next = section->nextu;
+
+		free(section->name);
+		if (sect_HasData(section->type)) {
+			free(section->data);
+			for (uint32_t i = 0; i < section->nbPatches; i++)
+				free(section->patches[i].rpnExpression);
+			free(section->patches);
+		}
+		free(section->symbols);
+		free(section);
+
+		section = next;
+	} while (section);
 }
 
 static void freeSymbol(struct Symbol *symbol)
@@ -665,8 +679,7 @@
 {
 	for (unsigned int i = 0; i < nbObjFiles; i++) {
 		for (uint32_t j = 0; j < nodes[i].nbNodes; j++) {
-			if (nodes[i].nodes[j].type == NODE_REPT)
-				free(nodes[i].nodes[j].iters);
+			freeNode(&nodes[i].nodes[j]);
 		}
 		free(nodes[i].nodes);
 	}
@@ -677,16 +690,12 @@
 	sect_ForEach(freeSection, NULL);
 	sect_CleanupSections();
 
-	struct SymbolList *list = symbolLists;
+	for (struct SymbolList *list = symbolLists, *next; list; list = next) {
+		next = list->next;
 
-	while (list) {
 		for (size_t i = 0; i < list->nbSymbols; i++)
 			freeSymbol(list->symbolList[i]);
 		free(list->symbolList);
-
-		struct SymbolList *next = list->next;
-
 		free(list);
-		list = next;
 	}
 }
--- a/src/link/patch.c
+++ b/src/link/patch.c
@@ -478,6 +478,8 @@
 		}
 		struct Assertion *next = assert->next;
 
+		free(assert->patch.rpnExpression);
+		free(assert->message);
 		free(assert);
 		assert = next;
 	}