changeset 121:d88f2f40e3ae

tiobjd: handling of symbol-less relocs
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Fri, 04 Apr 2014 07:19:15 +0000
parents 4d8dfdbd2ea1
children ca82528ec84d
files ticoff/disasm.c ticoff/reloc.c
diffstat 2 files changed, 25 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/ticoff/disasm.c	Fri Apr 04 05:45:22 2014 +0000
+++ b/ticoff/disasm.c	Fri Apr 04 07:19:15 2014 +0000
@@ -14,16 +14,15 @@
 extern unsigned get_u16(), get_u32();
 
 static void
-find_better_symbol(symp, addp)
+find_better_symbol(sec, symp, addp)
+	struct internal_scnhdr *sec;
 	struct internal_syment **symp;
 	unsigned *addp;
 {
-	struct internal_scnhdr *sec;
 	unsigned addr, delta;
 	struct internal_syment *sym;
 	unsigned n;
 
-	sec = (*symp)->section;
 	addr = *addp;
 	for (n = 0; n < sec->nsymbols; n++) {
 		sym = sec->sorted_symbols[n];
@@ -48,15 +47,18 @@
 {
 	struct internal_syment *sym = rel->sym;
 
-	addend -= sym->value;
-	if (sym->section && !strcmp(sym->name, sym->section->name))
-		find_better_symbol(&sym, &addend);
+	if (sym)
+		addend -= sym->value;
+	if (!sym || sym->section && !strcmp(sym->name, sym->section->name))
+		find_better_symbol(sym ? sym->section : sec, &sym, &addend);
+	if (sym)
+		fputs(sym->name, stdout);
+	else
+		fputs(sec->name, stdout);
 	if (addend >= 10)
-		printf("%s+0x%x", sym->name, addend);
+		printf("+0x%x", addend);
 	else if (addend)
-		printf("%s+%u", sym->name, addend);
-	else
-		fputs(sym->name, stdout);
+		printf("+%u", addend);
 }
 
 void
--- a/ticoff/reloc.c	Fri Apr 04 05:45:22 2014 +0000
+++ b/ticoff/reloc.c	Fri Apr 04 07:19:15 2014 +0000
@@ -69,13 +69,15 @@
 		}
 		lastloc = intrel->location;
 		symidx = get_u32(extrel->r_symndx);
-		if (symidx >= nsymtab || !symtab[symidx]) {
+		if (symidx == 0xFFFFFFFF)
+			intrel->sym = 0;
+		else if (symidx >= nsymtab || !symtab[symidx]) {
 			fprintf(stderr,
 	"error: reloc references invalid symbol #%u in section \"%s\"\n",
 				symidx, sec->name);
 			exit(1);
-		}
-		intrel->sym = symtab[symidx];
+		} else
+			intrel->sym = symtab[symidx];
 		intrel->type = get_u16(extrel->r_type);
 		switch (intrel->type) {
 		case RTYPE_LONG:
@@ -105,6 +107,7 @@
 	unsigned n, m;
 	struct internal_scnhdr *sec;
 	struct internal_reloc *rel;
+	char *symname;
 
 	get_int_section_table();
 	get_int_symbol_table();
@@ -116,9 +119,14 @@
 		get_relocs_of_sec(sec);
 		rel = sec->int_relocs;
 		printf("Location  Type      Symbol relative to\n");
-		for (m = 0; m < sec->nreloc; m++, rel++)
+		for (m = 0; m < sec->nreloc; m++, rel++) {
+			if (rel->sym)
+				symname = rel->sym->name;
+			else
+				symname = "<none>";
 			printf("%08X  %-8s  %s\n", rel->location, rel->typestr,
-				rel->sym->name);
+				symname);
+		}
 		putchar('\n');
 	}
 	exit(0);