home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
M.u.C.S. Disc 2000
/
MUCS2000.iso
/
gnuc
/
util-41s.lzh
/
util-41
/
fixstk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-05
|
6KB
|
303 lines
/*
* utility to adjust _stksize in gcc-cc1.ttp
*
* Usage: fixstk size [<filename>]
* 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 <stdio.h>
#ifdef CROSSATARI
#include "cross-inc/st-out.h"
#else
#include <st-out.h>
#endif
#if __STDC__
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#else
#include <string.h>
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)))
# ifndef SYMLEN
# define SYMLEN 8
# endif
# define SIZEOF_ASYM ((SYMLEN*sizeof(char)) + sizeof(short) + sizeof(long))
# define SYM_OFFSET (sizeof(short) + (3*sizeof(long)))
#endif
#ifdef BYTE_SWAP
#define SWAP4(y) (((unsigned)(y)>>24) + (((unsigned)(y)>>8)&0xff00) + \
(((unsigned)(y)<<8)&0xff0000) + ((unsigned)(y)<<24))
#define SWAP2(y) ((((unsigned)(y)&0xff00)>>8) + (((unsigned)(y)&0x00ff)<<8))
#endif /* BYTE_SWAP */
extern void dump_version(char *prog);
char *progname = "fixstk";
int error = 0;
long newstksize;
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 all = 0;
int index = 1;
#ifndef WORD_ALIGNED
char extension[sizeof (struct asym)];
#else
char extension[SIZEOF_ASYM];
#endif
#ifndef WORD_ALIGNED
if(read(fd, &head, sizeof(head)) != sizeof(head))
#else
if(read_head(fd, &head))
#endif
{
perror(fn);
return -1;
}
#ifdef BYTE_SWAP
head.a_magic = SWAP2(head.a_magic);
head.a_syms = SWAP4(head.a_syms);
head.a_text = SWAP4(head.a_text);
head.a_data = SWAP4(head.a_data);
#endif
if(head.a_magic != CMAGIC)
{
fprintf(stderr,"%s: invalid magic number %x\n", fn, head.a_magic);
return -1;
}
if(head.a_syms == 0)
{
fprintf(stderr,"%s: no symbol table\n", fn);
return -1;
}
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);
return -1;
}
for(;;)
{
#ifndef WORD_ALIGNED
if(index && (read(fd, &sym, sizeof(sym)) != sizeof(sym)))
#else
if(index && read_sym(fd, &sym))
#endif
{
fprintf(stderr, "%s: symbol _stksize not found\n", fn);
return -1;
}
#ifdef BYTE_SWAP
sym.a_type = SWAP2(sym.a_type);
sym.a_value = SWAP4(sym.a_value);
#endif
if (index && (sym.a_type & A_LNAM) == A_LNAM)
if (read (fd, extension, sizeof (extension)) != sizeof (extension))
{
fprintf (stderr, "%s: symbol _stksize not found\n", fn);
return -1;
}
/* after symbol read check first for _stksize */
index ^= 1;
if (strncmp(sym_names[index], sym.a_name, 8) == 0)
{
if ((sym.a_type & A_LNAM) == A_LNAM
&& strncmp (sym_names[index] + 8, extension, sizeof (extension)))
continue;
if (sym.a_type & A_DATA)
break;
if (all++)
{
fprintf (stderr, "%s: symbol _stksize is undefined\n", fn);
return -1;
}
}
}
*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;
{
if (argv[0][0] != '\0')
progname = argv[0];
if (argc == 2 && strcmp(argv[1], "-v") == 0)
{
dump_version(progname);
exit(0);
}
if (argc < 3)
{
fprintf (stderr, "Usage: %s size file...\n", progname);
exit (1);
}
newstksize = calc_newsize (*++argv);
--argc;
while (--argc)
error |= fix_stack (*++argv);
exit (error);
}
int
fix_stack (fn)
char *fn;
{
int fd;
int what;
long stksize, offset;
if((fd = open(fn, 2)) < 0)
{
perror(fn);
return 1;
}
offset = find_offset(fd, fn, &what);
if (offset < 0)
{
close (fd);
return 1;
}
if(lseek(fd, offset, 0) != offset)
{
perror(fn);
close(fd);
return 1;
}
read(fd, &stksize, sizeof(long));
#ifdef BYTE_SWAP
stksize = SWAP4(stksize);
#endif
printf("%s: %s was %ld (%dK)\n",
fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
lseek(fd, -((long)sizeof(long)), 1);
#ifdef BYTE_SWAP
newstksize = SWAP4(newstksize);
#endif
if(write(fd, &newstksize, sizeof(long)) != sizeof(long))
{
perror(fn);
close(fd);
return 1;
}
lseek(fd, -((long)sizeof(long)), 1);
read(fd, &stksize, sizeof(long));
#ifdef BYTE_SWAP
stksize = SWAP4(stksize);
#endif
printf("%s: %s now is %ld (%dK)\n",
fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
return close(fd) != 0;
}
#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