changeset 211:71e25510f5af

tiobjd disasm -ll: show the actual line numbers
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Sat, 26 Mar 2016 22:03:08 +0000
parents 24c710b0d6a6
children 422d45f48fe6
files leo-obj/tool/disasm.c leo-obj/tool/intstruct.h leo-obj/tool/ln.c
diffstat 3 files changed, 64 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/leo-obj/tool/disasm.c	Sat Mar 05 02:51:04 2016 +0000
+++ b/leo-obj/tool/disasm.c	Sat Mar 26 22:03:08 2016 +0000
@@ -181,13 +181,14 @@
 	struct hint *hint = sec->hints;
 	u_char *asciz_end;
 	unsigned asciz_len;
-	unsigned *lineno_arr;
+	struct internal_lineno *lineno_arr;
 	unsigned lineno_cur, lineno_total;
 
 	if (sec->nreloc)
 		get_relocs_of_sec(sec);
 	if (disasm_lineno && sec->nlineent)
-		get_lineno_addrs(sec, &lineno_arr, &lineno_total);
+		get_lineno_array(sec, &lineno_arr, &lineno_total,
+				 disasm_lineno >= 2);
 	else {
 		lineno_arr = 0;
 		lineno_total = 0;
@@ -230,13 +231,20 @@
 			gothint = 0;
 		if (gothint && pos == hint->pos && hint->linebrk)
 			putchar('\n');
-		if (lineno_cur < lineno_total) {
-			if (pos >= lineno_arr[lineno_cur]) {
-				puts("; line");
+		while (lineno_cur < lineno_total) {
+			if (pos >= lineno_arr[lineno_cur].location) {
+				if (disasm_lineno >= 2)
+					printf("; line %u\n",
+						lineno_arr[lineno_cur].lineno);
+				else
+					puts("; line");
 				lineno_cur++;
 			} else {
-				if (lineno_arr[lineno_cur] - pos < headroom)
-					headroom = lineno_arr[lineno_cur] - pos;
+				if (lineno_arr[lineno_cur].location - pos <
+				    headroom)
+					headroom =
+					  lineno_arr[lineno_cur].location - pos;
+				break;
 			}
 		}
 		printf("%8x:\t", pos);
--- a/leo-obj/tool/intstruct.h	Sat Mar 05 02:51:04 2016 +0000
+++ b/leo-obj/tool/intstruct.h	Sat Mar 26 22:03:08 2016 +0000
@@ -44,6 +44,11 @@
 	char		*typestr;
 };
 
+struct internal_lineno {
+	unsigned	location;
+	unsigned	lineno;
+};
+
 struct hint {
 	unsigned	pos;
 	unsigned	endpos;
--- a/leo-obj/tool/ln.c	Sat Mar 05 02:51:04 2016 +0000
+++ b/leo-obj/tool/ln.c	Sat Mar 26 22:03:08 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Dumping of line number records
+ * Making use of line number records
  */
 
 #include <sys/types.h>
@@ -32,24 +32,51 @@
 	exit(0);
 }
 
-get_lineno_addrs(sec, arr_rtn, count_rtn)
+static unsigned
+get_lineno_base(func_symidx)
+	unsigned func_symidx;
+{
+	struct internal_syment *func_sym, *bf_sym;
+
+	if (func_symidx >= nsymtab)
+		return 0;
+	func_sym = symtab[func_symidx];
+	if (!func_sym->aux)
+		return 0;
+	if (func_symidx + 2 >= nsymtab)
+		return 0;
+	bf_sym = symtab[func_symidx + 2];
+	if (!bf_sym->aux)
+		return 0;
+	return get_u16(bf_sym->aux + 4);
+}
+
+get_lineno_array(sec, arr_rtn, count_rtn, actual_numbers)
 	struct internal_scnhdr *sec;
-	unsigned **arr_rtn, *count_rtn;
+	struct internal_lineno **arr_rtn;
+	unsigned *count_rtn;
 {
-	unsigned *array, cur, last;
+	struct internal_lineno *array;
+	unsigned cur, last;
 	unsigned n, m;
+	unsigned base, incr;
 	u_char *rec;
 
-	array = malloc(sizeof(unsigned) * sec->nlineent);
+	array = malloc(sizeof(struct internal_lineno) * sec->nlineent);
 	if (!array) {
 		perror("malloc");
 		exit(1);
 	}
 	m = 0;
 	rec = filemap + sec->line_offset;
+	base = 0;
 	for (n = 0; n < sec->nlineent; n++, rec += 6) {
-		if (!get_u16(rec + 4))
+		incr = get_u16(rec + 4);
+		if (!incr) {
+			if (actual_numbers)
+				base = get_lineno_base(get_u32(rec));
 			continue;
+		}
 		cur = get_u32(rec);
 		if (m) {
 			if (cur < last) {
@@ -58,10 +85,19 @@
 					sec->name);
 				exit(1);
 			}
-			if (cur == last)
+			if (cur == last && !actual_numbers)
 				continue;
 		}
-		array[m++] = cur;
+		if (actual_numbers) {
+			if (!base) {
+				fprintf(stderr,
+					"error: no line # base in section %s\n",
+					sec->name);
+				exit(1);
+			}
+			array[m].lineno = base + incr - 1;
+		}
+		array[m++].location = cur;
 		last = cur;
 	}
 	*arr_rtn = array;