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 >
C/C++ Source or Header  |  1998-10-05  |  6KB  |  303 lines

  1. /*
  2.  * utility to adjust _stksize in gcc-cc1.ttp
  3.  *
  4.  *    Usage: fixstk size [<filename>]
  5.  *      size:    specified as # of bytes         nnn
  6.  *        specified as # of Kilo Bytes        nnnK
  7.  *        specified as # of Mega Bytes        nnnM
  8.  *      filename:
  9.  *        optional, defaults to \.gcc-cc1.ttp
  10.  *
  11.  *    ++jrb
  12.  *
  13.  *      modified to allow fixing applications for which size of a stack
  14.  *      is defined via _initial_stack -- mj
  15.  */
  16.  
  17. #include <stdio.h>
  18.  
  19. #ifdef CROSSATARI
  20. #include "cross-inc/st-out.h"
  21. #else
  22. #include <st-out.h>
  23. #endif
  24.  
  25. #if __STDC__
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #else
  30. #include <string.h>
  31. extern char *malloc();
  32. extern long lseek();
  33. #define size_t unsigned long
  34. #endif
  35.  
  36. #ifndef FILENAME_MAX
  37. # define FILENAME_MAX 128
  38. #endif
  39.  
  40. #ifdef WORD_ALIGNED
  41. # define SIZEOF_AEXEC ((2*sizeof(short)) + (6*sizeof(long)))
  42. # ifndef SYMLEN
  43. #   define SYMLEN 8
  44. # endif
  45. # define SIZEOF_ASYM  ((SYMLEN*sizeof(char)) + sizeof(short) + sizeof(long))
  46. # define SYM_OFFSET   (sizeof(short) + (3*sizeof(long)))
  47. #endif
  48.  
  49. #ifdef BYTE_SWAP
  50.  
  51. #define SWAP4(y) (((unsigned)(y)>>24) + (((unsigned)(y)>>8)&0xff00) + \
  52.          (((unsigned)(y)<<8)&0xff0000) + ((unsigned)(y)<<24)) 
  53. #define SWAP2(y) ((((unsigned)(y)&0xff00)>>8) + (((unsigned)(y)&0x00ff)<<8))
  54.  
  55. #endif /* BYTE_SWAP */
  56.  
  57. extern void dump_version(char *prog);
  58. char *progname = "fixstk";
  59.  
  60. int error = 0;
  61. long newstksize;
  62.  
  63. static char *sym_names[] = { "__stksize", "__initial_stack" };
  64.  
  65. long find_offset (fd, fn, what)
  66. int fd;
  67. char *fn;
  68. int *what;
  69. {
  70.     struct aexec head;
  71.     struct asym  sym;
  72.     int    all = 0;
  73.     int index = 1;
  74. #ifndef WORD_ALIGNED
  75.     char extension[sizeof (struct asym)];
  76. #else
  77.     char extension[SIZEOF_ASYM];
  78. #endif
  79.     
  80. #ifndef WORD_ALIGNED
  81.     if(read(fd, &head, sizeof(head)) != sizeof(head))
  82. #else
  83.     if(read_head(fd, &head))
  84. #endif
  85.     {
  86.     perror(fn);
  87.     return -1;
  88.     }
  89. #ifdef BYTE_SWAP
  90.     head.a_magic = SWAP2(head.a_magic);
  91.     head.a_syms = SWAP4(head.a_syms);
  92.     head.a_text = SWAP4(head.a_text);
  93.     head.a_data = SWAP4(head.a_data);
  94. #endif
  95.     if(head.a_magic != CMAGIC)
  96.     {
  97.     fprintf(stderr,"%s: invalid magic number %x\n", fn, head.a_magic);
  98.     return -1;
  99.     }
  100.     if(head.a_syms == 0)
  101.     {
  102.     fprintf(stderr,"%s: no symbol table\n", fn);
  103.     return -1;
  104.     }
  105.     if(lseek(fd, head.a_text+head.a_data, 1) != 
  106. #ifndef WORD_ALIGNED
  107.        (head.a_text+head.a_data+sizeof(head)))
  108. #else
  109.        (head.a_text+head.a_data+SIZEOF_AEXEC))
  110. #endif
  111.     {
  112.     perror(fn);
  113.     return -1;
  114.     }
  115.     for(;;)
  116.     {
  117. #ifndef WORD_ALIGNED
  118.     if(index && (read(fd, &sym, sizeof(sym)) != sizeof(sym)))
  119. #else
  120.     if(index && read_sym(fd, &sym))
  121. #endif
  122.     {
  123.         fprintf(stderr, "%s: symbol _stksize not found\n", fn);
  124.         return -1;
  125.     }
  126. #ifdef BYTE_SWAP
  127.     sym.a_type = SWAP2(sym.a_type);
  128.     sym.a_value = SWAP4(sym.a_value);
  129. #endif
  130.     if (index && (sym.a_type & A_LNAM) == A_LNAM)
  131.       if (read (fd, extension, sizeof (extension)) != sizeof (extension))
  132.         {
  133.           fprintf (stderr, "%s: symbol _stksize not found\n", fn);
  134.           return -1;
  135.         }
  136.     /* after symbol read check first for _stksize */
  137.     index ^= 1;
  138.     if (strncmp(sym_names[index], sym.a_name, 8) == 0)
  139.     {
  140.       if ((sym.a_type & A_LNAM) == A_LNAM
  141.           && strncmp (sym_names[index] + 8, extension, sizeof (extension)))
  142.         continue;
  143.       if (sym.a_type & A_DATA)
  144.         break;
  145.       if (all++)
  146.         {
  147.           fprintf (stderr, "%s: symbol _stksize is undefined\n", fn);
  148.           return -1;
  149.         }
  150.     }
  151.     }
  152.     
  153.     *what = index;
  154. #ifndef WORD_ALIGNED
  155.     return sym.a_value + sizeof(head);
  156. #else
  157.     return sym.a_value + SIZEOF_AEXEC;
  158. #endif
  159. }
  160.  
  161. long calc_newsize(s)
  162. char *s;
  163. {
  164.     size_t len = strlen(s) - 1;
  165.     long mul = 1;
  166.     long atol();
  167.  
  168.     switch(s[len])
  169.     {
  170.       case 'k': case 'K':
  171.     mul = 1L << 10;
  172.     break;
  173.       case 'm': case 'M':
  174.     mul = 1L << 20;
  175.     break;
  176.       default:
  177.     len += 1;
  178.     }
  179.     
  180.     s[len] = '\0';
  181.     return mul * atol(s);
  182. }
  183.  
  184. int main(argc, argv)
  185. int argc;
  186. char **argv;
  187. {
  188.   if (argv[0][0] != '\0')
  189.     progname = argv[0];
  190.  
  191.   if (argc == 2 && strcmp(argv[1], "-v") == 0)
  192.   {
  193.     dump_version(progname);
  194.     exit(0);
  195.   }
  196.  
  197.   if (argc < 3)
  198.     {
  199.       fprintf (stderr, "Usage: %s size file...\n", progname);
  200.       exit (1);
  201.     }
  202.   newstksize = calc_newsize (*++argv);
  203.   --argc;
  204.   while (--argc)
  205.     error |= fix_stack (*++argv);
  206.   exit (error);
  207. }
  208.  
  209. int
  210. fix_stack (fn)
  211.      char *fn;
  212. {
  213.     int fd;
  214.     int what;
  215.     long stksize, offset;
  216.  
  217.     if((fd = open(fn, 2)) < 0)
  218.     {
  219.     perror(fn);
  220.     return 1;
  221.     }
  222.     
  223.     offset = find_offset(fd, fn, &what);
  224.     if (offset < 0)
  225.       {
  226.     close (fd);
  227.     return 1;
  228.       }
  229.  
  230.     if(lseek(fd, offset, 0) != offset)
  231.     {
  232.     perror(fn);
  233.     close(fd);
  234.     return 1;
  235.     }
  236.     read(fd, &stksize, sizeof(long));
  237. #ifdef BYTE_SWAP
  238.     stksize = SWAP4(stksize);
  239. #endif
  240.     printf("%s: %s was %ld (%dK)\n",
  241.          fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
  242.     
  243.     lseek(fd, -((long)sizeof(long)), 1);
  244.     
  245. #ifdef BYTE_SWAP
  246.     newstksize = SWAP4(newstksize);
  247. #endif
  248.     if(write(fd, &newstksize, sizeof(long)) != sizeof(long))
  249.     {
  250.     perror(fn);
  251.     close(fd);
  252.     return 1;
  253.     }
  254.     
  255.     lseek(fd, -((long)sizeof(long)), 1);
  256.     
  257.     read(fd, &stksize, sizeof(long));
  258. #ifdef BYTE_SWAP
  259.     stksize = SWAP4(stksize);
  260. #endif
  261.     printf("%s: %s now is %ld (%dK)\n",
  262.          fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
  263.     return close(fd) != 0;
  264. }
  265.  
  266. #ifdef WORD_ALIGNED
  267. #ifndef atarist
  268. # define lread  read
  269. # define lwrite write
  270. #endif
  271.  
  272. /*
  273.  * read header -- return !0 on err
  274.   */
  275. #define ck_read(fd, addr, siz) \
  276.   if((long)siz != lread(fd, addr, (long)siz)) return !0;
  277.   
  278. int read_head (fd, a)
  279. int fd;
  280. struct aexec *a;
  281. {
  282.     ck_read(fd, &a->a_magic,   sizeof(a->a_magic));
  283.     ck_read(fd, &a->a_text,    sizeof(a->a_text));
  284.     ck_read(fd, &a->a_data,    sizeof(a->a_data));
  285.     ck_read(fd, &a->a_bss,     sizeof(a->a_bss));
  286.     ck_read(fd, &a->a_syms,    sizeof(a->a_syms));
  287.     ck_read(fd, &a->a_AZero1,  sizeof(a->a_AZero1));
  288.     ck_read(fd, &a->a_AZero2,  sizeof(a->a_AZero2));
  289.     ck_read(fd, &a->a_isreloc, sizeof(a->a_isreloc));
  290.     return 0;
  291. }
  292.  
  293. int read_sym(fd, s)
  294. int fd;
  295. struct asym *s;
  296. {
  297.     ck_read(fd, s->a_name, 8);
  298.     ck_read(fd, &(s->a_type), sizeof(short));
  299.     ck_read(fd, &(s->a_value), sizeof(long));
  300.     return 0;
  301. }
  302. #endif
  303.