# HG changeset patch # User lost@l-w.ca # Date 1314518802 21600 # Node ID fc8386b13399e961a1bd7b1d27af860fd69e1843 # Parent 1571e150f1fd8d4f98a6be026827afd7d1c3f4e1 Added 'constant' sections to object file handling for lwasm and lwlink diff -r 1571e150f1fd -r fc8386b13399 lwasm/lwasm.h --- 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 }; diff -r 1571e150f1fd -r fc8386b13399 lwasm/output.c --- 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); } diff -r 1571e150f1fd -r fc8386b13399 lwasm/section.c --- 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"); diff -r 1571e150f1fd -r fc8386b13399 lwlink/link.c --- 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; } } diff -r 1571e150f1fd -r fc8386b13399 lwlink/lwlink.h --- 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 diff -r 1571e150f1fd -r fc8386b13399 lwlink/map.c --- 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; diff -r 1571e150f1fd -r fc8386b13399 lwlink/objdump.c --- 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; diff -r 1571e150f1fd -r fc8386b13399 lwlink/readfiles.c --- 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);