changeset 173:77cd647375e5

objgrep -r: dump symbols in other sections recovered through relocs
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Fri, 04 Jul 2014 06:34:33 +0000
parents 452baa748747
children 10c0cdc18208
files objgrep/dumpmatch.c objgrep/globals.c objgrep/globals.h objgrep/intstruct.h objgrep/main.c objgrep/mkpattern.c objgrep/tables.c
diffstat 7 files changed, 64 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/objgrep/dumpmatch.c	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/dumpmatch.c	Fri Jul 04 06:34:33 2014 +0000
@@ -69,12 +69,11 @@
 	return(dest);
 }
 
-dump_relocs_on_match()
+process_relocs_on_match()
 {
 	unsigned n, value;
 	struct internal_reloc *rel;
 
-	printf("\nDeduced from relocs:\n\n");
 	for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++) {
 		switch (rel->type) {
 		case RTYPE_LONG:
@@ -93,15 +92,51 @@
 			abort();
 		}
 		value -= rel->addend;
-		if (rel->secbase)
-			printf("%s:%s = %08X\n", objfilename,
-				rel->secbase->name, value);
-		else if (rel->extsym)
-			printf("%s = %08X\n", rel->extsym->name, value);
-		else {
-			fprintf(stderr,
-			"BUG in dump_relocs_on_match(): no base for reloc\n");
-			abort();
+		rel->symvalue = value;
+		if (rel->secbase) {
+			if (!rel->secbase->recov_flag) {
+				rel->secbase->recov_flag = 1;
+				rel->secbase->recov_addr = value;
+			} else if (rel->secbase->recov_addr != value)
+			    printf("Multiple addresses for %s:%s: %08X, %08X\n",
+				objfilename, rel->secbase->name,
+				rel->secbase->recov_addr, value);
 		}
 	}
 }
+
+dump_ext_relocs_on_match()
+{
+	unsigned n;
+	struct internal_reloc *rel;
+
+	printf("\nExternals deduced from relocs:\n\n");
+	for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++)
+		if (rel->extsym)
+			printf("%s = %08X\n", rel->extsym->name, rel->symvalue);
+}
+
+dump_reloc_symtab_on_match()
+{
+	unsigned n;
+	struct internal_syment *sym;
+
+	printf("\nThis module's symbols deduced from section relocs:\n\n");
+	for (n = 0; n < nsymtab; n++) {
+		sym = symtab[n];
+		if (!sym || !sym->section)
+			continue;
+		if (!sym->section->recov_flag)
+			continue;
+		switch (sym->class) {
+		case C_EXT:
+			printf("%s = %08X\n", sym->name,
+				sym->value + sym->section->recov_addr);
+			continue;
+		case C_STAT:
+			printf("%s:%s = %08X\n", objfilename, sym->name,
+				sym->value + sym->section->recov_addr);
+			continue;
+		}
+	}
+}
--- a/objgrep/globals.c	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/globals.c	Fri Jul 04 06:34:33 2014 +0000
@@ -19,5 +19,7 @@
 struct internal_syment **symtab;
 u_char *pattern_match, *pattern_mask;
 unsigned pattern_len;
+
 struct internal_reloc *relocs;
+unsigned nreloc_int, nreloc_ext;
 unsigned match_offset;
--- a/objgrep/globals.h	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/globals.h	Fri Jul 04 06:34:33 2014 +0000
@@ -17,5 +17,7 @@
 extern struct internal_syment **symtab;
 extern u_char *pattern_match, *pattern_mask;
 extern unsigned pattern_len;
+
 extern struct internal_reloc *relocs;
+extern unsigned nreloc_int, nreloc_ext;
 extern unsigned match_offset;
--- a/objgrep/intstruct.h	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/intstruct.h	Fri Jul 04 06:34:33 2014 +0000
@@ -13,6 +13,8 @@
 	unsigned	nlineent;
 	unsigned	flags;
 	unsigned	nsymbols;
+	unsigned	recov_flag;
+	unsigned	recov_addr;
 };
 
 struct internal_syment {
@@ -32,4 +34,5 @@
 	struct internal_syment *extsym;
 	int		type;
 	unsigned	addend;
+	unsigned	symvalue;
 };
--- a/objgrep/main.c	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/main.c	Fri Jul 04 06:34:33 2014 +0000
@@ -68,7 +68,12 @@
 		binfilename, match_offset);
 	if (sflag)
 		dump_symtab_on_match();
-	if (rflag && grep_section->nreloc)
-		dump_relocs_on_match();
+	if (rflag && grep_section->nreloc) {
+		process_relocs_on_match();
+		if (nreloc_ext)
+			dump_ext_relocs_on_match();
+		if (nreloc_int)
+			dump_reloc_symtab_on_match();
+	}
 	exit(0);
 }
--- a/objgrep/mkpattern.c	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/mkpattern.c	Fri Jul 04 06:34:33 2014 +0000
@@ -125,13 +125,16 @@
 		if (!sym) {
 			irel->secbase = grep_section;
 			irel->extsym = 0;
+			nreloc_int++;
 		} else if (sym->class == C_EXT && sym->scnum == 0) {
 			irel->extsym = sym;
 			irel->secbase = 0;
+			nreloc_ext++;
 		} else if (sym->class == C_STAT && sym->section &&
 			   !strcmp(sym->name, sym->section->name)) {
 			irel->secbase = sym->section;
 			irel->extsym = 0;
+			nreloc_int++;
 		} else {
 			fprintf(stderr, "error: unable to grok reloc\n");
 			exit(2);
--- a/objgrep/tables.c	Fri Jul 04 03:22:41 2014 +0000
+++ b/objgrep/tables.c	Fri Jul 04 06:34:33 2014 +0000
@@ -107,6 +107,7 @@
 	"warning: section #%u (%s): some nonzero value in s_page bytes\n",
 				n, sections[n].name);
 		sections[n].nsymbols = 0;
+		sections[n].recov_flag = 0;
 	}
 }