changeset 156:fc8386b13399

Added 'constant' sections to object file handling for lwasm and lwlink
author lost@l-w.ca
date Sun, 28 Aug 2011 02:06:42 -0600
parents 1571e150f1fd
children 4682460aed00
files lwasm/lwasm.h lwasm/output.c lwasm/section.c lwlink/link.c lwlink/lwlink.h lwlink/map.c lwlink/objdump.c lwlink/readfiles.c
diffstat 8 files changed, 91 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/lwasm.h	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwasm/lwasm.h	Sun Aug 28 02:06:42 2011 -0600
@@ -89,6 +89,7 @@
 enum
 {
 	section_flag_bss = 1,				// BSS section
+	section_flag_constant = 2,			// constants - no base offset
 	section_flag_none = 0				// no flags
 };
 
--- a/lwasm/output.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwasm/output.c	Sun Aug 28 02:06:42 2011 -0600
@@ -427,17 +427,22 @@
 		// write the flags
 		if (s -> flags & section_flag_bss)
 			writebytes("\x01", 1, 1, of);
-		
+		if (s -> flags & section_flag_constant)
+			writebytes("\x02", 1, 1, of);
+			
 		// indicate end of flags - the "" is NOT an error
 		writebytes("", 1, 1, of);
 		
 		// now the local symbols
 		
 		// a symbol for section base address
