[Ltrace-devel] [PATCH] Fix libunwind support for MIPS

Vicente Olivert Riera Vincent.Riera at imgtec.com
Thu Oct 8 15:59:35 UTC 2015


/* Verify that we can safely cast arch_addr_t* to unw_word_t*. */
(void)sizeof(char[1 - 2*(sizeof(unw_word_t) != sizeof(arch_addr_t))]);

This check will always fail for MIPS 32-bit architectures (the only ones
supported by ltrace) because unw_word_t is 64-bit sized (it's actually a
uint64_t) and arch_add_t (which is void*) is 32-bit sized:

output.c:784:3: error: size of unnamed array is negative

So do the check in a different way that works for all architectures.

Signed-off-by: Vicente Olivert Riera <Vincent.Riera at imgtec.com>
---
 output.c |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/output.c b/output.c
index b63befe..e166554 100644
--- a/output.c
+++ b/output.c
@@ -773,27 +773,28 @@ output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
 	    && proc->unwind_as != NULL) {
 		unw_cursor_t cursor;
 		arch_addr_t ip, function_offset;
+		unw_word_t uw_ip, uw_function_offset;
 		struct library *lib = NULL;
 		int unwind_depth = options.bt_depth;
 		char fn_name[100];
 		const char *lib_name;
 		size_t distance;
 
-		/* Verify that we can safely cast arch_addr_t* to
-		 * unw_word_t*.  */
-		(void)sizeof(char[1 - 2*(sizeof(unw_word_t)
-					!= sizeof(arch_addr_t))]);
 		unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
 		while (unwind_depth) {
 
-			int rc = unw_get_reg(&cursor, UNW_REG_IP,
-					     (unw_word_t *) &ip);
+			int rc = unw_get_reg(&cursor, UNW_REG_IP, &uw_ip);
+
 			if (rc < 0) {
 				fprintf(options.output, " > Error: %s\n",
 					unw_strerror(rc));
 				goto cont;
 			}
 
+			// Verify that we can safely cast arch_addr_t* to unw_word_t*.
+			ip = (arch_addr_t) uw_ip;
+			assert(uw_ip == (unw_word_t) ip);
+
 			/* We are looking for the library with the base address
 			 * closest to the current ip.  */
 			lib_name = "unmapped_area";
@@ -814,13 +815,18 @@ output_right(enum tof type, struct process *proc, struct library_symbol *libsym,
 
 			rc = unw_get_proc_name(&cursor, fn_name,
 					       sizeof(fn_name),
-					       (unw_word_t *) &function_offset);
-			if (rc == 0 || rc == -UNW_ENOMEM)
+					       &uw_function_offset);
+			if (rc == 0 || rc == -UNW_ENOMEM) {
+				// Verify that we can safely cast arch_addr_t* to unw_word_t*.
+				function_offset = (arch_addr_t) uw_function_offset;
+				assert(uw_function_offset == (unw_word_t) function_offset);
+
 				fprintf(options.output, " > %s(%s+%p) [%p]\n",
 					lib_name, fn_name, function_offset, ip);
-			else
+			} else {
 				fprintf(options.output, " > %s(??\?) [%p]\n",
 					lib_name, ip);
+			}
 
 		cont:
 			if (unw_step(&cursor) <= 0)
-- 
1.7.1




More information about the Ltrace-devel mailing list