diff ticoff/disasm.c @ 124:700d77d5cf00

tiobjd disasm: data section handling added
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Fri, 04 Apr 2014 18:39:01 +0000
parents 5f9cc99930a8
children b8ac21536779
line wrap: on
line diff
--- a/ticoff/disasm.c	Fri Apr 04 08:12:29 2014 +0000
+++ b/ticoff/disasm.c	Fri Apr 04 18:39:01 2014 +0000
@@ -75,6 +75,40 @@
 }
 
 void
+disasm_end_of_section(sec, symnum)
+	struct internal_scnhdr *sec;
+	unsigned symnum;
+{
+	struct internal_syment *sym;
+	char *sym_comment;
+
+	putchar('\n');
+	while (symnum < sec->nsymbols) {
+		sym = sec->sorted_symbols[symnum];
+		if (sym->value != sec->size) {
+			printf("error: expecting symbol at end of section\n");
+			return;
+		}
+		switch (sym->class) {
+		case C_EXT:
+			sym_comment = "Global";
+			break;
+		case C_STAT:
+			sym_comment = "static";
+			break;
+		case C_LABEL:
+			sym_comment = "label";
+			break;
+		default:
+			sym_comment = "unexpected class!";
+		}
+		printf("%s:\t; %s\n", sym->name, sym_comment);
+		symnum++;
+	}
+	printf("%8x:\t<end of section>\n", sec->size);
+}
+
+void
 disasm_text_section(sec)
 	struct internal_scnhdr *sec;
 {
@@ -201,6 +235,101 @@
 			return;
 		}
 	}
+	if (symnum < sec->nsymbols)
+		disasm_end_of_section(sec, symnum);
+}
+
+void
+disasm_data_section(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned symnum, relnum;
+	unsigned pos, incr, headroom;
+	int linebrk = 0;
+	struct internal_syment *sym;
+	struct internal_reloc *rel;
+	char *sym_comment;
+
+	printf("Disassembling data section:\n");
+	if (sec->nsymbols)
+		sort_symbols_of_sec(sec);
+	if (sec->nreloc)
+		get_relocs_of_sec(sec);
+	symnum = relnum = 0;
+	for (pos = 0; pos < sec->size; pos += incr) {
+		headroom = sec->size - pos;
+		while (symnum < sec->nsymbols) {
+			sym = sec->sorted_symbols[symnum];
+			if (sym->value > pos) {
+				if (sym->value - pos < headroom)
+					headroom = sym->value - pos;
+				break;
+			}
+			/* hit symbol */
+			if (!linebrk) {
+				putchar('\n');
+				linebrk = 1;
+			}
+			switch (sym->class) {
+			case C_EXT:
+				sym_comment = "Global";
+				break;
+			case C_STAT:
+				sym_comment = "static";
+				break;
+			case C_LABEL:
+				sym_comment = "label";
+				break;
+			default:
+				sym_comment = "unexpected class!";
+			}
+			printf("%s:\t; %s\n", sym->name, sym_comment);
+			symnum++;
+		}
+		if (relnum < sec->nreloc) {
+			rel = sec->int_relocs + relnum;
+			if (rel->location == pos)
+				relnum++;	/* it's ours */
+			else {
+				if (rel->location - pos < headroom)
+					headroom = rel->location - pos;
+				rel = 0;	/* no reloc for current pos */
+			}
+		} else
+			rel = 0;
+		printf("%8x:\t", pos);
+		if (rel) {
+			if (rel->type != RTYPE_LONG) {
+		printf("error: reloc other than word32 in data section\n");
+				return;
+			}
+			if (pos & 3) {
+			  printf("MISALIGNED pos for word32 reloc, aborting\n");
+				return;
+			}
+			disasm_word32_reloc(sec, rel);
+			incr = 4;
+		} else if (pos & 1 || headroom < 2) {
+			printf("%02x\n", filemap[sec->data_offset + pos]);
+			incr = 1;
+		} else if (pos & 2 || headroom < 4) {
+			printf("%04x\n",
+				get_u16(filemap + sec->data_offset + pos));
+			incr = 2;
+		} else {
+			printf("%08x\n",
+				get_u32(filemap + sec->data_offset + pos));
+			incr = 4;
+		}
+		linebrk = 0;
+		if (incr > headroom) {
+			printf("error: increment %u > headroom %u, aborting\n",
+				incr, headroom);
+			return;
+		}
+	}
+	if (symnum < sec->nsymbols)
+		disasm_end_of_section(sec, symnum);
 }
 
 void
@@ -209,6 +338,12 @@
 {
 	if (!strncmp(sec->name, ".text", 5))
 		disasm_text_section(sec);
+	else if (!strcmp(sec->name, ".const"))
+		disasm_data_section(sec);
+	else if (!strcmp(sec->name, ".cinit"))
+		disasm_data_section(sec);
+	else if (!strcmp(sec->name, ".data"))
+		disasm_data_section(sec);
 	/* other section types to be added */
 	else
 		printf("Unrecognized section type, skipped\n");