summary refs log tree commit diff
diff options
context:
space:
mode:
authorThomas Bracht Laumann Jespersen <t@laumann.xyz>2023-01-26 12:09:44 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2023-06-06 18:44:51 +0200
commit0d929287d77ccc3fb52ca8bd072678b5ae2c81c8 (patch)
tree72cf91ec66052797059734c9d089a49a69b47122
parente493a7f23352f51acc0a1e12284ab19d7894488a (diff)
downloadroux-0d929287d77ccc3fb52ca8bd072678b5ae2c81c8.tar.gz
implement line number info tracking
Support "file" and "loc" directives. "file" takes a string (a file name)
assigns it a number, sets the current file to that number and records
the string for later. "loc" takes a single number and outputs location
information with a reference to the current file.
-rw-r--r--all.h4
-rw-r--r--amd64/emit.c3
-rw-r--r--amd64/isel.c1
-rw-r--r--arm64/emit.c3
-rw-r--r--emit.c32
-rw-r--r--main.c8
-rw-r--r--ops.h2
-rw-r--r--parse.c20
-rw-r--r--rv64/emit.c3
-rw-r--r--tools/lexh.c6
10 files changed, 75 insertions, 7 deletions
diff --git a/all.h b/all.h
index b6591f0..4d36314 100644
--- a/all.h
+++ b/all.h
@@ -502,7 +502,7 @@ bshas(BSet *bs, uint elt)
 
 /* parse.c */
 extern Op optab[NOp];
-void parse(FILE *, char *, void (Dat *), void (Fn *));
+void parse(FILE *, char *, void (char *), void (Dat *), void (Fn *));
 void printfn(Fn *, FILE *);
 void printref(Ref, Fn *, FILE *);
 void err(char *, ...) __attribute__((noreturn));
@@ -568,6 +568,8 @@ void rega(Fn *);
 /* emit.c */
 void emitfnlnk(char *, Lnk *, FILE *);
 void emitdat(Dat *, FILE *);
+void emitdbgfile(char *, FILE *);
+void emitdbgloc(uint, FILE *);
 int stashbits(void *, int);
 void elf_emitfnfin(char *, FILE *);
 void elf_emitfin(FILE *);
diff --git a/amd64/emit.c b/amd64/emit.c
index 46de3d9..2290d2d 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -547,6 +547,9 @@ emitins(Ins i, Fn *fn, FILE *f)
 		emitcopy(i.arg[0], i.arg[1], i.cls, fn, f);
 		emitcopy(i.arg[1], TMP(XMM0+15), i.cls, fn, f);
 		break;
+	case Oloc:
+		emitdbgloc(i.arg[0].val, f);
+		break;
 	}
 }
 
diff --git a/amd64/isel.c b/amd64/isel.c
index 3d5d5a9..277063f 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -392,6 +392,7 @@ sel(Ins i, ANum *an, Fn *fn)
 	case_Oload:
 		seladdr(&i.arg[0], an, fn);
 		goto Emit;
+	case Oloc:
 	case Ocall:
 	case Osalloc:
 	case Ocopy:
diff --git a/arm64/emit.c b/arm64/emit.c
index ee1593f..5ca6e79 100644
--- a/arm64/emit.c
+++ b/arm64/emit.c
@@ -446,6 +446,9 @@ emitins(Ins *i, E *e)
 		if (!req(i->to, R))
 			emitf("mov %=, sp", i, e);
 		break;
+	case Oloc:
+		emitdbgloc(i->arg[0].val, e->f);
+		break;
 	}
 }
 
diff --git a/emit.c b/emit.c
index 017c461..b880d67 100644
--- a/emit.c
+++ b/emit.c
@@ -207,3 +207,35 @@ macho_emitfin(FILE *f)
 
 	emitfin(f, sec);
 }
+
+static uint32_t *file;
+static uint nfile;
+static uint curfile;
+
+void
+emitdbgfile(char *fn, FILE *f)
+{
+	uint32_t id;
+	uint n;
+
+	id = intern(fn);
+	for (n=0; n<nfile; n++)
+		if (file[n] == id) {
+			/* gas requires positive
+			 * file numbers */
+			curfile = n + 1;
+			return;
+		}
+	if (!file)
+		file = vnew(0, sizeof *file, PHeap);
+	vgrow(&file, ++nfile);
+	file[nfile-1] = id;
+	curfile = nfile;
+	fprintf(f, ".file %u %s\n", curfile, fn);
+}
+
+void
+emitdbgloc(uint loc, FILE *f)
+{
+	fprintf(f, "\t.loc %u %u\n", curfile, loc);
+}
diff --git a/main.c b/main.c
index abfe03e..5ecb4d0 100644
--- a/main.c
+++ b/main.c
@@ -107,6 +107,12 @@ func(Fn *fn)
 	freeall();
 }
 
