[PATCH] Use /usr/bin/nm -D on stripped binaries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use "nm -D" to retrieve also the symbols of crash when having stripped binaries.
Use the presence of the symbol table to determine if the binary has been
stripped or not.

Because we don't have static symbols in stripped binaries, we check the size
of the function (the "nm -S" output) and report "unknown" if the looked address
is outside of the function.


Signed-off-by: Bernhard Walle <bwalle@xxxxxxx>


2 files changed, 55 insertions(+), 12 deletions(-)
defs.h    |    1 
symbols.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++------------


Use "nm -D" to retrieve also the symbols of crash when having stripped binaries.
Use the presence of the symbol table to determine if the binary has been
stripped or not.

Because we don't have static symbols in stripped binaries, we check the size
of the function (the "nm -S" output) and report "unknown" if the looked address
is outside of the function.


Signed-off-by: Bernhard Walle <bwalle@xxxxxxx>

diff --git a/defs.h b/defs.h
--- a/defs.h
+++ b/defs.h
@@ -3296,6 +3296,7 @@
 void dump_offset_table(char *, ulong);
 int is_elf_file(char *);
 int is_kernel(char *);
+int is_binary_stripped(char *filename);
 int file_elf_version(char *);
 int is_system_map(char *);
 int select_namelist(char *);
diff --git a/symbols.c b/symbols.c
--- a/symbols.c
+++ b/symbols.c
@@ -2719,6 +2719,32 @@
         return TRUE;
 }
 
+int
+is_binary_stripped(char *filename)
+{
+#if defined(GDB_6_0) || defined(GDB_6_1)
+        struct bfd *bfd;
+#else
+        struct _bfd *bfd;
+#endif
+
+	if ((bfd = bfd_openr(filename, NULL)) == NULL) {
+		error(INFO, "Cannot open ELF file: %s\n", filename);
+		return FALSE;
+	}
+
+	if (!bfd_check_format(bfd, bfd_object)) {
+		error(INFO, "Invalid ELF file: %s\n", filename);
+		return FALSE;
+	}
+
+	int number_of_symbols;
+	number_of_symbols = bfd_canonicalize_symtab(bfd, NULL);
+
+	bfd_close(bfd);
+	
+	return number_of_symbols == 0;
+}
 
 /*
  *  This command may be used to:
@@ -9048,9 +9074,11 @@
 	char *arglist[MAXARGS];
 	char buf[BUFSIZE];
 	FILE *pipe;
-	ulong vaddr, lookfor;
-	ulong last_vaddr;
+	ulong vaddr, size, lookfor;
+	ulong last_vaddr, last_size;
 	char symbol[BUFSIZE];
+	int stripped_binary;
+	const char *nm_call;
 
 	fflush(fp);
 	fflush(stdout);
@@ -9073,11 +9101,17 @@
 		return;
 	}
 
+	stripped_binary = is_binary_stripped(thisfile);
+	if (stripped_binary)
+		nm_call = "/usr/bin/nm -DSBn %s";
+	else
+		nm_call = "/usr/bin/nm -BSn %s";
+
         for (i = 0; i < NUMBER_STACKFRAMES; i++) {
 		if (!(lookfor = retaddr[i]))
 			continue;
 
-		sprintf(buf, "/usr/bin/nm -Bn %s", thisfile);
+		sprintf(buf, nm_call, thisfile);
 	        if (!(pipe = popen(buf, "r"))) {
 			perror("pipe");
 			break;
@@ -9086,20 +9120,28 @@
 		last_vaddr = 0;
 		BZERO(symbol, BUFSIZE);
 
-	        while (fgets(buf, 80, pipe)) {
+	        while (fgets(buf, BUFSIZE, pipe)) {
 			c = parse_line(strip_linefeeds(buf), arglist);
-			if (c != 3)
+			if (c != 4)
 				continue;
 			vaddr = htol(arglist[0], FAULT_ON_ERROR, NULL);
+			size = htol(arglist[1], FAULT_ON_ERROR, NULL);
 			if (vaddr > lookfor) {
-				fprintf(stderr, "%s  %lx: %s+%ld\n",
-					i == 0 ? "\n" : "", 
-					lookfor, symbol, 
-					lookfor-last_vaddr);
-				break;
-			}
-			strcpy(symbol, arglist[2]);
+				if ((lookfor - last_vaddr) > last_size)
+					fprintf(stderr, "%s  %lx: %s+%ld\n",
+						i == 0 ? "\n" : "", 
+						lookfor, "unknown", 
+						lookfor-last_vaddr);
+				else
+					fprintf(stderr, "%s  %lx: %s+%ld\n",
+						i == 0 ? "\n" : "", 
+						lookfor, symbol, 
+						lookfor-last_vaddr);
+				break;
+			}
+			strcpy(symbol, arglist[3]);
 			last_vaddr = vaddr;
+			last_size = size;
 		}
 
 		pclose(pipe);
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux