changeset 110:e650fdc743fe

tiobjd: higher-level reloc handling
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 03 Apr 2014 03:03:41 +0000
parents e40592990516
children 0f94d17899b3
files ticoff/intstruct.h ticoff/main.c ticoff/reloc.c ticoff/tables.c
diffstat 4 files changed, 101 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ticoff/intstruct.h	Mon Mar 31 19:06:33 2014 +0000
+++ b/ticoff/intstruct.h	Thu Apr 03 03:03:41 2014 +0000
@@ -14,6 +14,7 @@
 	unsigned	flags;
 	unsigned	nsymbols;
 	struct internal_syment **sorted_symbols;
+	struct internal_reloc *int_relocs;
 };
 
 struct internal_syment {
@@ -25,3 +26,10 @@
 	u_char		*aux;
 	struct internal_scnhdr *section;
 };
+
+struct internal_reloc {
+	unsigned	location;
+	struct internal_syment *sym;
+	int		type;
+	char		*typestr;
+};
--- a/ticoff/main.c	Mon Mar 31 19:06:33 2014 +0000
+++ b/ticoff/main.c	Thu Apr 03 03:03:41 2014 +0000
@@ -13,6 +13,7 @@
 extern int cmd_nm();
 extern int cmd_profile();
 extern int cmd_rawrel();
+extern int cmd_reloc();
 extern int cmd_sechdr();
 extern int cmd_symtab();
 extern int dump_filehdr_info();
@@ -27,6 +28,7 @@
 	{"nm", cmd_nm},
 	{"profile", cmd_profile},
 	{"rawrel", cmd_rawrel},
+	{"reloc", cmd_reloc},
 	{"sechdr", cmd_sechdr},
 	{"symtab", cmd_symtab},
 	{0, 0}
--- a/ticoff/reloc.c	Mon Mar 31 19:06:33 2014 +0000
+++ b/ticoff/reloc.c	Thu Apr 03 03:03:41 2014 +0000
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include "filestruct.h"
 #include "intstruct.h"
+#include "coffconst.h"
 #include "globals.h"
 
 extern unsigned get_u16(), get_u32();
@@ -33,3 +34,92 @@
 	}
 	exit(0);
 }
+
+void
+get_relocs_of_sec(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned n;
+	struct external_reloc *extrel;
+	struct internal_reloc *intrel;
+	unsigned lastloc, symidx;
+
+	if (sec->int_relocs)
+		return;
+	if (!sec->nreloc) {
+		fprintf(stderr,
+	"BUG: get_relocs_of_sec() called for section \"%s\" w/o relocs\n",
+			sec->name);
+		exit(1);
+	}
+	intrel = malloc(sizeof(struct internal_reloc) * sec->nreloc);
+	if (!intrel) {
+		perror("malloc");
+		exit(1);
+	}
+	sec->int_relocs = intrel;
+	extrel = (struct external_reloc *)(filemap + sec->reloc_offset);
+	for (n = 0; n < sec->nreloc; n++, extrel++, intrel++) {
+		intrel->location = get_u32(extrel->r_vaddr);
+		if (n && intrel->location <= lastloc) {
+			fprintf(stderr,
+			"error: non-increasing reloc order in section \"%s\"\n",
+				sec->name);
+			exit(1);
+		}
+		lastloc = intrel->location;
+		symidx = get_u32(extrel->r_symndx);
+		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];
+		intrel->type = get_u16(extrel->r_type);
+		switch (intrel->type) {
+		case RTYPE_LONG:
+			intrel->typestr = "Word32";
+			break;
+		case RTYPE_THUMB_BL:
+			intrel->typestr = "Thumb_BL";
+			break;
+		case RTYPE_ARM_B:
+			intrel->typestr = "ARM_B";
+			break;
+		default:
+			fprintf(stderr,
+		"error: reloc in section \"%s\" of unexpected type 0x%x\n",
+				sec->name, intrel->type);
+			exit(1);
+		}
+		if (get_u16(extrel->r_reserved))
+			fprintf(stderr,
+	"warning: reloc in section \"%s\" has non-zero reserved field\n",
+				sec->name);
+	}
+}
+
+cmd_reloc()
+{
+	unsigned n, m;
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+
+	get_int_section_table();
+	get_int_symbol_table();
+	for (n = 0; n < nsections; n++) {
+		sec = sections + n;
+		if (!sec->nreloc)
+			continue;
+		printf("%s:\n\n", sec->name);
+		get_relocs_of_sec(sec);
+		rel = sec->int_relocs;
+		printf("Location  Type      Symbol relative to\n");
+		for (m = 0; m < sec->nreloc; m++, rel++)
+			printf("%08X  %-8s  %s\n", rel->location, rel->typestr,
+				rel->sym->name);
+		putchar('\n');
+	}
+	exit(0);
+}
--- a/ticoff/tables.c	Mon Mar 31 19:06:33 2014 +0000
+++ b/ticoff/tables.c	Thu Apr 03 03:03:41 2014 +0000
@@ -77,6 +77,7 @@
 				n, sections[n].name);
 		sections[n].nsymbols = 0;
 		sections[n].sorted_symbols = 0;
+		sections[n].int_relocs = 0;
 	}
 }