/* * Print a number of variable values for NcML */ static void pr_any_valsx( const ncvar_t *vp, /* variable */ size_t len, /* number of values to print */ bool_t more, /* true if more data for this row will * follow, so add trailing comma */ bool_t lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const void *vals /* pointer to block of values */ ) { long iel; safebuf_t *sb = sbuf_new(); const char *valp = (const char *)vals; for (iel = 0; iel < len-1; iel++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ sbuf_cat(sb, " "); lput(sbuf_str(sb)); } print_any_val(sb, vp, (void *)valp); lput(sbuf_str(sb)); lastdelim2x (more, lastrow); sbuf_free(sb); }
void putsymb(char *s, int t, int32 v, int ver, Sym *go) { int i, f; vlong gv; if(t == 'f') s++; lput(v); if(ver) t += 'a' - 'A'; cput(t+0x80); /* 0x80 is variable length */ if(t == 'Z' || t == 'z') { cput(s[0]); for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { cput(s[i]); cput(s[i+1]); } cput(0); cput(0); i++; } else { for(i=0; s[i]; i++) cput(s[i]); cput(0); } gv = 0; if(go) { if(!go->reachable) sysfatal("unreachable type %s", go->name); gv = go->value+INITDAT; } lput(gv); symsize += 4 + 1 + i+1 + 4; if(debug['n']) { if(t == 'z' || t == 'Z') { Bprint(&bso, "%c %.8lux ", t, v); for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); Bprint(&bso, "/%x", f); } Bprint(&bso, "\n"); return; } if(ver) Bprint(&bso, "%c %.8lux %s<%d> %s (%.8llux)\n", t, v, s, ver, go ? go->name : "", gv); else Bprint(&bso, "%c %.8lux %s\n", t, v, s, go ? go->name : "", gv); } }
/* * print last delimiter in each line before annotation (, or ;) */ static void lastdelim2x (bool_t more, bool_t lastrow) { if (more) { lput(" "); } else { if(lastrow) { lput("\n "); } else { lput("\n "); } } }
void swap (canon_info_t *cn, canon_line_t v[], int i, int j) { canon_line_t temp, line2; if (cn->lio == CANON_MEM) { temp = v[i]; v[i] = v[j]; v[j] = temp; } else { lget (i, &temp, cn); lget (j, &line2, cn); lput (j, &temp, cn); lput (i, &line2, cn); } }
/* * print last delimiter in each line before annotation (, or ;) */ static void lastdelim2 (boolean more, boolean lastrow) { if (more) { lput(", "); } else { if(lastrow) { lput(" ;"); lput("\n"); } else { lput(",\n"); lput(" "); } } }
void putsymb(char *s, int t, vlong v, int ver) { int i, f, l; if(t == 'f') s++; l = 4; switch(HEADTYPE){ default: break; case 5: if(debug['8']) break; case 2: case 6: lput(v>>32); l = 8; break; } lput(v); if(ver) t += 'a' - 'A'; cput(t+0x80); /* 0x80 is variable length */ if(t == 'Z' || t == 'z') { cput(s[0]); for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { cput(s[i]); cput(s[i+1]); } cput(0); cput(0); i++; } else { for(i=0; s[i]; i++) cput(s[i]); cput(0); } symsize += l + 1 + i + 1; if(debug['n']) { if(t == 'z' || t == 'Z') { Bprint(&bso, "%c %.8llux ", t, v); for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); Bprint(&bso, "/%x", f); } Bprint(&bso, "\n"); return; } if(ver) Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver); else Bprint(&bso, "%c %.8llux %s\n", t, v, s); } }
/* * Print a number of double variable values, where the optional comments * for each value identify the variable, and each dimension index. */ static void pr_dvals( const struct ncvar *vp, /* variable */ long len, /* number of values to print */ const char *fmt, /* printf format used for each value. If * nc_type is NC_CHAR and this is NULL, * character arrays will be printed as * strings enclosed in quotes. */ boolean more, /* true if more data for this row will * follow, so add trailing comma */ boolean lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const double *vals, /* pointer to block of values */ const struct fspec* fsp, /* formatting specs */ const long *cor /* corner coordinates */ ) { long iel; char sout[100]; /* temporary string for each encoded output */ for (iel = 0; iel < len-1; iel++) { printdval(sout, fmt, vp, *vals++); if (fsp->full_data_cmnts) { Printf("%s", sout); Printf(","); annotate (vp, fsp, cor, iel); } else { (void) strcat(sout, ", "); lput(sout); } } printdval(sout, fmt, vp, *vals++); if (fsp->full_data_cmnts) { Printf("%s", sout); lastdelim (more, lastrow); annotate (vp, fsp, cor, iel); } else { lput(sout); lastdelim2 (more, lastrow); } }
/* * Print a number of variable values, where the optional comments * for each value identify the variable, and each dimension index. */ static void pr_any_vals( const ncvar_t *vp, /* variable */ size_t len, /* number of values to print */ boolean more, /* true if more data for this row will * follow, so add trailing comma */ boolean lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const void *vals, /* pointer to block of values */ const fspec_t* fsp, /* formatting specs */ const size_t *cor /* corner coordinates */ ) { long iel; safebuf_t *sb = sbuf_new(); const char *valp = (const char *)vals; for (iel = 0; iel < len-1; iel++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (fsp->full_data_cmnts) { printf(sb->buf); printf(","); annotate (vp, fsp, cor, iel); } else { sbuf_cat(sb, ", "); lput(sbuf_str(sb)); } } print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (fsp->full_data_cmnts) { printf(sbuf_str(sb)); lastdelim (more, lastrow); annotate (vp, fsp, cor, iel); } else { lput(sbuf_str(sb)); lastdelim2 (more, lastrow); } sbuf_free(sb); }
void set_skip_attr (canon_info_t *ci, parse_info_t *pi) { canon_line_t lrec; if (ci->lio == CANON_DISK) { lget (pi->num_lines, &lrec, ci); lrec.skip_attr = 1; lput (pi->num_lines, &lrec, ci); } else lineptr[pi->num_lines].skip_attr = 1; }
/* * Print a number of attribute values */ void pr_any_att_vals( const ncatt_t *ap, /* attribute */ const void *vals /* pointer to block of values */ ) { size_t iel; size_t len = ap->len; /* number of values to print */ const char *valp = (const char *)vals; safebuf_t *sb = sbuf_new(); for (iel = 0; iel < len - 1; iel++) { print_any_att_val(sb, ap, (void *)valp); valp += ap->tinfo->size; /* next value according to type */ sbuf_cat(sb, iel == len - 1 ? "" : ", "); lput(sbuf_str(sb)); } print_any_att_val(sb, ap, (void *)valp); lput(sbuf_str(sb)); sbuf_free(sb); }
void putsymb(char *s, int t, long v, int ver) { int i, f; if(t == 'f') s++; lput(v); if(ver) t += 'a' - 'A'; cput(t+0x80); /* 0x80 is variable length */ if(t == 'Z' || t == 'z') { cput(s[0]); for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { cput(s[i]); cput(s[i+1]); } cput(0); cput(0); i++; } else { for(i=0; s[i]; i++) cput(s[i]); cput(0); } symsize += 4 + 1 + i + 1; if(debug['n']) { if(t == 'z' || t == 'Z') { Bprint(&bso, "%c %.8lux ", t, v); for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); Bprint(&bso, "/%x", f); } Bprint(&bso, "\n"); return; } if(ver) Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver); else Bprint(&bso, "%c %.8lux %s\n", t, v, s); } }
/* * Print the attribute identifier at the beginning of the line */ void canonicalize_key_attr (parse_info_t *obj, canon_info_t *canon_info, int lncont) { char buf[64]; int num_spaces; canon_line_t lrec; /* fprintf (stderr,"canonicalize_key_attr: attr=(%s)\n", attr_name[obj->curr_attr]); */ if (!canon_info->do_canon) return; num_spaces = ATTR_ID_LENGTH - strlen (attr_name[obj->curr_attr]) - 1; if (num_spaces > 0) sprintf(buf, "%%s:%%b%d", num_spaces); else sprintf(buf, "%%s:"); parse_buf_add (canon_info, buf, attr_name[obj->curr_attr]); /* if we are doing line continuation then exit * as we have already done the next part */ if (lncont) return; /* init the curr attribute type and count for this field */ if (canon_info->lio == CANON_MEM) { lineptr[obj->num_lines].attr = obj->curr_attr; lineptr[obj->num_lines].count = obj->attrs[obj->curr_attr] + 1; } else { lget (obj->num_lines, &lrec, canon_info); lrec.attr = obj->curr_attr; lrec.count = obj->attrs[obj->curr_attr] + 1; lput (obj->num_lines, &lrec, canon_info); } }
void asmb(void) { Prog *p; long t; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue() & ~KMASK); /* entry vaddr */ lput(52L); /* offset to first phdr */ lput(0L); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|0L); /* # Phdrs & Shdr size */ lput((0L<<16)|0L); /* # Shdrs & shdr string size */ lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT & ~KMASK); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize); /* file size */ lput(textsize); /* memory size */ lput(0x05L); /* protections = RX */ lput(0x10000L); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT & ~KMASK); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0x10000L); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); lput(0L); lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ break; } cflush(); }
void rpsl_lncont (parse_info_t *obj, canon_info_t *canon_info, int add_line_feed) { int i, j = 0, state = 0; char c, d; canon_line_t lrec; /* if (verbose) */ fprintf (dfile, "1 error-pos (%d) line-len (%d) num_lines (%d) \n", obj->error_pos, obj->eline_len, obj->num_lines); if (!canon_info->do_canon) return; /* Reset the parse buffer pointer to the beginning of * the line to overwrite any fragment of the canonicalized * line we have already parsed. */ dump_current_canon_line (canon_info); /* reset the number of lines */ if (canon_info->lio == CANON_MEM) lineptr[obj->num_lines].lines = obj->elines; else { lget (obj->num_lines, &lrec, canon_info); lrec.lines = obj->elines; lput (obj->num_lines, &lrec, canon_info); } if (fseek (canon_info->efd, 0, SEEK_SET) != EOF) { /* put in the attribute ID */ canonicalize_key_attr (obj, canon_info, 1); for (i = 0; i < obj->eline_len && (c = fgetc (canon_info->efd)) != EOF; i++) { if (state == 0) { /* initial state, skip past attr */ if (c == ':') state = 1; } else if (state == 1) { /* at the ATTR_ID_LEN, * get rid of spaces */ if (c == ' ' || c == '\t') continue; parse_buf_add (canon_info, "%c", &c); state = 2; } else if (state == 2) { /* print non-blank characters */ if (c == ' ' || c == '\t') { /* go to string trim state */ j = 1; state = 3; continue; } if (c == '\n') state = 4; parse_buf_add (canon_info, "%c", &c); } else if (state == 3) { /* string trim, remove trailing blanks */ if (c == ' ' || c == '\t') { j++; continue; } if (c == '\n') state = 4; else { /* print non-blank char and spaces */ d = ' '; for (; j > 0; j--) parse_buf_add (canon_info, "%c", &d); state = 2; } parse_buf_add (canon_info, "%c", &c); } else if (state == 4) { /* print line continuation char * and pad with space */ parse_buf_add (canon_info, "%c", &c); c = ' '; for (j = 1;(ATTR_ID_LENGTH - j) > 0; j++) parse_buf_add (canon_info, "%c", &c); state = 1; } } } else { parse_buf_add (canon_info, "%s", "INTERNAL ERROR: could not read error line!\n"); add_line_feed = 0; } if (add_line_feed) parse_buf_add (canon_info, "\n"); /* terminate the line */ parse_buf_add (canon_info, "%z"); return; }
void asmb(void) { Prog *p; long t; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 3: seek(cout, HEADR+textsize, 0); break; case 1: case 2: seek(cout, HEADR+textsize, 0); break; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 3: seek(cout, HEADR+textsize+datsize, 0); break; case 2: case 1: seek(cout, HEADR+textsize+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); /* round up file length for boot image */ if(HEADTYPE == 0 || HEADTYPE == 3) if((symsize+lcsize) & 1) CPUT(0); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: break; case 2: lput(4*13*13+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: lput(0x1030107); /* magic and sections */ lput(0x90100000); #define SPARC_NOOP 0x01000000 lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); break; } cflush(); }
/* Print data values for variable varid. * * Recursive to handle possibility of variables with multiple * unlimited dimensions, for which the CDL syntax requires use of "{" * and "}" in data section to disambiguate the size of nested records * in a simple linear list of values. */ static int print_rows( int level, /* 0 at top-level, incremented for each recursive level */ int ncid, /* netcdf id */ int varid, /* variable id */ const ncvar_t *vp, /* variable */ size_t ncols, /* number of values in a row */ int rank, /* number of elements in following 3 arrays */ size_t vdims[], /* variable dimension sizes */ size_t cor[], /* corner coordinates */ size_t edg[], /* edges of hypercube */ void *vals, /* allocated buffer for ncols values in a row */ int marks_pending /* number of pending closing "}" record markers */ ) { int d0 = 0; size_t inc = 1; int i; bool_t mark_record = (level > 0 && is_unlim_dim(ncid, vp->dims[level])); safebuf_t *sb = sbuf_new(); if (rank > 0) d0 = vdims[level]; for(i = level + 1; i < rank; i++) { inc *= vdims[i]; } if(mark_record) { /* the whole point of this recursion is printing these "{}" */ lput("{"); marks_pending++; /* matching "}"s to emit after last "row" */ } if(rank - level > 1) { /* this level is just d0 next levels */ size_t *local_cor = emalloc((rank + 1) * sizeof(size_t)); size_t *local_edg = emalloc((rank + 1) * sizeof(size_t)); for(i = 0; i < rank; i++) { local_cor[i] = cor[i]; local_edg[i] = edg[i]; } local_cor[level] = 0; local_edg[level] = 1; for(i = 0; i < d0 - 1; i++) { print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims, local_cor, local_edg, vals, 0); local_cor[level] += 1; } print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims, local_cor, local_edg, vals, marks_pending); free(local_edg); free(local_cor); } else { /* bottom out of recursion */ char *valp = vals; bool_t lastrow; int j; if(formatting_specs.brief_data_cmnts && rank > 1) { annotate_brief(vp, cor, vdims); } NC_CHECK(nc_get_vara(ncid, varid, cor, edg, (void *)valp)); for(i=0; i < d0 - 1; i++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (formatting_specs.full_data_cmnts) { printf("%s, ", sb->buf); annotate (vp, cor, i); } else { sbuf_cat(sb, ", "); lput(sbuf_str(sb)); } } print_any_val(sb, vp, (void *)valp); /* determine if this is the last row */ lastrow = true; for(j = 0; j < rank - 1; j++) { if (cor[j] != vdims[j] - 1) { lastrow = false; break; } } if (formatting_specs.full_data_cmnts) { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } printf("%s", sbuf_str(sb)); lastdelim (0, lastrow); annotate (vp, cor, i); } else { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } lput(sbuf_str(sb)); lastdelim2 (0, lastrow); } } sbuf_free(sb); return NC_NOERR; }
/* Our memory parse buffer is not large enough to hold the * canonicalized object, flush it to disk. Function opens up * a temp parse file 'flushfn' to hold the object. Each of * the lines in the memory buffer are copied to the disk buffer. * * Return: * pointer to the disk streams pointer. */ FILE *flush_parse_buffer (canon_info_t *cn) { char *p; int i, fd; FILE *fp; canon_line_t lrec; if (cn->fd != NULL) { fprintf (dfile, "Overflow buffer called a second time. Abort!\n"); exit (0); } strcpy (cn->flushfn, cn->flushfntmpl); fd = mkstemp (cn->flushfn); if ((fp = fdopen (fd, "w+")) == NULL) { fprintf (stderr, "Cannot open disk parse buffer (%s). Abort!\n", cn->flushfn); exit (0); } if (verbose) fprintf (dfile, "*****flush buffer to disk****\n:%s:\n",cn->buffer); /* Make sure last char is a NULL byte, we * could be in the middle of a string */ *cn->bufp = '\0'; if (cn->lio == CANON_DISK) fseek (cn->lfd, 0, SEEK_SET); for (i = 0, p = cn->buffer; p != NULL && p < cn->bufp; i++) { cn->flinep = ftell (fp); if (cn->lio == CANON_MEM) lineptr[i].fpos = cn->flinep; else { lget (i, &lrec, cn); lrec.fpos = cn->flinep; if (verbose) fprintf (dfile, "flush buf line pos (%ld)\n", lrec.fpos); lput (i, &lrec, cn); } fputs (p, fp); if ((p = strchr (p, '\0')) != NULL) p++; } if (verbose) fprintf (dfile, "flush_parse_buffer () number of lines flushed to disk (%d)\n", i); /* set the begining of line pointer (ie, cn->flinep) */ if (cn->linep == cn->bufp) { /* we are at the beginning of a line */ cn->flinep = ftell (fp); if (verbose) fprintf (dfile, "flush buf: we are at the beginning of a line...\n"); if (cn->lio == CANON_MEM) lineptr[i].fpos = cn->flinep; else { lget (i, &lrec, cn); lrec.fpos = cn->flinep; if (verbose) fprintf (dfile, "flush buf line pos (%ld)\n", lrec.fpos); lput (i, &lrec, cn); } } cn->io = CANON_DISK; cn->buf_space_left = 0; return fp; }
void asmb(void) { Prog *p; long t, magic; Optab *o; vlong vl; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 8; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %llux sb %llux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 9: case 10: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 9: case 10: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: if(dlm) lput(0x80000000 | (4*21*21+7)); /* q.out magic */ else lput(4*21*21+7); /* q.out magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 2: /* plan9 */ magic = 4*27*27+7; magic |= 0x00008000; /* fat header */ if(dlm) magic |= 0x80000000; /* dlm */ lput(magic); lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ vl = entryvalue(); lput(PADDR(vl)); /* va of entry (real mode on boot) */ lput(0L); lput(lcsize); llput(vl); /* va of entry */ break; case 3: break; case 5: elf32(POWER, ELFDATA2MSB, 0, nil); break; case 9: /* ELF64 Header */ case 10: /* A2 weirdness */ elf64(POWER64, ELFDATA2MSB, 0, nil); break; } cflush(); }
void asmb(void) { int32 t; int a, dynsym; uint32 fo, symo, startva; ElfEhdr *eh; ElfPhdr *ph, *pph; ElfShdr *sh; Section *sect; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); Bflush(&bso); sect = segtext.sect; seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); codeblk(sect->vaddr, sect->len); /* output read-only data in text segment (rodata, gosymtab and pclntab) */ for(sect = sect->next; sect != nil; sect = sect->next) { seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); datblk(sect->vaddr, sect->len); } if(debug['v']) Bprint(&bso, "%5.2f datblk\n", cputime()); Bflush(&bso); seek(cout, segdata.fileoff, 0); datblk(segdata.vaddr, segdata.filelen); /* output read-only data in text segment */ sect = segtext.sect->next; seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); datblk(sect->vaddr, sect->len); if(iself) { /* index of elf text section; needed by asmelfsym, double-checked below */ /* !debug['d'] causes extra sections before the .text section */ elftextsh = 1; if(!debug['d']) { elftextsh += 10; if(elfverneed) elftextsh += 2; } } /* output symbol table */ symsize = 0; lcsize = 0; symo = 0; if(!debug['s']) { // TODO: rationalize if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { default: if(iself) goto ElfSym; case Hnoheader: case Hrisc: case Hixp1200: case Hipaq: debug['s'] = 1; break; case Hplan9x32: symo = HEADR+segtext.len+segdata.filelen; break; case Hnetbsd: symo = rnd(segdata.filelen, 4096); break; ElfSym: symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen; symo = rnd(symo, INITRND); break; } seek(cout, symo, 0); if(iself) { if(debug['v']) Bprint(&bso, "%5.2f elfsym\n", cputime()); asmelfsym(); cflush(); ewrite(cout, elfstrdat, elfstrsize); // if(debug['v']) // Bprint(&bso, "%5.2f dwarf\n", cputime()); // dwarfemitdebugsections(); } cflush(); } cursym = nil; if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); seek(cout, 0L, 0); switch(HEADTYPE) { case Hnoheader: /* no header */ break; case Hrisc: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ lputl(0xe1a00000); /* NOP - relocation code */ lputl(0xeb000000 + 12); /* BL - zero init code */ lputl(0xeb000000 + (entryvalue() - INITTEXT + HEADR - 12 - 8) / 4); /* BL - entry code */ lputl(0xef000011); /* SWI - exit code */ lputl(textsize+HEADR); /* text size */ lputl(segdata.filelen); /* data size */ lputl(0); /* sym size */ lputl(segdata.len - segdata.filelen); /* bss size */ lputl(0); /* sym type */ lputl(INITTEXT-HEADR); /* text addr */ lputl(0); /* workspace - ignored */ lputl(32); /* addr mode / data addr flag */ lputl(0); /* data addr */ for(t=0; t<2; t++) lputl(0); /* reserved */ for(t=0; t<15; t++) lputl(0xe1a00000); /* NOP - zero init code */ lputl(0xe1a0f00e); /* B (R14) - zero init return */ break; case Hplan9x32: /* plan 9 */ lput(0x647); /* magic */ lput(textsize); /* sizes */ lput(segdata.filelen); lput(segdata.len - segdata.filelen); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case Hnetbsd: /* boot for NetBSD */ lput((143<<16)|0413); /* magic */ lputl(rnd(HEADR+textsize, 4096)); lputl(rnd(segdata.filelen, 4096)); lputl(segdata.len - segdata.filelen); lputl(symsize); /* nsyms */ lputl(entryvalue()); /* va of entry */ lputl(0L); lputl(0L); break; case Hixp1200: /* boot for IXP1200 */ break; case Hipaq: /* boot for ipaq */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; case Hlinux: /* elf arm */ eh = getElfEhdr(); fo = HEADR; startva = INITTEXT - fo; /* va of byte 0 of file */ /* This null SHdr must appear before all others */ sh = newElfShdr(elfstr[ElfStrEmpty]); /* program header info */ pph = newElfPhdr(); pph->type = PT_PHDR; pph->flags = PF_R + PF_X; pph->off = eh->ehsize; pph->vaddr = INITTEXT - HEADR + pph->off; pph->paddr = INITTEXT - HEADR + pph->off; pph->align = INITRND; if(!debug['d']) { /* interpreter for dynamic linking */ sh = newElfShdr(elfstr[ElfStrInterp]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC; sh->addralign = 1; if(interpreter == nil) interpreter = linuxdynld; elfinterp(sh, startva, interpreter); ph = newElfPhdr(); ph->type = PT_INTERP; ph->flags = PF_R; phsh(ph, sh); } elfphload(&segtext); elfphload(&segdata); /* Dynamic linking sections */ if (!debug['d']) { /* -d suppresses dynamic loader format */ /* S headers for dynamic linking */ sh = newElfShdr(elfstr[ElfStrGot]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 4; sh->addralign = 4; shsym(sh, lookup(".got", 0)); sh = newElfShdr(elfstr[ElfStrGotPlt]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 4; sh->addralign = 4; shsym(sh, lookup(".got.plt", 0)); dynsym = eh->shnum; sh = newElfShdr(elfstr[ElfStrDynsym]); sh->type = SHT_DYNSYM; sh->flags = SHF_ALLOC; sh->entsize = ELF32SYMSIZE; sh->addralign = 4; sh->link = dynsym+1; // dynstr // sh->info = index of first non-local symbol (number of local symbols) shsym(sh, lookup(".dynsym", 0)); sh = newElfShdr(elfstr[ElfStrDynstr]); sh->type = SHT_STRTAB; sh->flags = SHF_ALLOC; sh->addralign = 1; shsym(sh, lookup(".dynstr", 0)); sh = newElfShdr(elfstr[ElfStrHash]); sh->type = SHT_HASH; sh->flags = SHF_ALLOC; sh->entsize = 4; sh->addralign = 4; sh->link = dynsym; shsym(sh, lookup(".hash", 0)); sh = newElfShdr(elfstr[ElfStrRel]); sh->type = SHT_REL; sh->flags = SHF_ALLOC; sh->entsize = ELF32RELSIZE; sh->addralign = 4; sh->link = dynsym; shsym(sh, lookup(".rel", 0)); /* sh and PT_DYNAMIC for .dynamic section */ sh = newElfShdr(elfstr[ElfStrDynamic]); sh->type = SHT_DYNAMIC; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 8; sh->addralign = 4; sh->link = dynsym+1; // dynstr shsym(sh, lookup(".dynamic", 0)); ph = newElfPhdr(); ph->type = PT_DYNAMIC; ph->flags = PF_R + PF_W; phsh(ph, sh); /* * Thread-local storage segment (really just size). if(tlsoffset != 0) { ph = newElfPhdr(); ph->type = PT_TLS; ph->flags = PF_R; ph->memsz = -tlsoffset; ph->align = 4; } */ } ph = newElfPhdr(); ph->type = PT_GNU_STACK; ph->flags = PF_W+PF_R; ph->align = 4; if(elftextsh != eh->shnum) diag("elftextsh = %d, want %d", elftextsh, eh->shnum); for(sect=segtext.sect; sect!=nil; sect=sect->next) elfshbits(sect); for(sect=segdata.sect; sect!=nil; sect=sect->next) elfshbits(sect); if (!debug['s']) { sh = newElfShdr(elfstr[ElfStrSymtab]); sh->type = SHT_SYMTAB; sh->off = symo; sh->size = symsize; sh->addralign = 4; sh->entsize = 16; sh->link = eh->shnum; // link to strtab sh = newElfShdr(elfstr[ElfStrStrtab]); sh->type = SHT_STRTAB; sh->off = symo+symsize; sh->size = elfstrsize; sh->addralign = 1; // dwarfaddelfheaders(); } sh = newElfShstrtab(elfstr[ElfStrShstrtab]); sh->type = SHT_STRTAB; sh->addralign = 1; shsym(sh, lookup(".shstrtab", 0)); /* Main header */ eh->ident[EI_MAG0] = '\177'; eh->ident[EI_MAG1] = 'E'; eh->ident[EI_MAG2] = 'L'; eh->ident[EI_MAG3] = 'F'; eh->ident[EI_CLASS] = ELFCLASS32; eh->ident[EI_DATA] = ELFDATA2LSB; eh->ident[EI_VERSION] = EV_CURRENT; eh->type = ET_EXEC; eh->machine = EM_ARM; eh->version = EV_CURRENT; eh->entry = entryvalue(); if(pph != nil) { pph->filesz = eh->phnum * eh->phentsize; pph->memsz = pph->filesz; } seek(cout, 0, 0); a = 0; a += elfwritehdr(); a += elfwritephdrs(); a += elfwriteshdrs(); cflush(); if(a+elfwriteinterp() > ELFRESERVE) diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); break; } cflush(); if(debug['c']){ print("textsize=%d\n", textsize); print("datsize=%d\n", segdata.filelen); print("bsssize=%d\n", segdata.len - segdata.filelen); print("symsize=%d\n", symsize); print("lcsize=%d\n", lcsize); print("total=%d\n", textsize+segdata.len+symsize+lcsize); } }
/* * Print a number of char variable values, where the optional comments * for each value identify the variable, and each dimension index. */ static void pr_tvals( const struct ncvar *vp, /* variable */ long len, /* number of values to print */ const char *fmt, /* printf format used for each value. If * nc_type is NC_CHAR and this is NULL, * character arrays will be printed as * strings enclosed in quotes. */ boolean more, /* true if more data for this row will * follow, so add trailing comma */ boolean lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const char *vals, /* pointer to block of values */ const struct fspec* fsp, /* formatting specs */ const long *cor /* corner coordinates */ ) { long iel; const char *sp; unsigned char uc; char sout[100]; /* temporary string for each encoded output */ if (fmt == 0 || STREQ(fmt,"%s") || STREQ(fmt,"")) { /* as string */ Printf("\""); /* adjust len so trailing nulls don't get printed */ sp = vals + len; while (len != 0 && *--sp == '\0') len--; for (iel = 0; iel < len; iel++) switch (uc = *vals++ & 0377) { case '\b': Printf("\\b"); break; case '\f': Printf("\\f"); break; case '\n': /* generate linebreaks after new-lines */ Printf("\\n\",\n \""); break; case '\r': Printf("\\r"); break; case '\t': Printf("\\t"); break; case '\v': Printf("\\v"); break; case '\\': Printf("\\\\"); break; case '\'': Printf("\\\'"); break; case '\"': Printf("\\\""); break; default: if (isprint(uc)) Printf("%c",uc); else Printf("\\%.3o",uc); break; } Printf("\""); if (fsp->full_data_cmnts) { lastdelim (more, lastrow); annotate (vp, fsp, (long *)cor, 0L); } } else { /* use format from C_format attribute */ for (iel = 0; iel < len-1; iel++) { if (fsp->full_data_cmnts) { Printf(fmt, *vals++); Printf(", "); annotate (vp, fsp, (long *)cor, iel); } else { (void) sprintf(sout, fmt, *vals++); (void) strcat(sout, ", "); lput(sout); } } if (fsp->full_data_cmnts) { Printf(fmt, *vals++); lastdelim (more, lastrow); annotate (vp, fsp, (long *)cor, iel); } else { (void) sprintf(sout, fmt, *vals++); lput(sout); } } if (!fsp->full_data_cmnts) { lastdelim2 (more, lastrow); } }
void asmb(void) { Prog *p; long v; int a; short *op1; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; curp = firstp; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->pc != pc) { if(!debug['a']) print("%P\n", curp); diag("phase error %.4lux sb %.4lux in %s", p->pc, pc, TNAME); pc = p->pc; } curp = p; if(debug['a']) Bprint(&bso, "%lux:%P\n", pc, curp); asmins(p); if(cbc < sizeof(opa)) cflush(); for(op1 = opa; op1 < op; op1++) { a = *op1; *cbp++ = a >> 8; *cbp++ = a; } a = 2*(op - opa); pc += a; cbc -= a; if(debug['a']) { for(op1 = opa; op1 < op; op1++) if(op1 == opa) Bprint(&bso, "\t\t%4ux", *op1 & 0xffff); else Bprint(&bso, " %4ux", *op1 & 0xffff); if(op != opa) Bprint(&bso, "\n"); } } cflush(); switch(HEADTYPE) { case 0: /* this is garbage */ seek(cout, rnd(HEADR+textsize, 8192), 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND), 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND), 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize, 0); break; } if(debug['v']) Bprint(&bso, "%5.2f datblk\n", cputime()); Bflush(&bso); for(v = 0; v < datsize; v += sizeof(buf)-100) { if(datsize-v > sizeof(buf)-100) datblk(v, sizeof(buf)-100); else datblk(v, datsize-v); } symsize = 0; spsize = 0; lcsize = 0; relocsize = 0; Bflush(&bso); switch(HEADTYPE) { default: seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize+datsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize+datsize, 0); break; } if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); asmsym(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); asmsp(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); asmlc(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f reloc\n", cputime()); asmreloc(); } cflush(); if(debug['v']) Bprint(&bso, "%5.2f headr\n", cputime()); Bflush(&bso); seek(cout, 0L, 0); switch(HEADTYPE) { default: lput(0x160L<<16); /* magic and sections */ lput(0L); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x38L<<16)|7L); /* size of optional hdr and flags */ lput((0413<<16)|0437L); /* magic and version */ lput(rnd(HEADR+textsize, 4096)); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT-HEADR); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT+datsize); /* va of base of bss */ lput(~0L); /* gp reg mask */ lput(0L); lput(0L); lput(0L); lput(0L); lput(~0L); /* gp value ?? */ break; case 1: /* plan9 boot data goes into text */ lput(0407); /* magic */ lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */ lput(0); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 2: /* plan 9 */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 3: /* next boot */ /* header */ lput(0xfeedfaceL); /* magic */ lput(6); /* 68040 */ lput(1); /* more 68040 */ lput(5); /* file type 'boot' */ lput(HEADTYPE); /* number commands */ lput(HEADR-7*4); /* sizeof commands */ lput(1); /* no undefineds */ /* command 1 text */ lput(1); /* command = 'segment' */ lput(124); /* command size */ s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(rnd(textsize, 8192)); /* va size */ lput(HEADR); /* file offset */ lput(rnd(textsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(1); /* number of sections */ lput(0); /* flags */ /* text section */ s16put("__text"); s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(textsize); /* va size */ lput(HEADR); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 1 data */ lput(1); /* command = 'segment' */ lput(192); /* command size */ s16put("__DATA"); lput(INITDAT); /* va of start */ lput(rnd(datsize, 8192)); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(rnd(datsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(2); /* number of sections */ lput(0); /* flags */ /* data section */ s16put("__data"); s16put("__DATA"); lput(INITDAT); /* va of start */ lput(datsize); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* bss section */ s16put("__bss"); s16put("__DATA"); lput(INITDAT+datsize); /* va of start */ lput(bsssize); /* va size */ lput(0); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(1); /* flags = zero fill */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 2 symbol */ lput(2); /* command = 'symbol' */ lput(24); /* command size */ lput(HEADR+rnd(textsize, INITRND) +datsize); /* symoff */ lput(symsize); /* nsyms */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 4: /* preprocess pilot */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ lput(relocsize); /* relocation */ break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; long prevpc; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); /* emit text segment */ seek(cout, HEADR, 0); prevpc = pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; if (prevpc & (1<<31) && (pc & (1<<31)) == 0) { char *tn; tn = "?none?"; if(curtext != P && curtext->from.sym != S) tn = curtext->from.sym->name; Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn); } prevpc = pc; } /* for virtex 4, inject a jmp instruction after other text */ if(HEADTYPE == 6) /* branch to absolute entry address (0xfffe2100) */ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* emit data segment */ curtext = P; switch(HEADTYPE) { case 6: textsize += JMPSZ; /* fall through */ case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 6: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } /* back up and write the header */ seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: /* * customised for blue/gene, * notably the alignment and KMASK masking. */ strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue() & ~KMASK); /* entry vaddr */ lput(52L); /* offset to first phdr */ if(debug['S']){ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|40L); /* # Phdrs & Shdr size */ lput((3L<<16)|2L); /* # Shdrs & shdr string size */ } else{ lput(0L); lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|0L); /* # Phdrs & Shdr size */ lput((3L<<16)|0L); /* # Shdrs & shdr string size */ } lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT & ~KMASK); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize); /* file size */ lput(textsize); /* memory size */ lput(0x05L); /* protections = RX */ lput(0x10000L); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT & ~KMASK); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0x10000L); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); /* vaddr */ lput(0L); /* paddr */ lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ cflush(); if(!debug['S']) break; seek(cout, HEADR+textsize+datsize+symsize, 0); lput(1); /* Section name (string tbl index) */ lput(1); /* Section type */ lput(2|4); /* Section flags */ lput(INITTEXT & ~KMASK); /* Section virtual addr at execution */ lput(HEADR); /* Section file offset */ lput(textsize); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(0x10000L); /* Section alignment */ lput(0); /* Entry size if section holds table */ lput(7); /* Section name (string tbl index) */ lput(1); /* Section type */ lput(2|1); /* Section flags */ lput(INITDAT & ~KMASK); /* Section virtual addr at execution */ lput(HEADR+textsize); /* Section file offset */ lput(datsize); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(0x10000L); /* Section alignment */ lput(0); /* Entry size if section holds table */ /* string section header */ lput(12); /* Section name (string tbl index) */ lput(3); /* Section type */ lput(1 << 5); /* Section flags */ lput(0); /* Section virtual addr at execution */ lput(HEADR+textsize+datsize+symsize+3*40); /* Section file offset */ lput(14); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(1); /* Section alignment */ lput(0); /* Entry size if section holds table */ /* string table */ cput(0); strnput(".text", 5); cput(0); strnput(".data", 5); cput(0); strnput(".strtab", 7); cput(0); cput(0); break; case 6: /* * customised for virtex 4 boot, * notably the alignment and KMASK masking. */ strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue()); /* entry vaddr */ lput(52L); /* offset to first phdr */ debug['S'] = 1; /* no symbol table */ if(debug['S']){ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((4L<<16)|40L); /* # Phdrs & Shdr size */ lput((4L<<16)|2L); /* # Shdrs & shdr string size */ } else{ lput(0L); lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((4L<<16)|0L); /* # Phdrs & Shdr size */ lput((4L<<16)|0L); /* # Shdrs & shdr string size */ } lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize-JMPSZ); /* file size */ lput(textsize-JMPSZ); /* memory size */ lput(0x05L); /* protections = RX */ lput(0); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize+bsssize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); /* vaddr */ lput(0L); /* paddr */ lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ /* add tiny text section at end with jmp to start */ lput(1L); /* text - type = PT_LOAD */ lput(HEADR+textsize-JMPSZ); /* file offset */ lput(0xFFFFFFFC); /* vaddr */ lput(0xFFFFFFFC); /* paddr */ lput(JMPSZ); /* file size */ lput(JMPSZ); /* memory size */ lput(0x05L); /* protections = RX */ lput(0); /* disable alignment */ cflush(); break; } cflush(); }
/* Write out the error causing line verbatim (ie, as the user typed it in) and put * the error symbol '<?>' next to the error causing token. The error line is in * the file pointed to by 'canon_info->efd'. Because of line continuation '\' and * as-in/as-out, the line is saved to file as it can be arbitrarily large. The * basic steps here are to reset the canonicalize buffer back to the beginning or * the line and write over any partially canonicalized line with the error line. * Next the position within the line to put the error symbol is calculated and then * the error line is written to the canonicalize buffer. * * Return: * void */ void add_canonical_error_line (parse_info_t *obj, canon_info_t *canon_info, int add_line_feed) { int i, j, k, l; char c; canon_line_t lrec; /* if (verbose) */ fprintf (dfile, "1 error-pos (%d) line-len (%d) num_lines (%d) \n", obj->error_pos, obj->eline_len, obj->num_lines); if (!canon_info->do_canon) return; /* Reset the parse buffer pointer to the beginning of * the line to overwrite any fragment of the canonicalized * line we have already parsed. Want to write the error * line verbatim with the error symbol at the error token * position. */ dump_current_canon_line (canon_info); /* reset the number of lines */ if (canon_info->lio == CANON_MEM) lineptr[obj->num_lines].lines = obj->elines; else { lget (obj->num_lines, &lrec, canon_info); lrec.lines = obj->elines; lput (obj->num_lines, &lrec, canon_info); } /* Make the error symbol '<?>' abut the nearest token. * Find the position j to put '<?>'. Remember, because * of '\' line continuation, we can have many '\n's in * a single error line. */ if (fseek (canon_info->efd, 0, SEEK_SET) != EOF) { j = l = -1; i = obj->error_pos; k = 0; for (;j < 0 || l < 0 || (l <= j); k++) { if (k >= obj->eline_len || (c = fgetc (canon_info->efd)) == EOF || c == '\0') break; else if (c != ' ' && c != '\t' && c != '\n') j = k; else if ((j >= 0 && (j == (k - 1)) && k == i) || k > i) l = k; } if (j >= 0) j++; else j = 0; /* JW debug */ fprintf (dfile, "\nerror_line (): error_pos (%d) j (%d) l (%d) k (%d)\n", obj->error_pos, j, l, k); fseek (canon_info->efd, 0, SEEK_SET); for (i = 0; i < obj->eline_len && (c = fgetc (canon_info->efd)) != EOF; i++) { if (i % 10 == 0) fprintf (dfile, "|"); fprintf (dfile, "%c", c); } fprintf (dfile, "\n i (%d)\n", i); /* JW end debug */ /* write out the error line, inserting '<?>' at position j */ fseek (canon_info->efd, 0, SEEK_SET); for (i = 0; i < obj->eline_len && (c = fgetc (canon_info->efd)) != EOF; i++) { if (i == j) parse_buf_add (canon_info, "%s", ERROR_TOKEN); parse_buf_add (canon_info, "%c", &c); } } else { parse_buf_add (canon_info, "%s", "INTERNAL ERROR: could not read error line!\n"); add_line_feed = 0; } if (add_line_feed) parse_buf_add (canon_info, "\n"); /* terminate the line */ parse_buf_add (canon_info, "%z"); return; }
void asmb(void) { Prog *p; int32 t, etext; int np; vlong va, fo, w, symo; int strtabsize; vlong symdatva = 0x99LL<<24; Optab *o; strtabsize = 0; symo = 0; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { setarch(p); if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(thumb) thumbasmout(p, o); else asmout(p, o); pc += o->size; } while(pc-INITTEXT < textsize) { cput(0); pc++; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } /* output section header strings */ curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 3: OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; case 6: seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); strtabsize = linuxstrtable(); cflush(); t = rnd(HEADR+textsize, INITRND); seek(cout, t, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } cflush(); /* output symbol table */ symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 4: case 5: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 3: OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 6: symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize; symo = rnd(symo, INITRND); seek(cout, symo + 8, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(!debug['s']) asmthumbmap(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } curtext = P; if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ lputl(0xe1a00000); /* NOP - relocation code */ lputl(0xeb000000 + 12); /* BL - zero init code */ lputl(0xeb000000 + (entryvalue() - INITTEXT + HEADR - 12 - 8) / 4); /* BL - entry code */ lputl(0xef000011); /* SWI - exit code */ lputl(textsize+HEADR); /* text size */ lputl(datsize); /* data size */ lputl(0); /* sym size */ lputl(bsssize); /* bss size */ lputl(0); /* sym type */ lputl(INITTEXT-HEADR); /* text addr */ lputl(0); /* workspace - ignored */ lputl(32); /* addr mode / data addr flag */ lputl(0); /* data addr */ for(t=0; t<2; t++) lputl(0); /* reserved */ for(t=0; t<15; t++) lputl(0xe1a00000); /* NOP - zero init code */ lputl(0xe1a0f00e); /* B (R14) - zero init return */ break; case 2: /* plan 9 */ if(dlm) lput(0x80000000|0x647); /* magic */ else lput(0x647); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: /* boot for NetBSD */ lput((143<<16)|0413); /* magic */ lputl(rnd(HEADR+textsize, 4096)); lputl(rnd(datsize, 4096)); lputl(bsssize); lputl(symsize); /* nsyms */ lputl(entryvalue()); /* va of entry */ lputl(0L); lputl(0L); break; case 4: /* boot for IXP1200 */ break; case 5: /* boot for ipaq */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; case 6: /* elf arm */ strnput("\177ELF", 4); /* e_ident */ cput(1); /* class = 32 bit */ cput(1); /* data = LSB */ cput(1); /* version = CURRENT */ strnput("", 9); wputl(2); /* type = EXEC */ wputl(40); /* machine = ARM */ lputl(1L); /* version = CURRENT */ lputl(entryvalue()); /* entry vaddr */ lputl(52L); /* offset to first phdr */ np = 3; if(!debug['s']) np++; lputl(52L+32*np); /* offset to first shdr */ lputl(0L); /* processor specific flags */ wputl(52); /* Ehdr size */ wputl(32); /* Phdr size */ wputl(np); /* # of Phdrs */ wputl(40); /* Shdr size */ if (!debug['s']) wputl(7); /* # of Shdrs */ else wputl(5); /* # of Shdrs */ wputl(4); /* Shdr with strings */ fo = 0; va = INITTEXT & ~((vlong)INITRND - 1); w = HEADR+textsize; linuxphdr(1, /* text - type = PT_LOAD */ 1L+4L, /* text - flags = PF_X+PF_R */ 0, /* file offset */ va, /* vaddr */ va, /* paddr */ w, /* file size */ w, /* memory size */ INITRND); /* alignment */ fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; linuxphdr(1, /* data - type = PT_LOAD */ 2L+4L, /* data - flags = PF_W+PF_R */ fo, /* file offset */ va, /* vaddr */ va, /* paddr */ w, /* file size */ w+bsssize, /* memory size */ INITRND); /* alignment */ if(!debug['s']) { linuxphdr(1, /* data - type = PT_LOAD */ 2L+4L, /* data - flags = PF_W+PF_R */ symo, /* file offset */ symdatva, /* vaddr */ symdatva, /* paddr */ 8+symsize+lcsize, /* file size */ 8+symsize+lcsize, /* memory size */ INITRND); /* alignment */ } linuxphdr(0x6474e551, /* gok - type = gok */ 1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */ 0, /* file offset */ 0, /* vaddr */ 0, /* paddr */ 0, /* file size */ 0, /* memory size */ 8); /* alignment */ linuxshdr(nil, /* name */ 0, /* type */ 0, /* flags */ 0, /* addr */ 0, /* off */ 0, /* size */ 0, /* link */ 0, /* info */ 0, /* align */ 0); /* entsize */ stroffset = 1; /* 0 means no name, so start at 1 */ fo = HEADR; va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR; w = textsize; linuxshdr(".text", /* name */ 1, /* type */ 6, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; linuxshdr(".data", /* name */ 1, /* type */ 3, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ fo += w; va += w; w = bsssize; linuxshdr(".bss", /* name */ 8, /* type */ 3, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ w = strtabsize; linuxshdr(".shstrtab", /* name */ 3, /* type */ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 0); /* entsize */ if (debug['s']) break; fo = symo+8; w = symsize; linuxshdr(".gosymtab", /* name */ 1, /* type 1 = SHT_PROGBITS */ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 24); /* entsize */ fo += w; w = lcsize; linuxshdr(".gopclntab", /* name */ 1, /* type 1 = SHT_PROGBITS*/ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 24); /* entsize */ break; } cflush(); if(debug['c']){ print("textsize=%ld\n", textsize); print("datsize=%ld\n", datsize); print("bsssize=%ld\n", bsssize); print("symsize=%ld\n", symsize); print("lcsize=%ld\n", lcsize); print("total=%ld\n", textsize+datsize+bsssize+symsize+lcsize); } }
void asmb(void) { Prog *p; long t, etext; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ asmout(p, o); pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 7: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 3: case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 4: case 5: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 3: case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 7: break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ case 6: /* no header, padded segments */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ lputl(0xe1a00000); /* NOP - relocation code */ lputl(0xeb000000 + 12); /* BL - zero init code */ lputl(0xeb000000 + (entryvalue() - INITTEXT + HEADR - 12 - 8) / 4); /* BL - entry code */ lputl(0xef000011); /* SWI - exit code */ lputl(textsize+HEADR); /* text size */ lputl(datsize); /* data size */ lputl(0); /* sym size */ lputl(bsssize); /* bss size */ lputl(0); /* sym type */ lputl(INITTEXT-HEADR); /* text addr */ lputl(0); /* workspace - ignored */ lputl(32); /* addr mode / data addr flag */ lputl(0); /* data addr */ for(t=0; t<2; t++) lputl(0); /* reserved */ for(t=0; t<15; t++) lputl(0xe1a00000); /* NOP - zero init code */ lputl(0xe1a0f00e); /* B (R14) - zero init return */ break; case 2: /* plan 9 */ if(dlm) lput(0x80000000|0x647); /* magic */ else lput(0x647); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: /* boot for NetBSD */ lput((143<<16)|0413); /* magic */ lputl(rnd(HEADR+textsize, 4096)); lputl(rnd(datsize, 4096)); lputl(bsssize); lputl(symsize); /* nsyms */ lputl(entryvalue()); /* va of entry */ lputl(0L); lputl(0L); break; case 4: /* boot for IXP1200 */ break; case 5: /* boot for ipaq */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; case 7: /* elf */ debug['S'] = 1; /* symbol table */ elf32(ARM, ELFDATA2LSB, 0, nil); break; } cflush(); }
void asmb(void) { Prog *p; long magic, t, etext; vlong vl; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + PCSZ; } if(p->as == ADWORD && (pc & 7) != 0) { lputl(0); pc += 4; } if(p->pc != pc) { diag("phase error %llux sb %llux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ asmout(p, o); pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } curtext = P; switch(HEADTYPE) { case 0: case 2: case 7: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 7: break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ case 6: /* no header, padded segments */ break; case 2: /* plan 9 */ magic = 4*28*28+7; magic |= 0x00008000; /* fat header */ if(dlm) magic |= 0x80000000; /* dlm */ lput(magic); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ vl = entryvalue(); lput(PADDR(vl)); /* va of entry */ lput(0L); lput(lcsize); llput(vl); /* va of entry */ break; case 7: /* elf */ debug['S'] = 1; /* symbol table */ elf64(ARM64, ELFDATA2LSB, 0, nil); break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; long prevpc; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); /* emit text segment */ seek(cout, HEADR, 0); prevpc = pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; if (prevpc & (1<<31) && (pc & (1<<31)) == 0) { char *tn; tn = "??none??"; if(curtext != P && curtext->from.sym != S) tn = curtext->from.sym->name; Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn); } prevpc = pc; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* emit data segment */ curtext = P; switch(HEADTYPE) { case 6: /* * but first, for virtex 4, inject a jmp instruction after * other text: branch to absolute entry address (0xfffe2100). */ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); textsize += JMPSZ; cflush(); /* fall through */ case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 6: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } /* back up and write the header */ seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: /* * intended for blue/gene */ elf32(POWER, ELFDATA2MSB, 0, nil); break; case 6: /* * intended for virtex 4 boot */ debug['S'] = 1; /* symbol table */ elf32(POWER, ELFDATA2MSB, 1, elf32jmp); break; } cflush(); }
static void PrintUsage(FILE *fp) { lput("" ); lput("usage: lout options files" ); lput("" ); lput(" -s suppress access to cross reference database" ); lput(" -EPS EPS (Encapsulated PostScript) output" ); lput(" -PDF or -Z PDF (Adobe Portable Document Format) output" ); lput(" -p plain text output instead of PostScript" ); lput(" -P like -p but with form-feed char between pages" ); lput(" -S safe execution (disable calls to system(3))" ); lput(" -U unsafe execution (allow calls to system(3))" ); lput(" -l ASCII collation order when sorting indexes etc." ); lput(" -L locale collation order when sorting indexes etc." ); lput(" -o file output to file instead of stdout" ); lput(" -e file error messages to file instead of stderr" ); lput(" -a alternative error format: file:line:col ..." ); lput(" -w print total number of words in output" ); lput(" -i file like @SysInclude { file }; not recommended" ); lput(" -I directory add directory to include file search path" ); lput(" -C directory add directory to LCM file search path" ); lput(" -F directory add directory to font metrics file search path" ); lput(" -H directory add directory to hyphenation file search path" ); lput(" -D directory add directory to database file search path" ); lput(" --option{value} set option e.g. --'@InitialFont{Times Base 10p}'" ); lput(" -c file use file.li instead of lout.li for crossrefs" ); lput(" -M save memory (don't read in database indexes)" ); lput(" -x initializing run, not for ordinary use" ); lput(" -u print this usage message on stderr and exit" ); lput(" -V print version and configuration information" ); lput(" - a file name denoting standard input" ); lput("" ); } /* end PrintUsage */