void dumpall(struct filenode *node, int lastoff, FILE *f) { struct romfh ri; struct filenode *p; ri.nextfh = htonl(0x2d726f6d); ri.spec = htonl(0x3166732d); ri.size = htonl(lastoff); ri.checksum = htonl(0x55555555); dumpri(&ri, node, f); p = node->dirlist.head; while (p->next) { dumpnode(p, f); p = p->next; } /* Align the whole bunch to ROMBSIZE boundary */ if (lastoff&1023) dumpzero(1024-(lastoff&1023), f); }
int dumpnode(struct filenode *node, FILE *f) { struct romfh ri; struct filenode *p; ri.nextfh = 0; ri.spec = 0; ri.size = htonl(node->size); ri.checksum = htonl(0x55555555); if(node->pad) dumpzero(node->pad, f); if(node->next && node->next->next) ri.nextfh = htonl(node->next->offset); if((node->modes & 0111) && (S_ISDIR(node->modes) || S_ISREG(node->modes))) ri.nextfh |= htonl(ROMFH_EXEC); if(node->orig_link) { ri.nextfh |= htonl(ROMFH_HRD); /* Don't allow hardlinks to convey attributes */ ri.nextfh &= ~htonl(ROMFH_EXEC); ri.spec = htonl(node->orig_link->offset); dumpri(&ri, node, f); } else if(S_ISDIR(node->modes)) { ri.nextfh |= htonl(ROMFH_DIR); if(listisempty(&node->dirlist)) { ri.spec = htonl(node->offset); } else { ri.spec = htonl(node->dirlist.head->offset); } dumpri(&ri, node, f); } else if(S_ISLNK(node->modes)) { ri.nextfh |= htonl(ROMFH_LNK); dumpri(&ri, node, f); memset(bigbuf, 0, sizeof(bigbuf)); if(readlink(node->realname, bigbuf, node->size) < 0) { return 1; } dumpdataa(bigbuf, node->size, f); } else if(S_ISREG(node->modes)) { int offset, len, fd, max, avail; ri.nextfh |= htonl(ROMFH_REG); dumpri(&ri, node, f); offset = 0; max = node->size; /* XXX warn about size mismatch */ fd = open(node->realname, O_RDONLY #ifdef O_BINARY | O_BINARY #endif ); if(fd) { while(offset < max) { avail = max - offset < sizeof(bigbuf) ? max - offset : sizeof(bigbuf); len = read(fd, bigbuf, avail); if(len <= 0) break; dumpdata(bigbuf, len, f); offset += len; } close(fd); } max = (max + 15)&~15; while(offset < max) { avail = max - offset < sizeof(bigbuf) ? max - offset : sizeof(bigbuf); memset(bigbuf, 0, avail); dumpdata(bigbuf, avail, f); offset += avail; } } else if(S_ISCHR(node->modes)) { ri.nextfh |= htonl(ROMFH_CHR); ri.spec = htonl(major(node->devnode) << 16 | minor(node->devnode)); dumpri(&ri, node, f); } else if(S_ISBLK(node->modes)) { ri.nextfh |= htonl(ROMFH_BLK); ri.spec = htonl(major(node->devnode) << 16 | minor(node->devnode)); dumpri(&ri, node, f); } else if(S_ISFIFO(node->modes)) { ri.nextfh |= htonl(ROMFH_FIF); dumpri(&ri, node, f); } else if(S_ISSOCK(node->modes)) { ri.nextfh |= htonl(ROMFH_SCK); dumpri(&ri, node, f); } p = node->dirlist.head; while(p->next) { if(dumpnode(p, f)) { return 1; } p = p->next; } return 0; }
void dumpdataa(void *addr, int len, FILE *f) { dumpdata(addr, len, f); if((len & 15) != 0) dumpzero(16 - (len & 15), f); }
/* * evaluate one initialiser * * if dump is TRUE, dump literal immediately * save character string in litq to dump later * this is used for structures and arrays of pointers to char, so that the * struct or array is built immediately and the char strings are dumped later */ void init(int size, int ident, int *dim, int more, int dump, int is_struct) { int32_t value; int sz; /* number of chars in queue */ /* * djm 14/3/99 We have to rewrite this bit (ugh!) so that we store * our literal in a temporary queue, then if needed, we then dump * it out.. */ if ((sz = qstr(&value)) != -1 ) { sz++; #if 0 if (ident == VARIABLE || (size != 1 && more != CCHAR)) error(E_ASSIGN); #endif #ifdef INIT_TEST outstr("ident="); outdec(ident); outstr("size="); outdec(size); outstr("more="); outdec(more); outstr("dim="); outdec(*dim); outstr("sz="); outdec(sz); nl(); #endif if (ident == ARRAY && more == 0) { /* * Dump the literals where they are, padding out as appropriate */ if (*dim != -1 && sz > *dim) { /* * Ooops, initialised to long a string! */ warning(W_INIT2LONG); sz = *dim; gltptr = sz; *(glbq + sz - 1) = '\0'; /* Terminate string */ } dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab, glbq); *dim -= sz; gltptr = 0; dumpzero(size, *dim); return; } else { /* * Store the literals in the queue! */ storeq(sz, glbq, &value); gltptr = 0; defword(); printlabel(litlab); outbyte('+'); outdec(value); nl(); --*dim; return; } } /* * djm, catch label names in structures (for (*name)() initialisation */ else { char sname[NAMEMAX + 1]; SYMBOL *ptr; if (symname(sname) && strcmp(sname,"sizeof") ) { /* We have got something.. */ if ((ptr = findglb(sname))) { /* Actually found sommat..very good! */ if (ident == POINTER || (ident == ARRAY && more)) { defword(); outname(ptr->name, dopref(ptr)); nl(); --*dim; } else if (ptr->type == ENUM) { value = ptr->size; goto constdecl; } else { error(E_DDECL); } } else error(E_UNSYMB, sname); } else if (rcmatch('}')) { #if 0 dumpzero(size,*dim); #endif } else if (constexpr(&value, 1)) { constdecl: if (ident == POINTER) { /* 24/1/03 dom - We want to be able to assign values to pointers or they're a bit useless.. */ #if 0 /* the only constant which can be assigned to a pointer is 0 */ if (value != 0) warning(W_ASSPTR); #endif size = 2; dump = YES; } if (dump) { /* struct member or array of pointer to char */ if (size == 4) { /* there appears to be a bug in z80asm regarding defl */ defbyte(); outdec((value % 65536UL) % 256); outbyte(','); outdec((value % 65536UL) / 256); outbyte(','); outdec((value / 65536UL) % 256); outbyte(','); outdec((value / 65536UL) / 256); } else { if (size == 1) defbyte(); else defword(); outdec(value); } nl(); /* Dump out a train of zeros as appropriate */ if (ident == ARRAY && more == 0) { dumpzero(size,(*dim)-1); } } else stowlit(value, size); --*dim; } } }
/* * initialise global object */ int initials(char *sname, int type, int ident, int dim, int more, TAG_SYMBOL * tag, char zfar) { int size, desize = 0; int olddim = dim; if (cmatch('=')) { /* initialiser present */ defstatic = 1; /* So no 2nd redefine djm */ gltptr = 0; glblab = getlabel(); if (dim == 0) dim = -1; switch (type) { case CCHAR: size = 1; break; case LONG: size = 4; break; case CINT: default: size = 2; } output_section("data_compiler"); // output_section("text"); prefix(); outname(sname, YES); col(); nl(); if (cmatch('{')) { /* aggregate initialiser */ if ((ident == POINTER || ident == VARIABLE) && type == STRUCT) { /* aggregate is structure or pointer to structure */ dim = 0; olddim = 1; if (ident == POINTER) point(); str_init(tag); } else { /* aggregate is not struct or struct pointer */ agg_init(size, type, ident, &dim, more, tag); } needchar('}'); } else { /* single initialiser */ init(size, ident, &dim, more, 0, 0); } /* dump literal queue and fill tail of array with zeros */ if ((ident == ARRAY && more == CCHAR) || type == STRUCT) { if (type == STRUCT) { dumpzero(tag->size, dim); desize = dim < 0 ? abs(dim+1)*tag->size : olddim * tag->size; } else { /* Handles unsized arrays of chars */ dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } dumplits(0, YES, gltptr, glblab, glbq); } else { if (!(ident == POINTER && type == CCHAR)) { dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab,glbq); if ( type != CCHAR ) /* Already dumped by init? */ desize = dumpzero(size, dim); dim = dim < 0 ? abs(dim+1) : olddim; cscale(type,tag,&dim); desize = dim; } } output_section("code_compiler"); // output_section("code"); } else { char *dosign, *typ; dosign = ""; if (ident == ARRAY && (dim == 0)) { typ = ExpandType(more, &dosign, (tag - tagtab)); warning(W_NULLARRAY, dosign, typ); } /* no initialiser present, let loader insert zero */ if (ident == POINTER) type = (zfar ? CPTR : CINT); cscale(type, tag, &dim); desize = dim; } return (desize); }
/* * initialise structure */ int str_init(TAG_SYMBOL *tag) { int dim, flag; int sz, usz, numelements = 0; SYMBOL *ptr; int nodata = NO; ptr = tag->ptr; while (ptr < tag->end) { numelements++; dim = ptr->size; sz = getstsize(ptr,NO); if ( nodata == NO ) { if ( rcmatch('{') ) { needchar('{'); while (dim) { if ( ptr->type == STRUCT ) { if ( ptr->ident == ARRAY ) /* array of struct */ needchar('{'); str_init(tag); if ( ptr->ident == ARRAY ) { --dim; needchar('}'); } } else { init(sz, ptr->ident, &dim, 1, 1,1); } if (cmatch(',') == 0) break; blanks(); } needchar('}'); dumpzero(sz,dim); } else { init(sz, ptr->ident, &dim, ptr->more, 1, 1); } /* Pad out afterwards */ } else { /* Run out of data for this initialisation, set blank */ defstorage(); outdec(dim * getstsize(ptr,YES)); nl(); } usz = (ptr->size ? ptr->size : 1 ) * getstsize(ptr,YES); ++ptr; flag = NO; while (ptr->offset.i == 0 && ptr < tag->end) { if (getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) > usz) { usz = getstsize(ptr,YES) * (ptr->size ? ptr->size : 1 ) ; flag = YES; } ++ptr; } /* Pad out the union */ if (usz != sz && flag) { defstorage(); outdec(usz - sz); nl(); } if (cmatch(',') == 0 && ptr != tag->end) { nodata = YES; } } return numelements; }