-		writebytes("\x02", 1, 1, of);
-		writebytes(s -> name, strlen(s -> name) + 1, 1, of);
-		// address 0; "\0" is not an error
-		writebytes("\0", 2, 1, of);
+		if ((s -> flags & section_flag_constant) == 0)
+		{
+			writebytes("\x02", 1, 1, of);
+			writebytes(s -> name, strlen(s -> name) + 1, 1, of);
+			// address 0; "\0" is not an error
+			writebytes("\0", 2, 1, of);
+		}
 		for (se = as -> symtab.head; se; se = se -> next)
 		{
 			lw_expr_t te;
@@ -582,11 +587,20 @@
 		// now blast out the code
 		
 		// length
-		buf[0] = s -> oblen >> 8 & 0xff;
-		buf[1] = s -> oblen & 0xff;
+		if (s -> flags & section_flag_constant)
+		{
+			buf[0] = 0;
+			buf[1] = 0;
+		}
+		else
+		{
+			buf[0] = s -> oblen >> 8 & 0xff;
+			buf[1] = s -> oblen & 0xff;
+		}
 		writebytes(buf, 2, 1, of);
 		
-		if (!(s -> flags & section_flag_bss))
+		
+		if (!(s -> flags & section_flag_bss) && !(s -> flags & section_flag_constant))
 		{
 			writebytes(s -> obytes, s -> oblen, 1, of);
 		}
--- a/lwasm/section.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwasm/section.c	Sun Aug 28 02:06:42 2011 -0600
@@ -98,6 +98,11 @@
 		{
 			s -> flags |= section_flag_bss;
 		}
+		if (!strcasecmp(sn, "_constant"))
+		{
+			s -> flags |= section_flag_constant;
+		}
+		
 		// parse options
 		if (opts)
 		{
@@ -110,6 +115,14 @@
 			{
 				s -> flags &= ~section_flag_bss;
 			}
+			else if (!strcasecmp(opts, "constant"))
+			{
+				s -> flags |= section_flag_constant;
+			}
+			else if (!strcasecmp(opts, "!constant"))
+			{
+				s -> flags |= section_flag_constant;
+			}
 			else
 			{
 				lwasm_register_error(as, l, "Unrecognized section flag");
--- a/lwlink/link.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwlink/link.c	Sun Aug 28 02:06:42 2011 -0600
@@ -45,7 +45,7 @@
 
 	for (sn = 0; sn < fn -> nsections; sn++)
 	{
-		if (!strcmp(name, (char *)(fn -> sections[sn].name)))
+		if (!strcmp(name, (char *)(fn -> sections[sn].name)) && (fn -> sections[sn].flags | SECTION_CONST) == 0)
 		{
 			// we have a match
 			sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1));
@@ -73,6 +73,9 @@
 
 	for (sn = 0; sn < fn -> nsections; sn++)
 	{
+		// ignore "constant" sections
+		if (fn -> sections[sn].flags & SECTION_CONST)
+			continue;
 		// ignore if the noflags tell us to
 		if (noflags && (fn -> sections[sn].flags & noflags))
 			continue;
@@ -154,6 +157,9 @@
 			{
 				for (sn0 = 0; sn0 < inputfiles[fn0] -> nsections; sn0++)
 				{
+					// ignore "constant" sections
+					if (inputfiles[fn0] -> sections[sn0].flags & SECTION_CONST)
+						continue;
 					// ignore if the "no flags" bit says to
 					if (linkscript.lines[ln].noflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].noflags))
 						continue;
@@ -213,6 +219,25 @@
 		{
 			if (!strcmp(sym, (char *)(se -> sym)))
 			{
+				// if the section was not previously processed and is CONSTANT, force it in
+				// otherwise error out if it is not being processed
+				if (fn -> sections[sn].processed == 0)
+				{
+					if (fn -> sections[sn].flags & SECTION_CONST)
+					{
+						// add to section list
+						sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1));
+						sectlist[nsects].ptr = &(fn -> sections[sn]);
+						fn -> sections[sn].processed = 1;
+						fn -> sections[sn].loadaddress = 0;
+						nsects++;
+					}
+					else
+					{
+						// if we're in a non-processed section, bail!
+						continue;
+					}
+				}
 //				fprintf(stderr, "Found symbol %s in %s\n", sym, fn -> filename);
 				if (!(fn -> forced))
 				{
@@ -220,11 +245,15 @@
 					fn -> forced = 1;
 					nforced = 1;
 				}
-				val = se -> offset + fn -> sections[sn].loadaddress;
+				if (fn -> sections[sn].flags & SECTION_CONST)
+					val = se -> offset;
+				else
+					val = se -> offset + fn -> sections[sn].loadaddress;
 				r = lw_expr_stack_create();
 				term = lw_expr_term_create_int(val & 0xffff);
 				lw_expr_stack_push(r, term);
 				lw_expr_term_free(term);
+
 				return r;
 			}
 		}
@@ -276,7 +305,10 @@
 		{
 			if (!strcmp((char *)(se -> sym), sym))
 			{
-				val = se -> offset + sect -> loadaddress;
+				if (sect -> flags & SECTION_CONST)
+					val = se -> offset;
+				else
+					val = se -> offset + sect -> loadaddress;
 				goto out;
 			}
 		}
@@ -287,7 +319,10 @@
 			{
 				if (!strcmp((char *)(se -> sym), sym))
 				{
-					val = se -> offset + sect -> file -> sections[i].loadaddress;
+					if (sect -> file -> sections[i].flags & SECTION_CONST)
+						val = se -> offset;
+					else
+						val = se -> offset + sect -> file -> sections[i].loadaddress;
 					goto out;
 				}
 			}
--- a/lwlink/lwlink.h	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwlink/lwlink.h	Sun Aug 28 02:06:42 2011 -0600
@@ -54,6 +54,7 @@
 typedef struct fileinfo_s fileinfo_t;
 
 #define SECTION_BSS		1
+#define SECTION_CONST	2
 typedef struct
 {
 	unsigned char *name;	// name of the section
--- a/lwlink/map.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwlink/map.c	Sun Aug 28 02:06:42 2011 -0600
@@ -94,7 +94,10 @@
 			}
 			ne = lw_alloc(sizeof(struct symliste));
 			ne -> ext = 0;
-			ne -> addr = sym -> offset + sectlist[sn].ptr -> loadaddress;
+			if (sectlist[sn].ptr -> flags & SECTION_CONST)
+				ne -> addr = sym -> offset;
+			else
+				ne -> addr = sym -> offset + sectlist[sn].ptr -> loadaddress;
 			ne -> next = ce;
 			ne -> name = (char *)(sym -> sym);
 			ne -> fn = sectlist[sn].ptr -> file -> filename;
--- a/lwlink/objdump.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwlink/objdump.c	Sun Aug 28 02:06:42 2011 -0600
@@ -154,6 +154,7 @@
 	long cc;
 	int val;
 	int bss;
+	int constant;
 
 	static char *opernames[] = {
 		"?",
@@ -179,6 +180,7 @@
 	while (1)
 	{
 		bss = 0;
+		constant = 0;
 		
 		// bail out if no more sections
 		if (!(CURBYTE()))
@@ -197,7 +199,11 @@
 				printf("    FLAG: BSS\n");
 				bss = 1;
 				break;
-
+			case 0x02:
+				printf("    FLAG: CONSTANT\n");
+				constant = 1;
+				break;
+				
 			default:
 				printf("    FLAG: %02X (unknown)\n", CURBYTE());
 				break;
--- a/lwlink/readfiles.c	Sun Aug 28 00:07:15 2011 -0600
+++ b/lwlink/readfiles.c	Sun Aug 28 02:06:42 2011 -0600
@@ -198,6 +198,10 @@
 				s -> flags |= SECTION_BSS;
 				break;
 
+			case 0x02:
+				s -> flags |= SECTION_CONST;
+				break;
+				
 			default:
 				fprintf(stderr, "%s (%s): unrecognized section flag %02X\n", fn -> filename, s -> name, (int)(CURBYTE()));
 				exit(1);