Home
       size.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       size.c (3016B)
       ---
            1 #include <errno.h>
            2 #include <limits.h>
            3 #include <stdarg.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <string.h>
            7 
            8 #include <scc/ar.h>
            9 #include <scc/arg.h>
           10 #include <scc/mach.h>
           11 
           12 struct sizes {
           13         unsigned long long text;
           14         unsigned long long data;
           15         unsigned long long bss;
           16 };
           17 
           18 static int status;
           19 static char *filename, *membname;
           20 static int tflag;
           21 static unsigned long long ttext, tdata, tbss, ttotal;
           22 char *argv0;
           23 
           24 static void
           25 error(char *fmt, ...)
           26 {
           27         va_list va;
           28 
           29         va_start(va, fmt);
           30         fprintf(stderr, "size: %s: ", filename);
           31         if (membname)
           32                 fprintf(stderr, "%s: ", membname);
           33         vfprintf(stderr, fmt, va);
           34         putc('\n', stderr);
           35         va_end(va);
           36 
           37         status = EXIT_FAILURE;
           38 }
           39 
           40 static void
           41 sizeobj(FILE *fp, int type)
           42 {
           43         int i;
           44         Obj *obj;
           45         unsigned long long total, *p;
           46         struct sizes siz;
           47         Section sec;
           48 
           49         if ((obj = newobj(type)) == NULL) {
           50                 error("failed allocation");
           51                 return;
           52         }
           53 
           54         if (readobj(obj, fp) < 0) {
           55                 error("invalid file");
           56                 goto err;
           57         }
           58 
           59         siz.text = siz.data = siz.bss = 0;
           60         for (i = 0; getsec(obj, &i, &sec); i++) {
           61                 switch (sec.type) {
           62                 case 'R':
           63                 case 'T':
           64                         p = &siz.text;
           65                         break;
           66                 case 'D':
           67                         p = &siz.data;
           68                         break;
           69                 case 'B':
           70                         p = &siz.bss;
           71                         break;
           72                 default:
           73                         continue;
           74                 }
           75 
           76                 if (*p > ULLONG_MAX - sec.size) {
           77                         error("integer overflow");
           78                         goto err;
           79                 }
           80                         
           81                 *p += sec.size;
           82         }
           83 
           84         total = siz.text + siz.data + siz.bss;
           85         printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n",
           86                siz.text,
           87                siz.data,
           88                siz.bss,
           89                total, total, filename);
           90 
           91         ttext += siz.text;
           92         tdata += siz.data;
           93         tbss += siz.bss;
           94         ttotal += total;
           95 
           96 err:
           97         delobj(obj);
           98 }
           99 
          100 static void
          101 sizelib(FILE *fp)
          102 {
          103         int t;
          104         long off, cur;
          105         char memb[SARNAM+1];
          106 
          107         for (;;) {
          108                 cur = ftell(fp);
          109                 off = armember(fp, memb);
          110                 switch (off) {
          111                 case -1:
          112                         error("library corrupted");
          113                         if (ferror(fp))
          114                                 error(strerror(errno));
          115                 case 0:
          116                         return;
          117                 default:
          118                         membname = memb;
          119                         if ((t = objprobe(fp, NULL)) != -1)
          120                                 sizeobj(fp, t);
          121                         membname = NULL;
          122                         fseek(fp, cur, SEEK_SET);
          123                         fseek(fp, off, SEEK_CUR);
          124                         break;
          125                 }
          126         }
          127 }
          128 
          129 static void
          130 size(char *fname)
          131 {
          132         int t;
          133         FILE *fp;
          134 
          135         filename = fname;
          136         if ((fp = fopen(fname, "rb")) == NULL) {
          137                 error(strerror(errno));
          138                 return;
          139         }
          140 
          141         if ((t = objprobe(fp, NULL)) != -1)
          142                 sizeobj(fp, t);
          143         else if (archive(fp))
          144                 sizelib(fp);
          145         else
          146                 error("bad format");
          147 
          148         fclose(fp);
          149 }
          150 
          151 static void
          152 usage(void)
          153 {
          154         fputs("usage: size [-t] [file...]\n", stderr);
          155         exit(EXIT_FAILURE);
          156 }
          157 
          158 int
          159 main(int argc, char *argv[])
          160 {
          161         unsigned long long total;
          162 
          163         ARGBEGIN {
          164         case 't':
          165                 tflag = 1;
          166                 break;
          167         default:
          168                 usage();
          169         } ARGEND
          170 
          171         puts("text\tdata\tbss\tdec\thex\tfilename");
          172 
          173         if (argc == 0) {
          174                 size("a.out");
          175         } else {
          176                 for (; *argv; ++argv)
          177                         size(*argv);
          178         }
          179 
          180         if (tflag) {
          181                 total = ttext + tdata + tbss;
          182                 printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n",
          183                        ttext, tdata, tbss, total, total, "(TOTALS)");
          184         }
          185 
          186         if (fflush(stdout)) {
          187                 fprintf(stderr,
          188                         "size: error writing in output:%s\n",
          189                         strerror(errno));
          190                 status = 1;
          191         }
          192 
          193         return status;
          194 }