From 60a932b36804bff8b6ca40adc665a33a59475db1 Mon Sep 17 00:00:00 2001
From: Spencer Oliver <spen@spen-soft.co.uk>
Date: Mon, 13 Aug 2012 11:22:35 +0100
Subject: [PATCH] build: fix memory leaks

Fix the memory leaks found by clang-3.1

Change-Id: Iaae68627ef599c324c9c9ee5737c22e92512862d
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/775
Tested-by: jenkins
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
---
 src/flash/mflash.c       |  1 +
 src/flash/nand/lpc3180.c | 16 ++++++++++++----
 src/flash/nor/at91sam7.c |  4 +++-
 src/rtos/FreeRTOS.c      | 18 ++++++++++--------
 src/rtos/linux.c         | 21 +++++++++++++++++----
 src/rtos/rtos.c          |  2 ++
 src/server/gdb_server.c  |  1 +
 7 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/src/flash/mflash.c b/src/flash/mflash.c
index bf61a1149..5d1f3b6ed 100644
--- a/src/flash/mflash.c
+++ b/src/flash/mflash.c
@@ -770,6 +770,7 @@ COMMAND_HANDLER(mg_write_cmd)
 	int retval = fileio_size(&fileio, &filesize);
 	if (retval != ERROR_OK) {
 		fileio_close(&fileio);
+		free(buffer);
 		return retval;
 	}
 
diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index 1b5306701..a44f3c21e 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -524,8 +524,9 @@ static int lpc3180_write_page(struct nand_device *nand,
 			target_write_u32(target, 0x200b8010, 0x0);
 
 			if (!lpc3180_controller_ready(nand, 1000)) {
-				LOG_ERROR(
-					"timeout while waiting for completion of auto encode cycle");
+				LOG_ERROR("timeout while waiting for completion of auto encode cycle");
+				free(page_buffer);
+				free(oob_buffer);
 				return ERROR_NAND_OPERATION_FAILED;
 			}
 		}
@@ -536,11 +537,15 @@ static int lpc3180_write_page(struct nand_device *nand,
 		retval = nand_read_status(nand, &status);
 		if (retval != ERROR_OK) {
 			LOG_ERROR("couldn't read status");
+			free(page_buffer);
+			free(oob_buffer);
 			return ERROR_NAND_OPERATION_FAILED;
 		}
 
 		if (status & NAND_STATUS_FAIL) {
 			LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status);
+			free(page_buffer);
+			free(oob_buffer);
 			return ERROR_NAND_OPERATION_FAILED;
 		}
 
@@ -888,8 +893,9 @@ static int lpc3180_read_page(struct nand_device *nand,
 			target_write_u32(target, 0x200b8014, 0xaa55aa55);
 
 			if (!lpc3180_controller_ready(nand, 1000)) {
-				LOG_ERROR(
-					"timeout while waiting for completion of auto decode cycle");
+				LOG_ERROR("timeout while waiting for completion of auto decode cycle");
+				free(page_buffer);
+				free(oob_buffer);
 				return ERROR_NAND_OPERATION_FAILED;
 			}
 
@@ -899,6 +905,8 @@ static int lpc3180_read_page(struct nand_device *nand,
 				if (mlc_isr & 0x40) {
 					LOG_ERROR("uncorrectable error detected: 0x%2.2x",
 						(unsigned)mlc_isr);
+					free(page_buffer);
+					free(oob_buffer);
 					return ERROR_NAND_OPERATION_FAILED;
 				}
 
diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c
index 3e99c4a64..95ba084b5 100644
--- a/src/flash/nor/at91sam7.c
+++ b/src/flash/nor/at91sam7.c
@@ -897,8 +897,10 @@ static int at91sam7_erase(struct flash_bank *bank, int first, int last)
 		for (pos = 0; pos < nbytes; pos++)
 			buffer[pos] = 0xFF;
 
-		if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK)
+		if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK) {
+			free(buffer);
 			return ERROR_FLASH_OPERATION_FAILED;
+		}
 
 		free(buffer);
 	}
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index a64626989..1e4ddc532 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -259,6 +259,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
 				(uint8_t *)&list_thread_count);
 		if (retval != ERROR_OK) {
 			LOG_OUTPUT("Error reading number of threads in FreeRTOS thread list\r\n");
+			free(list_of_lists);
 			return retval;
 		}
 
@@ -273,8 +274,8 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
 				param->pointer_width,
 				(uint8_t *)&list_elem_ptr);
 		if (retval != ERROR_OK) {
-			LOG_OUTPUT(
-				"Error reading first thread item location in FreeRTOS thread list\r\n");
+			LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n");
+			free(list_of_lists);
 			return retval;
 		}
 
@@ -288,8 +289,8 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
 					param->pointer_width,
 					(uint8_t *)&(rtos->thread_details[tasks_found].threadid));
 			if (retval != ERROR_OK) {
-				LOG_OUTPUT(
-					"Error reading thread list item object in FreeRTOS thread list\r\n");
+				LOG_OUTPUT("Error reading thread list item object in FreeRTOS thread list\r\n");
+				free(list_of_lists);
 				return retval;
 			}
 
