home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / util / utlsrc37.zoo / fixstk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-30  |  5.1 KB  |  259 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. #include <st-out.h>
  19.  
  20. #if __STDC__
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <string.h>
  24. #else
  25. #include <string.h>
  26. extern char *malloc();
  27. extern long lseek();
  28. #define size_t unsigned long
  29. #endif
  30.  
  31. #ifndef FILENAME_MAX
  32. # define FILENAME_MAX 128
  33. #endif
  34.  
  35. #ifdef WORD_ALIGNED
  36. # define SIZEOF_AEXEC ((2*sizeof(short)) + (6*sizeof(long)))
  37. # ifndef SYMLEN
  38. #   define SYMLEN 8
  39. # endif
  40. # define SIZEOF_ASYM  ((SYMLEN*sizeof(char)) + sizeof(short) + sizeof(long))
  41. # define SYM_OFFSET   (sizeof(short) + (3*sizeof(long)))
  42. #endif
  43.  
  44. int error = 0;
  45. long newstksize;
  46.  
  47. static char *sym_names[] = { "__stksize", "__initial_stack" };
  48.  
  49. long find_offset (fd, fn, what)
  50. int fd;
  51. char *fn;
  52. int *what;
  53. {
  54.     struct aexec head;
  55.     struct asym  sym;
  56.     int    all = 0;
  57.     int index = 1;
  58. #ifndef WORD_ALIGNED
  59.     char extension[sizeof (struct asym)];
  60. #else
  61.     char extension[SIZEOF_ASYM];
  62. #endif
  63.     
  64. #ifndef WORD_ALIGNED
  65.     if(read(fd, &head, sizeof(head)) != sizeof(head))
  66. #else
  67.     if(read_head(fd, &head))
  68. #endif
  69.     {
  70.     perror(fn);
  71.     return -1;
  72.     }
  73.     if(head.a_magic != CMAGIC)
  74.     {
  75.     fprintf(stderr,"%s: invalid magic number %x\n", fn, head.a_magic);
  76.     return -1;
  77.     }
  78.     if(head.a_syms == 0)
  79.     {
  80.     fprintf(stderr,"%s: no symbol table\n", fn);
  81.     return -1;
  82.     }
  83.     if(lseek(fd, head.a_text+head.a_data, 1) != 
  84. #ifndef WORD_ALIGNED
  85.        (head.a_text+head.a_data+sizeof(head)))
  86. #else
  87.        (head.a_text+head.a_data+SIZEOF_AEXEC))
  88. #endif
  89.     {
  90.     perror(fn);
  91.     return -1;
  92.     }
  93.     for(;;)
  94.     {
  95. #ifndef WORD_ALIGNED
  96.     if(index && (read(fd, &sym, sizeof(sym)) != sizeof(sym)))
  97. #else
  98.     if(index && read_sym(fd, &sym))
  99. #endif
  100.     {
  101.         fprintf(stderr, "%s: symbol _stksize not found\n", fn);
  102.         return -1;
  103.     }
  104.     if (index && (sym.a_type & A_LNAM) == A_LNAM)
  105.       if (read (fd, extension, sizeof (extension)) != sizeof (extension))
  106.         {
  107.           fprintf (stderr, "%s: symbol _stksize not found\n", fn);
  108.           return -1;
  109.         }
  110.     /* after symbol read check first for _stksize */
  111.     index ^= 1;
  112.     if (strncmp(sym_names[index], sym.a_name, 8) == 0)
  113.     {
  114.       if ((sym.a_type & A_LNAM) == A_LNAM
  115.           && strncmp (sym_names[index] + 8, extension, sizeof (extension)))
  116.         continue;
  117.       if (sym.a_type & A_DATA)
  118.         break;
  119.       if (all++)
  120.         {
  121.           fprintf (stderr, "%s: symbol _stksize is undefined\n", fn);
  122.           return -1;
  123.         }
  124.     }
  125.     }
  126.     
  127.     *what = index;
  128. #ifndef WORD_ALIGNED
  129.     return sym.a_value + sizeof(head);
  130. #else
  131.     return sym.a_value + SIZEOF_AEXEC;
  132. #endif
  133. }
  134.  
  135. long calc_newsize(s)
  136. char *s;
  137. {
  138.     size_t len = strlen(s) - 1;
  139.     long mul = 1;
  140.     long atol();
  141.  
  142.     switch(s[len])
  143.     {
  144.       case 'k': case 'K':
  145.     mul = 1L << 10;
  146.     break;
  147.       case 'm': case 'M':
  148.     mul = 1L << 20;
  149.     break;
  150.       default:
  151.     len += 1;
  152.     }
  153.     
  154.     s[len] = '\0';
  155.     return mul * atol(s);
  156. }
  157.  
  158. int main(argc, argv)
  159. int argc;
  160. char **argv;
  161. {
  162.   if (argc < 3)
  163.     {
  164.       fprintf (stderr, "Usage: %s size file...\n", *argv);
  165.       exit (1);
  166.     }
  167.   newstksize = calc_newsize (*++argv);
  168.   --argc;
  169.   while (--argc)
  170.     error |= fix_stack (*++argv);
  171.   exit (error);
  172. }
  173.  
  174. int
  175. fix_stack (fn)
  176.      char *fn;
  177. {
  178.     int fd;
  179.     int what;
  180.     long stksize, offset;
  181.  
  182.     if((fd = open(fn, 2)) < 0)
  183.     {
  184.     perror(fn);
  185.     return 1;
  186.     }
  187.     
  188.     offset = find_offset(fd, fn, &what);
  189.     if (offset < 0)
  190.       {
  191.     close (fd);
  192.     return 1;
  193.       }
  194.  
  195.     if(lseek(fd, offset, 0) != offset)
  196.     {
  197.     perror(fn);
  198.     close(fd);
  199.     return 1;
  200.     }
  201.     read(fd, &stksize, sizeof(long));
  202.     printf("%s: %s was %ld (%dK)\n",
  203.          fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
  204.     
  205.     lseek(fd, -((long)sizeof(long)), 1);
  206.     
  207.     if(write(fd, &newstksize, sizeof(long)) != sizeof(long))
  208.     {
  209.     perror(fn);
  210.     close(fd);
  211.     return 1;
  212.     }
  213.     
  214.     lseek(fd, -((long)sizeof(long)), 1);
  215.     
  216.     read(fd, &stksize, sizeof(long));
  217.     printf("%s: %s now is %ld (%dK)\n",
  218.          fn, sym_names[what] + 1, stksize, (int)(stksize/1024));
  219.     return close(fd) != 0;
  220. }
  221.  
  222. #ifdef WORD_ALIGNED
  223. #ifndef atarist
  224. # define lread  read
  225. # define lwrite write
  226. #endif
  227.  
  228. /*
  229.  * read header -- return !0 on err
  230.   */
  231. #define ck_read(fd, addr, siz) \
  232.   if((long)siz != lread(fd, addr, (long)siz)) return !0;
  233.   
  234. int read_head (fd, a)
  235. int fd;
  236. struct aexec *a;
  237. {
  238.     ck_read(fd, &a->a_magic,   sizeof(a->a_magic));
  239.     ck_read(fd, &a->a_text,    sizeof(a->a_text));
  240.     ck_read(fd, &a->a_data,    sizeof(a->a_data));
  241.     ck_read(fd, &a->a_bss,     sizeof(a->a_bss));
  242.     ck_read(fd, &a->a_syms,    sizeof(a->a_syms));
  243.     ck_read(fd, &a->a_AZero1,  sizeof(a->a_AZero1));
  244.     ck_read(fd, &a->a_AZero2,  sizeof(a->a_AZero2));
  245.     ck_read(fd, &a->a_isreloc, sizeof(a->a_isreloc));
  246.     return 0;
  247. }
  248.  
  249. int read_sym(fd, s)
  250. int fd;
  251. struct asym *s;
  252. {
  253.     ck_read(fd, s->a_name, 8);
  254.     ck_read(fd, &(s->a_type), sizeof(short));
  255.     ck_read(fd, &(s->a_value), sizeof(long));
  256.     return 0;
  257. }
  258. #endif
  259.