/* * utility to adjust _stksize in gcc-cc1.ttp * * Usage: fixstk size [] * size: specified as # of bytes nnn * specified as # of Kilo Bytes nnnK * specified as # of Mega Bytes nnnM * filename: * optional, defaults to \.gcc-cc1.ttp * * ++jrb * * modified to allow fixing applications for which size of a stack * is defined via _initial_stack -- mj */ #include #include #if __STDC__ #include #include #include #else #include extern char *malloc(); extern long lseek(); #define size_t unsigned long #endif #ifndef FILENAME_MAX # define FILENAME_MAX 128 #endif #ifdef WORD_ALIGNED # define SIZEOF_AEXEC ((2*sizeof(short)) + (6*sizeof(long))) # define SIZEOF_ASYM ((SYMLEN*sizeof(char)) + sizeof(short) + sizeof(long)) # define SYM_OFFSET (sizeof(short) + (3*sizeof(long))) #endif static char *sym_names[] = { "__stksize", "__initial_stack" }; long find_offset (fd, fn, what) int fd; char *fn; int *what; { struct aexec head; struct asym sym; int found; int all = 0; int index = 1; #ifndef WORD_ALIGNED if(read(fd, &head, sizeof(head)) != sizeof(head)) #else if(read_head(fd, &head)) #endif { perror(fn); exit(2); } if(head.a_magic != CMAGIC) { fprintf(stderr,"Invalid magic number %x\n", head.a_magic); exit(3); } if(head.a_syms == 0) { fprintf(stderr,"%s: no symbol table\n", fn); exit(4); } if(lseek(fd, head.a_text+head.a_data, 1) != #ifndef WORD_ALIGNED (head.a_text+head.a_data+sizeof(head))) #else (head.a_text+head.a_data+SIZEOF_AEXEC)) #endif { perror(fn); exit(5); } for(;;) { #ifndef WORD_ALIGNED if(index && (read(fd, &sym, sizeof(sym)) != sizeof(sym))) #else if(index && read_sym(fd, &sym)) #endif { fprintf(stderr, "symbol _stksize not found\n"); exit(6); } /* after symbol read check first for _stksize */ index ^= 1; if (strncmp(sym_names[index], sym.a_name, 8) == 0) { if ((found = (sym.a_type & A_DATA)) || all++) break; } } if(!found) { fprintf(stderr, "symbol _stksize is undefined\n"); exit(9); } *what = index; #ifndef WORD_ALIGNED return sym.a_value + sizeof(head); #else return sym.a_value + SIZEOF_AEXEC; #endif } long calc_newsize(s) char *s; { size_t len = strlen(s) - 1; long mul = 1; long atol(); switch(s[len]) { case 'k': case 'K': mul = 1L << 10; break; case 'm': case 'M': mul = 1L << 20; break; default: len += 1; } s[len] = '\0'; return mul * atol(s); } int main(argc, argv) int argc; char **argv; { int fd; int what; long newstksize, stksize, offset; char sizestr[16], fn[FILENAME_MAX]; if(argc < 2) { fprintf(stderr, "usage: fixstk size []\n"); exit(1); } strcpy(sizestr, *++argv); if(argc > 2) (void) strcpy(fn, *++argv); else (void) strcpy(fn, "gcc-cc1.ttp"); if((fd = open(fn, 2)) < 0) { perror(fn); exit(1); } newstksize = calc_newsize(sizestr); offset = find_offset(fd, fn, &what); if(lseek(fd, offset, 0) != offset) { perror(fn); close(fd); exit(7); } read(fd, &stksize, sizeof(long)); printf("%s: %s was %ld (%dK)\n", fn, sym_names[what] + 1, stksize, (int)(stksize/1024)); lseek(fd, -((long)sizeof(long)), 1); if(write(fd, &newstksize, sizeof(long)) != sizeof(long)) { perror(fn); close(fd); exit(8); } lseek(fd, -((long)sizeof(long)), 1); read(fd, &stksize, sizeof(long)); printf("%s: %s now is %ld (%dK)\n", fn, sym_names[what] + 1, stksize, (int)(stksize/1024)); return close(fd); } #ifdef WORD_ALIGNED #ifndef atarist # define lread read # define lwrite write #endif /* * read header -- return !0 on err */ #define ck_read(fd, addr, siz) \ if((long)siz != lread(fd, addr, (long)siz)) return !0; int read_head (fd, a) int fd; struct aexec *a; { ck_read(fd, &a->a_magic, sizeof(a->a_magic)); ck_read(fd, &a->a_text, sizeof(a->a_text)); ck_read(fd, &a->a_data, sizeof(a->a_data)); ck_read(fd, &a->a_bss, sizeof(a->a_bss)); ck_read(fd, &a->a_syms, sizeof(a->a_syms)); ck_read(fd, &a->a_AZero1, sizeof(a->a_AZero1)); ck_read(fd, &a->a_AZero2, sizeof(a->a_AZero2)); ck_read(fd, &a->a_isreloc, sizeof(a->a_isreloc)); return 0; } int read_sym(fd, s) int fd; struct asym *s; { ck_read(fd, s->a_name, 8); ck_read(fd, &(s->a_type), sizeof(short)); ck_read(fd, &(s->a_value), sizeof(long)); return 0; } #endif