elfread.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       elfread.c (14837B)
       ---
            1 #include <assert.h>
            2 #include <errno.h>
            3 #include <limits.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <string.h>
            7 
            8 #include <scc/mach.h>
            9 #include <scc/elf.h>
           10 
           11 #include <scc/elf/elftypes.h>
           12 #include <scc/elf/elfhdr.h>
           13 #include <scc/elf/elfphdr.h>
           14 #include <scc/elf/elfshdr.h>
           15 #include <scc/elf/elfent.h>
           16 #include <scc/elf/elfrel.h>
           17 
           18 #include "../libmach.h"
           19 #include "fun.h"
           20 
           21 struct elfunpack {
           22         void (*hdr)(int, unsigned char *, Elfhdr *);
           23         void (*phdr)(int, unsigned char *, Elfphdr *);
           24         void (*sec)(int, unsigned char *, Elfsec *);
           25         void (*sym)(int, unsigned char *, Elfsym *);
           26         void (*rel)(int, unsigned char *, Elfrel *);
           27         void (*rela)(int, unsigned char *, Elfrel *);
           28 
           29         int hdrsiz;
           30         int phdrsiz;
           31         int shentsiz;
           32         int symsiz;
           33         int relsiz;
           34         int relasiz;
           35 };
           36 
           37 struct elfunpack unpack64;
           38 struct elfunpack unpack32;
           39 
           40 static void
           41 unpack_hdr64(int order, unsigned char *buf, Elfhdr *hdr)
           42 {
           43         Elf64_Ehdr ehdr;
           44         int n;
           45 
           46         n = unpack(order,
           47                    buf,
           48                    "'16sslqqqlssssss",
           49                    ehdr.e_ident,
           50                    &ehdr.e_type,
           51                    &ehdr.e_machine,
           52                    &ehdr.e_version,
           53                    &ehdr.e_entry,
           54                    &ehdr.e_phoff,
           55                    &ehdr.e_shoff,
           56                    &ehdr.e_flags,
           57                    &ehdr.e_ehsize,
           58                    &ehdr.e_phentsize,
           59                    &ehdr.e_phnum,
           60                    &ehdr.e_shentsize,
           61                    &ehdr.e_shnum,
           62                    &ehdr.e_shstrndx);
           63 
           64         assert(n == ELFH64SZ);
           65 
           66         memcpy(hdr->ident, ehdr.e_ident, EI_NIDENT);
           67         hdr->type = ehdr.e_type;
           68         hdr->machine = ehdr.e_machine;
           69         hdr->version = ehdr.e_version;
           70         hdr->entry = ehdr.e_entry;
           71         hdr->phoff = ehdr.e_phoff;
           72         hdr->shoff = ehdr.e_shoff;
           73         hdr->flags = ehdr.e_flags;
           74         hdr->ehsize = ehdr.e_ehsize;
           75         hdr->phentsize = ehdr.e_phentsize;
           76         hdr->phnum = ehdr.e_phnum;
           77         hdr->shentsize = ehdr.e_shentsize;
           78         hdr->shnum = ehdr.e_shnum;
           79         hdr->shstrndx = ehdr.e_shstrndx;
           80 }
           81 
           82 static void
           83 unpack_hdr32(int order, unsigned char *buf, Elfhdr *hdr)
           84 {
           85         Elf32_Ehdr ehdr;
           86         int n;
           87 
           88         n = unpack(order,
           89                    buf,
           90                    "'16sslllllssssss",
           91                    ehdr.e_ident,
           92                    &ehdr.e_type,
           93                    &ehdr.e_machine,
           94                    &ehdr.e_version,
           95                    &ehdr.e_entry,
           96                    &ehdr.e_phoff,
           97                    &ehdr.e_shoff,
           98                    &ehdr.e_flags,
           99                    &ehdr.e_ehsize,
          100                    &ehdr.e_phentsize,
          101                    &ehdr.e_phnum,
          102                    &ehdr.e_shentsize,
          103                    &ehdr.e_shnum,
          104                    &ehdr.e_shstrndx);
          105 
          106         assert(n == ELFH32SZ);
          107 
          108         memcpy(hdr->ident, ehdr.e_ident, EI_NIDENT);
          109         hdr->type = ehdr.e_type;
          110         hdr->machine = ehdr.e_machine;
          111         hdr->version = ehdr.e_version;
          112         hdr->entry = ehdr.e_entry;
          113         hdr->phoff = ehdr.e_phoff;
          114         hdr->shoff = ehdr.e_shoff;
          115         hdr->flags = ehdr.e_flags;
          116         hdr->ehsize = ehdr.e_ehsize;
          117         hdr->phentsize = ehdr.e_phentsize;
          118         hdr->phnum = ehdr.e_phnum;
          119         hdr->shentsize = ehdr.e_shentsize;
          120         hdr->shnum = ehdr.e_shnum;
          121         hdr->shstrndx = ehdr.e_shstrndx;
          122 }
          123 
          124 static void
          125 unpack_phdr64(int order, unsigned char *buf, Elfphdr *hdr)
          126 {
          127         int n;
          128         Elf64_Phdr phdr;
          129 
          130         n = unpack(order,
          131                    buf,
          132                    "llqqqqqq",
          133                    &phdr.p_type,
          134                    &phdr.p_flags,
          135                    &phdr.p_offset,
          136                    &phdr.p_vaddr,
          137                    &phdr.p_paddr,
          138                    &phdr.p_filesz,
          139                    &phdr.p_memsz,
          140                    &phdr.p_align);
          141 
          142         assert(n == ELFP64SZ);
          143 
          144         hdr->type = phdr.p_type;
          145         hdr->flags = phdr.p_flags;
          146         hdr->offset = phdr.p_offset;
          147         hdr->vaddr = phdr.p_vaddr;
          148         hdr->paddr = phdr.p_paddr;
          149         hdr->filesz = phdr.p_filesz;
          150         hdr->memsz = phdr.p_memsz;
          151         hdr->align = phdr.p_align;
          152 }
          153 
          154 static void
          155 unpack_phdr32(int order, unsigned char *buf, Elfphdr *hdr)
          156 {
          157         int n;
          158         Elf32_Phdr phdr;
          159 
          160         n = unpack(order,
          161                    buf,
          162                    "llllllll",
          163                    &phdr.p_type,
          164                    &phdr.p_offset,
          165                    &phdr.p_vaddr,
          166                    &phdr.p_paddr,
          167                    &phdr.p_filesz,
          168                    &phdr.p_memsz,
          169                    &phdr.p_flags,
          170                    &phdr.p_align);
          171 
          172         assert(n == ELFP32SZ);
          173 
          174         hdr->type = phdr.p_type;
          175         hdr->flags = phdr.p_flags;
          176         hdr->offset = phdr.p_offset;
          177         hdr->vaddr = phdr.p_vaddr;
          178         hdr->paddr = phdr.p_paddr;
          179         hdr->filesz = phdr.p_filesz;
          180         hdr->memsz = phdr.p_memsz;
          181         hdr->align = phdr.p_align;
          182 }
          183 
          184 static void
          185 unpack_shdr64(int order, unsigned char *buf, Elfsec *sec)
          186 {
          187         int n;
          188         Elf64_Shdr shdr;
          189 
          190         n = unpack(order,
          191                    buf,
          192                    "llqqqqllqq",
          193                    &shdr.sh_name,
          194                    &shdr.sh_type,
          195                    &shdr.sh_flags,
          196                    &shdr.sh_addr,
          197                    &shdr.sh_offset,
          198                    &shdr.sh_size,
          199                    &shdr.sh_link,
          200                    &shdr.sh_info,
          201                    &shdr.sh_addralign,
          202                    &shdr.sh_entsize);
          203 
          204         assert(n == ELFS64SZ);
          205 
          206         sec->sh_name = shdr.sh_name;
          207         sec->type = shdr.sh_type;
          208         sec->flags = shdr.sh_flags;
          209         sec->addr = shdr.sh_addr;
          210         sec->offset = shdr.sh_offset;
          211         sec->size = shdr.sh_size;
          212         sec->link = shdr.sh_link;
          213         sec->info = shdr.sh_info;
          214         sec->addralign = shdr.sh_addralign;
          215         sec->entsize = shdr.sh_entsize;
          216 }
          217 
          218 static void
          219 unpack_shdr32(int order, unsigned char *buf, Elfsec *sec)
          220 {
          221         int n;
          222         Elf32_Shdr shdr;
          223 
          224         n = unpack(order,
          225                    buf,
          226                    "llllllllll",
          227                    &shdr.sh_name,
          228                    &shdr.sh_type,
          229                    &shdr.sh_flags,
          230                    &shdr.sh_addr,
          231                    &shdr.sh_offset,
          232                    &shdr.sh_size,
          233                    &shdr.sh_link,
          234                    &shdr.sh_info,
          235                    &shdr.sh_addralign,
          236                    &shdr.sh_entsize);
          237 
          238         assert(n == ELFS32SZ);
          239 
          240         sec->sh_name = shdr.sh_name;
          241         sec->type = shdr.sh_type;
          242         sec->flags = shdr.sh_flags;
          243         sec->addr = shdr.sh_addr;
          244         sec->offset = shdr.sh_offset;
          245         sec->size = shdr.sh_size;
          246         sec->link = shdr.sh_link;
          247         sec->info = shdr.sh_info;
          248         sec->addralign = shdr.sh_addralign;
          249         sec->entsize = shdr.sh_entsize;
          250 }
          251 
          252 static void
          253 unpack_sym64(int order, unsigned char *buf, Elfsym *sym)
          254 {
          255         int n;
          256         Elf64_Sym ent;
          257 
          258         n = unpack(order,
          259                    buf,
          260                    "lccsqq",
          261                    &ent.st_name,
          262                    &ent.st_info,
          263                    &ent.st_other,
          264                    &ent.st_shndx,
          265                    &ent.st_value,
          266                    &ent.st_size);
          267 
          268         assert(n == ELFE64SZ);
          269 
          270         sym->st_name = ent.st_name;
          271         sym->info = ent.st_info;
          272         sym->other = ent.st_other;
          273         sym->shndx = ent.st_shndx;
          274         sym->value = ent.st_value;
          275         sym->size = ent.st_size;
          276 }
          277 
          278 static void
          279 unpack_sym32(int order, unsigned char *buf, Elfsym *sym)
          280 {
          281         int n;
          282         Elf32_Sym ent;
          283 
          284         n = unpack(order,
          285                    buf,
          286                    "lllccs",
          287                    &ent.st_name,
          288                    &ent.st_value,
          289                    &ent.st_size,
          290                    &ent.st_info,
          291                    &ent.st_other,
          292                    &ent.st_shndx);
          293 
          294         assert(n == ELFE32SZ);
          295 
          296         sym->st_name = ent.st_name;
          297         sym->info = ent.st_info;
          298         sym->other = ent.st_other;
          299         sym->shndx = ent.st_shndx;
          300         sym->value = ent.st_value;
          301         sym->size = ent.st_size;
          302 }
          303 
          304 static void
          305 unpack_rel64(int order, unsigned char *buf, Elfrel *rp)
          306 {
          307         int n;
          308         Elf64_Rel r;
          309 
          310         n = unpack(order,
          311                    buf,
          312                    "qq",
          313                    &r.r_offset,
          314                    &r.r_info);
          315 
          316         assert(n == ELFR64SZ);
          317 
          318         rp->off = r.r_offset;
          319         rp->info = r.r_info;
          320         rp->addend = 0;
          321 }
          322 
          323 static void
          324 unpack_rel32(int order, unsigned char *buf, Elfrel *rp)
          325 {
          326         int n;
          327         Elf32_Rel r;
          328 
          329         n = unpack(order,
          330                    buf,
          331                    "ll",
          332                    &r.r_offset,
          333                    &r.r_info);
          334 
          335         assert(n == ELFR32SZ);
          336 
          337         rp->off = r.r_offset;
          338         rp->info = r.r_info;
          339         rp->addend = 0;
          340 }
          341 
          342 static void
          343 unpack_rela64(int order, unsigned char *buf, Elfrel *rp)
          344 {
          345         int n;
          346         Elf64_Rela r;
          347 
          348         n = unpack(order,
          349                    buf,
          350                    "qqq",
          351                    &r.r_offset,
          352                    &r.r_info,
          353                    &r.r_addend);
          354 
          355         assert(n == ELFRA64SZ);
          356 
          357         rp->off = r.r_offset;
          358         rp->info = r.r_info;
          359         rp->addend = r.r_addend;
          360 }
          361 
          362 static void
          363 unpack_rela32(int order, unsigned char *buf, Elfrel *rp)
          364 {
          365         int n;
          366         Elf32_Rela r;
          367 
          368         n = unpack(order,
          369                    buf,
          370                    "lll",
          371                    &r.r_offset,
          372                    &r.r_info,
          373                    &r.r_addend);
          374 
          375         assert(n == ELFRA32SZ);
          376 
          377         rp->off = r.r_offset;
          378         rp->info = r.r_info;
          379         rp->addend = r.r_addend;
          380 }
          381 
          382 static int
          383 readhdr(Obj *obj, FILE *fp)
          384 {
          385         Elf *elf = obj->data;
          386         Elfhdr *hdr = &elf->hdr;
          387         Elfunpack *u = elf->unpack;
          388         unsigned char buf[ELFH64SZ];
          389 
          390         if (fread(buf, u->hdrsiz, 1, fp) != 1)
          391                 return 0;
          392         (*u->hdr)(ORDER(obj->type), buf, hdr);
          393 
          394         if (hdr->shnum > INT_MAX ||  hdr->phnum > INT_MAX)
          395                 return 0;
          396 
          397         switch (hdr->type) {
          398         case ET_REL:
          399         case ET_EXEC:
          400         case ET_DYN:
          401                 return 1;
          402         default:
          403                 return 0;
          404         }
          405 }
          406 
          407 static int
          408 readphdr(Obj *obj, FILE *fp)
          409 {
          410         int i, r;
          411         Elfphdr *phdr;
          412         Elf *elf = obj->data;
          413         Elfhdr *hdr = &elf->hdr;
          414         Elfunpack *u = elf->unpack;
          415         unsigned char *buf;
          416 
          417         r = 0;
          418         if (hdr->phnum > 0
          419         &&  (hdr->phoff == 0 || hdr->phentsize < u->phdrsiz)) {
          420                 errno = ERANGE;
          421                 goto err0;
          422         }
          423         if (hdr->phoff == 0 || hdr->phnum == 0)
          424                 return 1;
          425 
          426         if ((buf = malloc(hdr->phentsize)) == NULL)
          427                 goto err0;
          428         if ((phdr = calloc(hdr->phnum, sizeof(*phdr))) == NULL)
          429                 goto err1;
          430         elf->phdr = phdr;
          431 
          432         if (!objpos(obj, fp, hdr->phoff))
          433                 goto err1;
          434 
          435         for (i = 0; i < hdr->phnum; i++) {
          436                 if (fread(buf, hdr->phentsize, 1, fp) != 1)
          437                         goto err1;
          438                 (*u->phdr)(ORDER(obj->type), buf, &phdr[i]);
          439                 if (phdr[i].offset > LONG_MAX)
          440                         goto  err1;
          441         }
          442         r = 1;
          443 
          444 err1:
          445         free(buf);
          446 err0:
          447         return r;
          448 }
          449 
          450 static int
          451 readshdr(Obj *obj, FILE *fp)
          452 {
          453         int r, nsec;
          454         Elfsec *sec;
          455         Elf *elf = obj->data;
          456         Elfhdr *hdr = &elf->hdr;
          457         Elfunpack *u = elf->unpack;
          458         unsigned char *buf;
          459 
          460         if (hdr->shoff == 0)
          461                 return 1;
          462 
          463         if (!objpos(obj, fp, hdr->shoff))
          464                 return 0;
          465 
          466         if (hdr->shnum != SHN_UNDEF) {
          467                 if (hdr->shnum > INT_MAX)
          468                         return 0;
          469                 nsec = hdr->shnum;
          470         } else {
          471                 Elfsec sec0;
          472                 fpos_t pos;
          473                 unsigned char buf0[ELFS64SZ];
          474 
          475                 fgetpos(fp, &pos);
          476                 fread(buf0, u->shentsiz, 1, fp);
          477                 fsetpos(fp, &pos);
          478 
          479                 if (ferror(fp))
          480                         return 0;
          481 
          482                 (*u->sec)(ORDER(obj->type), buf0, &sec0);
          483                 if (sec0.size > INT_MAX)
          484                         return 0;
          485                 nsec = sec0.size;
          486         }
          487 
          488         if (nsec == 0)
          489                 return 1;
          490 
          491         r = 0;
          492         if ((buf = malloc(hdr->shentsize)) == NULL)
          493                 return 0;
          494         if ((sec = calloc(nsec, sizeof(*sec))) == NULL)
          495                 goto err;
          496         elf->secs = sec;
          497         elf->nsec = nsec;
          498 
          499         for ( ; nsec-- > 0; ++sec) {
          500                 if (fread(buf, hdr->shentsize, 1, fp) != 1)
          501                         goto err;
          502                 (*u->sec)(ORDER(obj->type), buf, sec);
          503         }
          504         r = 1;
          505 err:
          506         free(buf);
          507         return r;
          508 }
          509 
          510 static int
          511 readstrtbl(Obj *obj, FILE *fp)
          512 {
          513         char *s;
          514         int idx;
          515         Elfsec *tbl, *sec;
          516         Elf *elf = obj->data;
          517         Elfhdr *hdr = &elf->hdr;
          518 
          519         if (hdr->shstrndx != SHN_XINDEX) {
          520                 idx = hdr->shstrndx;
          521         } else {
          522                 if (hdr->shnum == 0)
          523                         return 0;
          524                 sec = elf->secs;
          525                 if (sec->link > INT_MAX)
          526                         return 0;
          527                 idx = sec->link;
          528         }
          529         if (idx > elf->nsec || elf->secs[idx].type != SHT_STRTAB)
          530                 return 0;
          531         elf->secstrtbl = idx;
          532 
          533         for (sec = elf->secs; sec < &elf->secs[elf->nsec]; ++sec) {
          534                 if (sec->type != SHT_STRTAB)
          535                         continue;
          536 
          537                 if (sec->size > SIZE_MAX)
          538                         return 0;
          539                 if ((s = malloc(sec->size)) == NULL)
          540                         return 0;
          541                 sec->strtbl = s;
          542 
          543                 if (!objpos(obj, fp, sec->offset))
          544                         return 0;
          545                 if (fread(s, sec->size, 1, fp) != 1)
          546                         return 0;
          547         }
          548 
          549         return 1;
          550 }
          551 
          552 static int
          553 secsize(Elfsec *sec, int onent, int entsiz)
          554 {
          555         unsigned long long nent;
          556 
          557         if (sec->entsize == 0 || sec->entsize < entsiz)
          558                 return -1;
          559         nent = sec->size / sec->entsize;
          560         if (nent > INT_MAX - onent)
          561                 return -1;
          562 
          563         return nent;
          564 }
          565 
          566 static int
          567 readsyms(Obj *obj, Elfsec *sec, FILE *fp)
          568 {
          569         int r = 0, n, oldn;
          570         Elfsym *sym;
          571         Elfsec *tbl;
          572         Elf *elf = obj->data;
          573         Elfunpack *u = elf->unpack;
          574         Elfhdr *hdr = &elf->hdr;
          575         unsigned char *buf;
          576 
          577         if ((n = secsize(sec, elf->nsym, u->symsiz)) <= 0)
          578                 return n;
          579         if ((buf = malloc(sec->entsize)) == NULL)
          580                 return 0;
          581 
          582         oldn = elf->nsym;
          583         sym = realloc(elf->syms, (oldn + n) * sizeof(Elfsym));
          584         if (!sym)
          585                 goto err;
          586         elf->syms = sym;
          587         elf->nsym += n;
          588 
          589         if (!objpos(obj, fp, sec->offset))
          590                 goto err;
          591 
          592         if (sec->link >= hdr->shnum)
          593                 goto err;
          594         tbl = &elf->secs[sec->link];
          595         if (tbl->type != SHT_STRTAB)
          596                 goto err;
          597 
          598         for (sym = &elf->syms[oldn] ; n-- > 0 ; ++sym) {
          599                 if (fread(buf, sec->entsize, 1, fp) != 1)
          600                         goto err;
          601                 (*u->sym)(ORDER(obj->type), buf, sym);
          602                 sym->symsec = sec;
          603                 if (sym->st_name >= tbl->size)
          604                         goto err;
          605                 sym->name = &tbl->strtbl[sym->st_name];
          606 
          607                 switch (sym->shndx) {
          608                 case SHN_XINDEX:
          609                         /*
          610                          * Elf supports an extension mechanism to allow
          611                          * indexes bigger than 4 bytes. We don't care
          612                          * and we reject elf files using this feature.
          613                          */
          614                         goto err;
          615                 case SHN_UNDEF:
          616                 case SHN_ABS:
          617                 case SHN_COMMON:
          618                         break;
          619                 default:
          620                         if (sym->shndx >= elf->nsec)
          621                                 goto err;
          622                         break;
          623                 }
          624         }
          625         r = 1;
          626 
          627 err:
          628         free(buf);
          629         return r;
          630 }
          631 
          632 static int
          633 readrels(Obj *obj, Elfsec *sec, FILE *fp)
          634 {
          635         int r = 0, oldn, n, min;
          636         Elf *elf = obj->data;
          637         Elfunpack *u = elf->unpack;
          638         Elfrel *rp;
          639         void (*fn)(int, unsigned char *, Elfrel *);
          640         unsigned char *buf;
          641 
          642         if (sec->type == SHT_RELA) {
          643                 fn = u->rela;
          644                 min = u->relasiz;
          645         } else {
          646                 fn = u->rel;
          647                 min = u->relsiz;
          648         }
          649 
          650         if (!objpos(obj, fp, sec->offset))
          651                 goto err;
          652 
          653         if ((n = secsize(sec, elf->nrel, min)) <= 0)
          654                 return n;
          655         if ((buf = malloc(sec->entsize)) == NULL)
          656                 return 0;
          657 
          658         oldn = elf->nrel;
          659         rp = realloc(elf->rels, (oldn + n) * sizeof(Elfrel));
          660         if (!rp)
          661                 goto err;
          662         elf->rels = rp;
          663         elf->nrel += n;
          664 
          665         for (rp = &elf->rels[oldn]; n-- > 0; ++rp) {
          666                 if (fread(buf, sec->entsize, 1, fp) != 1)
          667                         goto err;
          668                 (*fn)(ORDER(obj->type), buf, rp);
          669         }
          670         r = 1;
          671 
          672 err:
          673         free(buf);
          674         return r;
          675 }
          676 
          677 static int
          678 procsecs(Obj *obj, FILE *fp)
          679 {
          680         Elf *elf = obj->data;
          681         Elfsec *tbl, *sec;
          682 
          683         tbl = &elf->secs[elf->secstrtbl];
          684         for (sec = elf->secs; sec < &elf->secs[elf->nsec]; ++sec) {
          685                 if (sec->sh_name >= tbl->size)
          686                         return 0;
          687                 sec->name = &tbl->strtbl[sec->sh_name];
          688 
          689                 switch (sec->type) {
          690                 case SHT_DYNSYM:
          691                 case SHT_SYMTAB:
          692                         if (!readsyms(obj, sec, fp))
          693                                 return 0;
          694                         break;
          695                 case SHT_RELA:
          696                 case SHT_REL:
          697                         if (!readrels(obj, sec, fp))
          698                                 return 0;
          699                         break;
          700                 }
          701         }
          702 
          703         return 1;
          704 }
          705 
          706 int
          707 elfread(Obj *obj, FILE *fp)
          708 {
          709         fpos_t pos;
          710         Elf *elf = obj->data;
          711         unsigned char buf[EI_CLASS+1];
          712 
          713         fgetpos(fp, &pos);
          714         fread(buf, sizeof(buf), 1, fp);
          715         fsetpos(fp, &pos);
          716 
          717         if (buf[EI_CLASS] == ELFCLASS64) {
          718                 if (elf->is32)
          719                         return 0;
          720                 elf->is32 = 0;
          721                 elf->unpack = &unpack64;
          722         } else {
          723                 elf->is32 = 1;
          724                 elf->unpack = &unpack32;
          725         }
          726 
          727         if (!readhdr(obj, fp))
          728                 return -1;
          729         if (!readphdr(obj, fp))
          730                 return -1;
          731         if (!readshdr(obj, fp))
          732                 return -1;
          733         if (!readstrtbl(obj, fp))
          734                 return -1;
          735         if (!procsecs(obj, fp))
          736                 return -1;
          737 
          738         return 0;
          739 }
          740 
          741 struct elfunpack unpack64 = {
          742         .hdr = unpack_hdr64,
          743         .phdr = unpack_phdr64,
          744         .sec = unpack_shdr64,
          745         .sym = unpack_sym64,
          746         .rel = unpack_rel64,
          747         .rela = unpack_rela64,
          748 
          749         .hdrsiz = ELFH64SZ,
          750         .phdrsiz = ELFP64SZ,
          751         .shentsiz = ELFS64SZ,
          752         .symsiz = ELFE64SZ,
          753         .relsiz = ELFR64SZ,
          754         .relasiz = ELFRA64SZ,
          755 };
          756 
          757 struct elfunpack unpack32 = {
          758         .hdr = unpack_hdr32,
          759         .phdr = unpack_phdr32,
          760         .sec = unpack_shdr32,
          761         .sym = unpack_sym32,
          762         .rel = unpack_rel32,
          763         .rela = unpack_rela32,
          764 
          765         .hdrsiz = ELFH32SZ,
          766         .phdrsiz = ELFP32SZ,
          767         .shentsiz = ELFS32SZ,
          768         .symsiz = ELFE32SZ,
          769         .relsiz = ELFR32SZ,
          770         .relasiz = ELFRA32SZ,
          771 };