changeset 135:df432a4b1b84

tiobjd: disasm of code and data sections unified
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 07 Apr 2014 04:06:17 +0000
parents c131238c56bf
children 81fc8da9a29c
files leo-obj/tool/disasm.c
diffstat 1 files changed, 71 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/leo-obj/tool/disasm.c	Mon Apr 07 02:41:35 2014 +0000
+++ b/leo-obj/tool/disasm.c	Mon Apr 07 04:06:17 2014 +0000
@@ -78,42 +78,47 @@
 	putchar('\n');
 }
 
-void
-disasm_end_of_section(sec, symnum)
-	struct internal_scnhdr *sec;
-	unsigned symnum;
+static void
+handle_symbol(sym, statep, linebrkp)
+	struct internal_syment *sym;
+	int *statep, *linebrkp;
 {
-	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++;
+	if (sym->class == C_FCN && !strcmp(sym->name, ".ef")) {
+		printf("; End function\n");
+		return;
+	}
+	if (!*linebrkp) {
+		putchar('\n');
+		*linebrkp = 1;
+	}
+	if (sym->class == C_FCN && !strcmp(sym->name, ".bf")) {
+		printf("; Begin function\n");
+		return;
 	}
-	printf("%8x:\t<end of section>\n", sec->size);
+	switch (sym->class) {
+	case C_EXT:
+		sym_comment = "Global";
+		break;
+	case C_STAT:
+		sym_comment = "static";
+		break;
+	case C_LABEL:
+		sym_comment = "label";
+		if (!strcmp(sym->name, "$CODE16"))
+			*statep = 1;
+		else if (!strcmp(sym->name, "$CODE32"))
+			*statep = 0;
+		break;
+	default:
+		sym_comment = "unexpected class!";
+	}
+	printf("%s:\t; %s\n", sym->name, sym_comment);
 }
 
 void
-disasm_text_section(sec)
+disasm_codedata_section(sec)
 	struct internal_scnhdr *sec;
 {
 	unsigned symnum, relnum;
@@ -121,11 +126,7 @@
 	int state = -1, linebrk = 0;
 	struct internal_syment *sym;
 	struct internal_reloc *rel;
-	char *sym_comment;
 
-	printf("Disassembling code section:\n");
-	if (sec->nsymbols)
-		sort_symbols_of_sec(sec);
 	if (sec->nreloc)
 		get_relocs_of_sec(sec);
 	symnum = relnum = 0;
@@ -139,28 +140,7 @@
 				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";
-				if (!strcmp(sym->name, "$CODE16"))
-					state = 1;
-				else if (!strcmp(sym->name, "$CODE32"))
-					state = 0;
-				break;
-			default:
-				sym_comment = "unexpected class!";
-			}
-			printf("%s:\t; %s\n", sym->name, sym_comment);
+			handle_symbol(sym, &state, &linebrk);
 			symnum++;
 		}
 		if (relnum < sec->nreloc) {
@@ -175,14 +155,19 @@
 		} else
 			rel = 0;
 		printf("%8x:\t", pos);
-		if (rel && rel->type == RTYPE_LONG) {
-			if (pos & 3) {
-			  printf("MISALIGNED pos for word32 reloc, aborting\n");
+		if (rel) {
+			if (rel->type == RTYPE_LONG) {
+				if (pos & 3) {
+			printf("MISALIGNED pos for word32 reloc, aborting\n");
+					return;
+				}
+				disasm_word32_reloc(sec, rel);
+				incr = 4;
+				goto next;
+			} else if (sec->disasm_mode == DISASM_MODE_DATA) {
+		printf("error: reloc other than word32 in data section\n");
 				return;
 			}
-			disasm_word32_reloc(sec, rel);
-			incr = 4;
-			goto next;
 		}
 		if (pos & 1 || headroom < 2) {
 			if (rel) {
@@ -193,6 +178,18 @@
 			incr = 1;
 			goto next;
 		}
+		if (sec->disasm_mode == DISASM_MODE_DATA) {
+			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;
+			}
+			goto next;
+		}
 		switch (state) {
 		case 0:		/* ARM */
 			if (pos & 3) {
@@ -239,101 +236,18 @@
 			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);
+	if (symnum == sec->nsymbols)
+		return;
+	while (symnum < sec->nsymbols) {
+		sym = sec->sorted_symbols[symnum];
+		if (sym->value != sec->size) {
+			printf("error: expecting symbol at end of section\n");
 			return;
 		}
+		handle_symbol(sym, &state, &linebrk);
+		symnum++;
 	}
-	if (symnum < sec->nsymbols)
-		disasm_end_of_section(sec, symnum);
+	printf("%8x:\t<end of section>\n", sec->size);
 }
 
 void
@@ -360,10 +274,12 @@
 {
 	switch (sec->disasm_mode) {
 	case DISASM_MODE_CODE:
-		disasm_text_section(sec);
+		printf("Disassembling code section:\n");
+		disasm_codedata_section(sec);
 		return;
 	case DISASM_MODE_DATA:
-		disasm_data_section(sec);
+		printf("Disassembling data section:\n");
+		disasm_codedata_section(sec);
 		return;
 	case DISASM_MODE_BSS:
 		disasm_bss(sec);