Home
       coff32read.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
       ---
       coff32read.c (6442B)
       ---
            1 #include <assert.h>
            2 #include <ctype.h>
            3 #include <stdint.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <string.h>
            7 
            8 #include <scc/mach.h>
            9 
           10 #include "../libmach.h"
           11 #include "coff32.h"
           12 
           13 static void
           14 unpack_hdr(int order, unsigned char *buf, FILHDR *hdr)
           15 {
           16         int n;
           17 
           18         n = unpack(order,
           19                    buf,
           20                    "sslllss",
           21                    &hdr->f_magic,
           22                    &hdr->f_nscns,
           23                    &hdr->f_timdat,
           24                    &hdr->f_symptr,
           25                    &hdr->f_nsyms,
           26                    &hdr->f_opthdr,
           27                    &hdr->f_flags);
           28         assert(n == FILHSZ);
           29 }
           30 
           31 static void
           32 unpack_line(int order, unsigned char *buf, LINENO *lp)
           33 {
           34         int n;
           35 
           36         n = unpack(order,
           37                    buf,
           38                    "lls",
           39                    &lp->l_symndx,
           40                    &lp->l_paddr,
           41                    &lp->l_lnno);
           42         assert(n == LINESZ);
           43 }
           44 
           45 static void
           46 unpack_scn(int order, unsigned char *buf, SCNHDR *scn)
           47 {
           48         int n;
           49 
           50         n = unpack(order,
           51                   buf,
           52                   "'8llllllssl",
           53                   scn->s_name,
           54                   &scn->s_paddr,
           55                   &scn->s_vaddr,
           56                   &scn->s_size,
           57                   &scn->s_scnptr,
           58                   &scn->s_relptr,
           59                   &scn->s_lnnoptr,
           60                   &scn->s_nrelloc,
           61                   &scn->s_nlnno,
           62                   &scn->s_flags);
           63         assert(n == SCNHSZ);
           64 }
           65 
           66 static void
           67 unpack_ent(int order, unsigned char *buf, SYMENT *ent)
           68 {
           69         int n;
           70         char *s;
           71 
           72         n = unpack(order,
           73                    buf,
           74                    "'8lsscc",
           75                    ent->n_name,
           76                    &ent->n_value,
           77                    &ent->n_scnum,
           78                    &ent->n_type,
           79                    &ent->n_sclass,
           80                    &ent->n_numaux);
           81         assert(n == SYMESZ);
           82 
           83         s = ent->n_name;
           84         if (!s[0] && !s[1] && !s[2] && !s[3])
           85                 unpack(order, buf, "ll", &ent->n_zeroes, &ent->n_offset);
           86 }
           87 
           88 static void
           89 unpack_reloc(int order, unsigned char *buf, RELOC *rel)
           90 {
           91         int n;
           92 
           93         n = unpack(order,
           94                    buf,
           95                    "lls",
           96                    &rel->r_vaddr,
           97                    &rel->r_symndx,
           98                    &rel->r_type);
           99         assert(n == RELSZ);
          100 }
          101 
          102 static void
          103 unpack_aout(int order, unsigned char *buf, AOUTHDR *aout)
          104 {
          105         int n;
          106 
          107         n = unpack(order,
          108                    buf,
          109                    "ssllllll",
          110                    &aout->magic,
          111                    &aout->vstamp,
          112                    &aout->tsize,
          113                    &aout->dsize,
          114                    &aout->bsize,
          115                    &aout->entry,
          116                    &aout->text_start,
          117                    &aout->data_start);
          118         assert(n == AOUTSZ);
          119 }
          120 
          121 static int
          122 readhdr(Obj *obj, FILE *fp)
          123 {
          124         FILHDR *hdr;
          125         struct coff32 *coff;
          126         unsigned char buf[FILHSZ];
          127 
          128         coff  = obj->data;
          129         hdr = &coff->hdr;
          130 
          131         if (fread(buf, FILHSZ, 1, fp) != 1)
          132                 return 0;
          133         unpack_hdr(ORDER(obj->type), buf, hdr);
          134 
          135         return 1;
          136 }
          137 
          138 static int
          139 readstr(Obj *obj, FILE *fp)
          140 {
          141         FILHDR *hdr;
          142         struct coff32 *coff;
          143         long siz;
          144         char *str;
          145         unsigned char buf[10];
          146 
          147         coff  = obj->data;
          148         hdr = &coff->hdr;
          149 
          150         coff->strsiz = 0;
          151         coff->strtbl = NULL;
          152 
          153         if (hdr->f_nsyms == 0)
          154                 return 1;
          155 
          156         if (fread(buf, 4, 1, fp) != 1)
          157                 return 0;
          158         unpack(ORDER(obj->type), buf, "l", &siz);
          159         if (siz < 4 || siz > SIZE_MAX)
          160                 return 0;
          161         if (siz == 4)
          162                 return 1;
          163 
          164         if ((str = malloc(siz)) == NULL)
          165                 return 0;
          166         coff->strtbl = str;
          167         coff->strsiz = siz;
          168 
          169         return fread(str+4, siz-4, 1, fp) == 1;
          170 }
          171 
          172 static int
          173 readreloc(Obj *obj, FILE *fp)
          174 {
          175         int i;
          176         long j;
          177         RELOC **rels, *rp;
          178         SCNHDR *scn;
          179         FILHDR *hdr;
          180         struct coff32 *coff;
          181         unsigned char buf[RELSZ];
          182 
          183         coff  = obj->data;
          184         hdr = &coff->hdr;
          185 
          186         if (hdr->f_nscns == 0)
          187                 return 1;
          188 
          189         rels = calloc(hdr->f_nscns, sizeof(*rels));
          190         if (!rels)
          191                 return 0;
          192         coff->rels = rels;
          193 
          194         for (i = 0; i < hdr->f_nscns; i++) {
          195                 scn = &coff->scns[i];
          196                 if (scn->s_nrelloc == 0)
          197                         continue;
          198 
          199                 if (!objpos(obj, fp, scn->s_relptr))
          200                         return 0;
          201 
          202                 rp = calloc(scn->s_nrelloc, sizeof(RELOC));
          203                 if (!rp)
          204                         return 0;
          205                 rels[i] = rp;
          206 
          207                 for (j = 0; j < scn->s_nrelloc; j++) {
          208                         if (fread(buf, RELSZ, 1, fp) != 1)
          209                                 return 0;
          210                         unpack_reloc(ORDER(obj->type), buf, &rp[i]);
          211                         if (rp[i].r_symndx >= hdr->f_nsyms)
          212                                 return 0;
          213                 }
          214         }
          215 
          216         return 1;
          217 }
          218 
          219 static int
          220 readents(Obj *obj, FILE *fp)
          221 {
          222         FILHDR *hdr;
          223         struct coff32 *coff;
          224         SYMENT *ent;
          225         long i;
          226         unsigned char buf[SYMESZ];
          227 
          228         coff  = obj->data;
          229         hdr = &coff->hdr;
          230 
          231         if (hdr->f_nsyms == 0)
          232                 return 1;
          233 
          234         ent = calloc(hdr->f_nsyms, sizeof(*ent));
          235         if (!ent)
          236                 return 0;
          237         coff->ents = ent;
          238 
          239         if (!objpos(obj, fp, hdr->f_symptr))
          240                 return 0;
          241         for (i = 0; i < hdr->f_nsyms; i++) {
          242                 if (fread(buf, SYMESZ, 1, fp) != 1)
          243                         return 0;
          244                 unpack_ent(ORDER(obj->type), buf, &ent[i]);
          245                 if (ent->n_scnum > hdr->f_nscns)
          246                         return 0;                
          247         }
          248 
          249         return 1;
          250 }
          251 
          252 static int
          253 readscns(Obj *obj, FILE *fp)
          254 {
          255         FILHDR *hdr;
          256         struct coff32 *coff;
          257         SCNHDR *scn;
          258         long i;
          259         unsigned char buf[SCNHSZ];
          260 
          261         coff  = obj->data;
          262         hdr = &coff->hdr;
          263 
          264         if (hdr->f_nscns == 0)
          265                 return 1;
          266 
          267         scn = calloc(hdr->f_nscns, sizeof(*scn));
          268         if (!scn)
          269                 return 0;
          270         coff->scns = scn;
          271 
          272         for (i = 0; i < hdr->f_nscns; i++) {
          273                 if (fread(buf, SCNHSZ, 1, fp) < 0)
          274                         return 0;
          275                 unpack_scn(ORDER(obj->type), buf, &scn[i]);
          276         }
          277 
          278         return 1;
          279 }
          280 
          281 static int
          282 readlines(Obj *obj, FILE *fp)
          283 {
          284         int i,j;
          285         LINENO **lines, *lp;
          286         FILHDR *hdr;
          287         SCNHDR *scn;
          288         struct coff32 *coff;
          289         unsigned char buf[LINESZ];
          290 
          291         coff  = obj->data;
          292         hdr = &coff->hdr;
          293 
          294         if (hdr->f_nscns == 0)
          295                 return 1;
          296 
          297         lines = calloc(hdr->f_nscns, sizeof(lp));
          298         if (!lines)
          299                 return 0;
          300         coff->lines = lines;
          301 
          302         for (i = 0; i < hdr->f_nscns; i++) {
          303                 scn = &coff->scns[i];
          304                 if (scn->s_nlnno == 0)
          305                         continue;
          306 
          307                 lp = calloc(sizeof(*lp), scn->s_nlnno);
          308                 if (!lp)
          309                         return 0;
          310                 lines[i] = lp;
          311 
          312                 for (j = 0; j < scn->s_nlnno; j++) {
          313                         if (!objpos(obj, fp, scn->s_lnnoptr))
          314                                 return 0;
          315                         if (fread(buf, LINESZ, 1, fp) == 1)
          316                                 return 0;
          317                         unpack_line(ORDER(obj->type), buf, &lp[j]);
          318                         if (lp[i].l_symndx >= hdr->f_nsyms)
          319                                 return 0;
          320                 }
          321         }
          322 
          323         return 1;
          324 }
          325 
          326 static int
          327 readaout(Obj *obj, FILE *fp)
          328 {
          329         struct coff32 *coff = obj->data;
          330         FILHDR *hdr = &coff->hdr;
          331         unsigned char buf[AOUTSZ];
          332 
          333         if (hdr->f_opthdr == 0)
          334                 return 1;
          335 
          336         if (fread(buf, AOUTSZ, 1, fp) != 1)
          337                 return 0;
          338 
          339         unpack_aout(ORDER(obj->type), buf, &coff->aout);
          340 
          341         return 1;
          342 }
          343 
          344 int
          345 coff32read(Obj *obj, FILE *fp)
          346 {
          347         long i;
          348         struct coff32 *coff = obj->data;
          349         FILHDR *hdr = &coff->hdr;
          350 
          351         if (!readhdr(obj, fp))
          352                 return -1;
          353         if (!readaout(obj, fp))
          354                 return -1;
          355         if (!readscns(obj, fp))
          356                 return -1;
          357         if (!readents(obj, fp))
          358                 return -1;
          359         if (!readstr(obj, fp))
          360                 return -1;
          361         if (!readreloc(obj, fp))
          362                 return -1;
          363         if (!readlines(obj, fp))
          364                 return -1;
          365 
          366         for (i = 0; i < hdr->f_nsyms; i++) {
          367                 SYMENT *ent = &coff->ents[i];
          368                 if (ent->n_zeroes != 0 && ent->n_offset > coff->strsiz)
          369                         return -1;
          370         }
          371 
          372         return 0;
          373 }