+static void
+dbgfile(char *fn)
+{
+	emitdbgfile(fn, outf);
+}
+
 int
 main(int ac, char *av[])
 {
@@ -181,7 +187,7 @@ main(int ac, char *av[])
 				exit(1);
 			}
 		}
-		parse(inf, f, data, func);
+		parse(inf, f, dbgfile, data, func);
 		fclose(inf);
 	} while (++optind < ac);
 
diff --git a/ops.h b/ops.h
index fbcc2a8..e0be8d0 100644
--- a/ops.h
+++ b/ops.h
@@ -121,6 +121,8 @@ O(vastart, T(m,e,e,e, x,e,e,e), 0) X(0, 0, 0) V(0)
 
 O(copy,    T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0)
 
+/* Debug */
+O(loc,     T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0)
 
 /****************************************/
 /* INTERNAL OPERATIONS (keep nop first) */
diff --git a/parse.c b/parse.c
index c54448f..5b9f60e 100644
--- a/parse.c
+++ b/parse.c
@@ -53,6 +53,7 @@ enum Token {
 	Tdata,
 	Tsection,
 	Talign,
+	Tfile,
 	Tl,
 	Tw,
 	Tsh,
@@ -110,6 +111,7 @@ static char *kwmap[Ntok] = {
 	[Tdata] = "data",
 	[Tsection] = "section",
 	[Talign] = "align",
+	[Tfile] = "file",
 	[Tsb] = "sb",
 	[Tub] = "ub",
 	[Tsh] = "sh",
@@ -130,7 +132,7 @@ enum {
 	TMask = 16383, /* for temps hash */
 	BMask = 8191, /* for blocks hash */
 
-	K = 9583425, /* found using tools/lexh.c */
+	K = 10525445, /* found using tools/lexh.c */
 	M = 23,
 };
 
@@ -655,6 +657,16 @@ parseline(PState ps)
 		expect(Tnl);
 		closeblk();
 		return PLbl;
+	case Oloc:
+		expect(Tint);
+		op = Oloc;
+		k = Kw;
+		r = R;
+		arg[0] = INT(tokval.num);
+		if (arg[0].val != tokval.num)
+			err("line number too big");
+		arg[1] = R;
+		goto Ins;
 	}
 	r = tmpref(tokval.str);
 	expect(Teq);
@@ -1160,7 +1172,7 @@ parselnk(Lnk *lnk)
 }
 
 void
-parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
+parse(FILE *f, char *path, void dbgfile(char *), void data(Dat *), void func(Fn *))
 {
 	Lnk lnk;
 	uint n;
@@ -1177,6 +1189,10 @@ parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
 		switch (parselnk(&lnk)) {
 		default:
 			err("top-level definition expected");
+		case Tfile:
+			expect(Tstr);
+			dbgfile(tokval.str);
+			break;
 		case Tfunc:
 			func(parsefn(&lnk));
 			break;
diff --git a/rv64/emit.c b/rv64/emit.c
index acb6df3..6044dee 100644
--- a/rv64/emit.c
+++ b/rv64/emit.c
@@ -405,6 +405,9 @@ emitins(Ins *i, Fn *fn, FILE *f)
 		if (!req(i->to, R))
 			emitf("mv %=, sp", i, fn, f);
 		break;
+	case Oloc:
+		emitdbgloc(i->arg[0].val, f);
+		break;
 	}
 }
 
diff --git a/tools/lexh.c b/tools/lexh.c
index 5ceb4ee..8883976 100644
--- a/tools/lexh.c
+++ b/tools/lexh.c
@@ -23,11 +23,11 @@ char *tok[] = {
 	"ceql", "cnel", "cles", "clts", "cgts", "cges",
 	"cnes", "ceqs", "cos", "cuos", "cled", "cltd",
 	"cgtd", "cged", "cned", "ceqd", "cod", "cuod",
-	"vaarg", "vastart", "...", "env",
+	"vaarg", "vastart", "...", "env", "loc",
 
 	"call", "phi", "jmp", "jnz", "ret", "hlt", "export",
-	"function", "type", "data", "section", "align", "blit",
-	"l", "w", "sh", "uh", "h", "sb", "ub", "b",
+	"function", "type", "data", "section", "align", "file",
+	"blit", "l", "w", "sh", "uh", "h", "sb", "ub", "b",
 	"d", "s", "z", "loadw", "loadl", "loads", "loadd",
 	"alloc1", "alloc2",