@@ -304,8 +305,8 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
 					FREERTOS_THREAD_NAME_STR_SIZE,
 					(uint8_t *)&tmp_str);
 			if (retval != ERROR_OK) {
-				LOG_OUTPUT(
-					"Error reading first thread item location in FreeRTOS thread list\r\n");
+				LOG_OUTPUT("Error reading first thread item location in FreeRTOS thread list\r\n");
+				free(list_of_lists);
 				return retval;
 			}
 			tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00';
@@ -338,12 +339,13 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
 					param->pointer_width,
 					(uint8_t *)&list_elem_ptr);
 			if (retval != ERROR_OK) {
-				LOG_OUTPUT(
-					"Error reading next thread item location in FreeRTOS thread list\r\n");
+				LOG_OUTPUT("Error reading next thread item location in FreeRTOS thread list\r\n");
+				free(list_of_lists);
 				return retval;
 			}
 		}
 	}
+
 	free(list_of_lists);
 	rtos->thread_count = tasks_found;
 	return 0;
diff --git a/src/rtos/linux.c b/src/rtos/linux.c
index cd7ae0437..15d52366f 100644
--- a/src/rtos/linux.c
+++ b/src/rtos/linux.c
@@ -420,6 +420,8 @@ int fill_task(struct target *target, struct threads *t)
 	} else
 		LOG_ERROR("fill task: unable to read memory");
 
+	free(buffer);
+
 	return retval;
 }
 
@@ -494,8 +496,10 @@ int get_current(struct target *target, int create)
 		int retval;
 
 		if (target_get_gdb_reg_list(head->target, &reg_list,
-				&reg_list_size) != ERROR_OK)
+				&reg_list_size) != ERROR_OK) {
+			free(buffer);
 			return ERROR_TARGET_FAILURE;
+		}
 
 		if (!reg_list[13]->valid)
 			reg_list[13]->type->get(reg_list[13]);
@@ -550,6 +554,8 @@ int get_current(struct target *target, int create)
 		head = head->next;
 	}
 
+	free(buffer);
+
 	return ERROR_OK;
 }
 
@@ -615,6 +621,7 @@ retry:
 			(uint8_t *) registers);
 
 	if (retval != ERROR_OK) {
+		free(buffer);
 		LOG_ERROR("cpu_context: unable to read memory\n");
 		return context;
 	}
@@ -643,6 +650,8 @@ retry:
 	if (*thread_info_addr_old == 0xdeadbeef)
 		*thread_info_addr_old = thread_info_addr_update;
 
+	free(buffer);
+
 	return context;
 }
 
@@ -655,11 +664,13 @@ uint32_t next_task(struct target *target, struct threads *t)
 	if (retval == ERROR_OK) {
 		uint32_t val = get_buffer(target, buffer);
 		val = val - NEXT;
-		return val;
 		free(buffer);
+		return val;
 	} else
 		LOG_ERROR("next task: unable to read memory");
 
+	free(buffer);
+
 	return 0;
 }
 
@@ -778,6 +789,7 @@ int linux_get_tasks(struct target *target, int context)
 		retval = get_name(target, t);
 
 		if (loop > MAX_THREADS) {
+			free(t);
 			LOG_INFO("more than %d threads !!", MAX_THREADS);
 			return ERROR_FAIL;
 		}
@@ -829,6 +841,7 @@ int linux_get_tasks(struct target *target, int context)
 		(timeval_ms() - start) / linux_os->threadid_count);
 
 	LOG_INFO("threadid count %d", linux_os->threadid_count);
+	free(t);
 
 	return ERROR_OK;
 }
@@ -973,7 +986,7 @@ error_handling:
 #ifndef PID_CHECK
 error_handling:
 	free(t);
-	LOG_ERROR("unable toread pid");
+	LOG_ERROR("unable to read pid");
 	return;
 
 #endif
@@ -1454,7 +1467,7 @@ static int linux_thread_packet(struct connection *connection, char *packet,
 			}
 		}
 
-			/* if a packet handler returned an error, exit input loop */
+		/* if a packet handler returned an error, exit input loop */
 		if (retval != ERROR_OK)
 			return retval;
 	}
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index 07e44eae0..524e1daca 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -169,6 +169,8 @@ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
 			if (target->rtos->symbols[symbol_num].symbol_name == NULL) {
 				LOG_OUTPUT("ERROR: unknown symbol\r\n");
 				gdb_put_packet(connection, "OK", 2);
+				free(hex_name_str);
+				free(name_str);
 				return ERROR_OK;
 			}
 
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 1c0ee08fd..31f814dee 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1138,6 +1138,7 @@ static int gdb_set_register_packet(struct connection *connection,
 
 	if ((unsigned int)chars != strlen(separator + 1)) {
 		LOG_ERROR("gdb sent a packet with wrong register size");
+		free(bin_buf);
 		return ERROR_SERVER_REMOTE_CLOSED;
 	}
 
-- 
GitLab