summaryrefslogtreecommitdiff
path: root/src/libmach/executable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmach/executable.c')
-rw-r--r--src/libmach/executable.c1525
1 files changed, 0 insertions, 1525 deletions
diff --git a/src/libmach/executable.c b/src/libmach/executable.c
deleted file mode 100644
index eae14441a..000000000
--- a/src/libmach/executable.c
+++ /dev/null
@@ -1,1525 +0,0 @@
-// Inferno libmach/executable.c
-// http://code.google.com/p/inferno-os/source/browse/utils/libmach/executable.c
-//
-// Copyright © 1994-1999 Lucent Technologies Inc.
-// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
-// Portions Copyright © 1997-1999 Vita Nuova Limited.
-// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
-// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
-// Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <bootexec.h>
-#include <mach.h>
-#include "elf.h"
-#include "macho.h"
-
-/*
- * All a.out header types. The dummy entry allows canonical
- * processing of the union as a sequence of int32s
- */
-
-typedef struct {
- union{
- /*struct { */
- Exec exechdr; /* a.out.h */
- /* uvlong hdr[1];*/
- /*};*/
- Ehdr32 elfhdr32; /* elf.h */
- Ehdr64 elfhdr64; /* elf.h */
- struct mipsexec mips; /* bootexec.h */
- struct mips4kexec mipsk4; /* bootexec.h */
- struct sparcexec sparc; /* bootexec.h */
- struct nextexec next; /* bootexec.h */
- Machhdr machhdr; /* macho.h */
- } e;
- int32 dummy; /* padding to ensure extra int32 */
-} ExecHdr;
-
-static int nextboot(int, Fhdr*, ExecHdr*);
-static int sparcboot(int, Fhdr*, ExecHdr*);
-static int mipsboot(int, Fhdr*, ExecHdr*);
-static int mips4kboot(int, Fhdr*, ExecHdr*);
-static int common(int, Fhdr*, ExecHdr*);
-static int commonllp64(int, Fhdr*, ExecHdr*);
-static int adotout(int, Fhdr*, ExecHdr*);
-static int elfdotout(int, Fhdr*, ExecHdr*);
-static int machdotout(int, Fhdr*, ExecHdr*);
-static int armdotout(int, Fhdr*, ExecHdr*);
-static int pedotout(int, Fhdr*, ExecHdr*);
-static void setsym(Fhdr*, vlong, int32, vlong, int32, vlong, int32);
-static void setdata(Fhdr*, uvlong, int32, vlong, int32);
-static void settext(Fhdr*, uvlong, uvlong, int32, vlong);
-static void hswal(void*, int, uint32(*)(uint32));
-static uvlong _round(uvlong, uint32);
-
-/*
- * definition of per-executable file type structures
- */
-
-typedef struct Exectable{
- int32 magic; /* big-endian magic number of file */
- char *name; /* executable identifier */
- char *dlmname; /* dynamically loadable module identifier */
- uchar type; /* Internal code */
- uchar _magic; /* _MAGIC() magic */
- Mach *mach; /* Per-machine data */
- int32 hsize; /* header size */
- uint32 (*swal)(uint32); /* beswal or leswal */
- int (*hparse)(int, Fhdr*, ExecHdr*);
-} ExecTable;
-
-extern Mach mmips;
-extern Mach mmips2le;
-extern Mach mmips2be;
-extern Mach msparc;
-extern Mach msparc64;
-extern Mach m68020;
-extern Mach mi386;
-extern Mach mamd64;
-extern Mach marm;
-extern Mach mpower;
-extern Mach mpower64;
-extern Mach malpha;
-
-/* BUG: FIX THESE WHEN NEEDED */
-Mach mmips;
-Mach mmips2le;
-Mach mmips2be;
-Mach msparc;
-Mach msparc64;
-Mach m68020;
-Mach mpower;
-Mach mpower64;
-Mach malpha;
-
-ExecTable exectab[] =
-{
- { V_MAGIC, /* Mips v.out */
- "mips plan 9 executable BE",
- "mips plan 9 dlm BE",
- FMIPS,
- 1,
- &mmips,
- sizeof(Exec),
- beswal,
- adotout },
- { P_MAGIC, /* Mips 0.out (r3k le) */
- "mips plan 9 executable LE",
- "mips plan 9 dlm LE",
- FMIPSLE,
- 1,
- &mmips,
- sizeof(Exec),
- beswal,
- adotout },
- { M_MAGIC, /* Mips 4.out */
- "mips 4k plan 9 executable BE",
- "mips 4k plan 9 dlm BE",
- FMIPS2BE,
- 1,
- &mmips2be,
- sizeof(Exec),
- beswal,
- adotout },
- { N_MAGIC, /* Mips 0.out */
- "mips 4k plan 9 executable LE",
- "mips 4k plan 9 dlm LE",
- FMIPS2LE,
- 1,
- &mmips2le,
- sizeof(Exec),
- beswal,
- adotout },
- { 0x160<<16, /* Mips boot image */
- "mips plan 9 boot image",
- nil,
- FMIPSB,
- 0,
- &mmips,
- sizeof(struct mipsexec),
- beswal,
- mipsboot },
- { (0x160<<16)|3, /* Mips boot image */
- "mips 4k plan 9 boot image",
- nil,
- FMIPSB,
- 0,
- &mmips2be,
- sizeof(struct mips4kexec),
- beswal,
- mips4kboot },
- { K_MAGIC, /* Sparc k.out */
- "sparc plan 9 executable",
- "sparc plan 9 dlm",
- FSPARC,
- 1,
- &msparc,
- sizeof(Exec),
- beswal,
- adotout },
- { 0x01030107, /* Sparc boot image */
- "sparc plan 9 boot image",
- nil,
- FSPARCB,
- 0,
- &msparc,
- sizeof(struct sparcexec),
- beswal,
- sparcboot },
- { U_MAGIC, /* Sparc64 u.out */
- "sparc64 plan 9 executable",
- "sparc64 plan 9 dlm",
- FSPARC64,
- 1,
- &msparc64,
- sizeof(Exec),
- beswal,
- adotout },
- { A_MAGIC, /* 68020 2.out & boot image */
- "68020 plan 9 executable",
- "68020 plan 9 dlm",
- F68020,
- 1,
- &m68020,
- sizeof(Exec),
- beswal,
- common },
- { 0xFEEDFACE, /* Next boot image */
- "next plan 9 boot image",
- nil,
- FNEXTB,
- 0,
- &m68020,
- sizeof(struct nextexec),
- beswal,
- nextboot },
- { I_MAGIC, /* I386 8.out & boot image */
- "386 plan 9 executable",
- "386 plan 9 dlm",
- FI386,
- 1,
- &mi386,
- sizeof(Exec),
- beswal,
- common },
- { S_MAGIC, /* amd64 6.out & boot image */
- "amd64 plan 9 executable",
- "amd64 plan 9 dlm",
- FAMD64,
- 1,
- &mamd64,
- sizeof(Exec)+8,
- nil,
- commonllp64 },
- { Q_MAGIC, /* PowerPC q.out & boot image */
- "power plan 9 executable",
- "power plan 9 dlm",
- FPOWER,
- 1,
- &mpower,
- sizeof(Exec),
- beswal,
- common },
- { T_MAGIC, /* power64 9.out & boot image */
- "power64 plan 9 executable",
- "power64 plan 9 dlm",
- FPOWER64,
- 1,
- &mpower64,
- sizeof(Exec)+8,
- nil,
- commonllp64 },
- { ELF_MAG, /* any elf32 or elf64 */
- "elf executable",
- nil,
- FNONE,
- 0,
- &mi386,
- sizeof(Ehdr64),
- nil,
- elfdotout },
- { MACH64_MAG, /* 64-bit MACH (apple mac) */
- "mach executable",
- nil,
- FAMD64,
- 0,
- &mamd64,
- sizeof(Machhdr),
- nil,
- machdotout },
- { MACH32_MAG, /* 32-bit MACH (apple mac) */
- "mach executable",
- nil,
- FI386,
- 0,
- &mi386,
- sizeof(Machhdr),
- nil,
- machdotout },
- { E_MAGIC, /* Arm 5.out and boot image */
- "arm plan 9 executable",
- "arm plan 9 dlm",
- FARM,
- 1,
- &marm,
- sizeof(Exec),
- beswal,
- common },
- { (143<<16)|0413, /* (Free|Net)BSD Arm */
- "arm *bsd executable",
- nil,
- FARM,
- 0,
- &marm,
- sizeof(Exec),
- leswal,
- armdotout },
- { L_MAGIC, /* alpha 7.out */
- "alpha plan 9 executable",
- "alpha plan 9 dlm",
- FALPHA,
- 1,
- &malpha,
- sizeof(Exec),
- beswal,
- common },
- { 0x0700e0c3, /* alpha boot image */
- "alpha plan 9 boot image",
- nil,
- FALPHA,
- 0,
- &malpha,
- sizeof(Exec),
- beswal,
- common },
- { 0x4d5a9000, /* see dosstub[] in pe.c */
- "windows PE executable",
- nil,
- FWINPE,
- 0,
- &mi386,
- sizeof(Exec), /* TODO */
- nil,
- pedotout },
- { 0 },
-};
-
-Mach *mach = &mi386; /* Global current machine table */
-
-static ExecTable*
-couldbe4k(ExecTable *mp)
-{
- Dir *d;
- ExecTable *f;
-
- if((d=dirstat("/proc/1/regs")) == nil)
- return mp;
- if(d->length < 32*8){ /* R3000 */
- free(d);
- return mp;
- }
- free(d);
- for (f = exectab; f->magic; f++)
- if(f->magic == M_MAGIC) {
- f->name = "mips plan 9 executable on mips2 kernel";
- return f;
- }
- return mp;
-}
-
-int
-crackhdr(int fd, Fhdr *fp)
-{
- ExecTable *mp;
- ExecHdr d;
- int nb, ret;
- uint32 magic;
-
- fp->type = FNONE;
- nb = read(fd, (char *)&d.e, sizeof(d.e));
- if (nb <= 0)
- return 0;
-
- ret = 0;
- magic = beswal(d.e.exechdr.magic); /* big-endian */
- for (mp = exectab; mp->magic; mp++) {
- if (nb < mp->hsize)
- continue;
-
- /*
- * The magic number has morphed into something
- * with fields (the straw was DYN_MAGIC) so now
- * a flag is needed in Fhdr to distinguish _MAGIC()
- * magic numbers from foreign magic numbers.
- *
- * This code is creaking a bit and if it has to
- * be modified/extended much more it's probably
- * time to step back and redo it all.
- */
- if(mp->_magic){
- if(mp->magic != (magic & ~DYN_MAGIC))
- continue;
-
- if(mp->magic == V_MAGIC)
- mp = couldbe4k(mp);
-
- if ((magic & DYN_MAGIC) && mp->dlmname != nil)
- fp->name = mp->dlmname;
- else
- fp->name = mp->name;
- }
- else{
- if(mp->magic != magic)
- continue;
- fp->name = mp->name;
- }
- fp->type = mp->type;
- fp->hdrsz = mp->hsize; /* will be zero on bootables */
- fp->_magic = mp->_magic;
- fp->magic = magic;
-
- mach = mp->mach;
- if(mp->swal != nil)
- hswal(&d, sizeof(d.e)/sizeof(uint32), mp->swal);
- ret = mp->hparse(fd, fp, &d);
- seek(fd, mp->hsize, 0); /* seek to end of header */
- break;
- }
- if(mp->magic == 0)
- werrstr("unknown header type");
- return ret;
-}
-
-/*
- * Convert header to canonical form
- */
-static void
-hswal(void *v, int n, uint32 (*swap)(uint32))
-{
- uint32 *ulp;
-
- for(ulp = v; n--; ulp++)
- *ulp = (*swap)(*ulp);
-}
-
-/*
- * Crack a normal a.out-type header
- */
-static int
-adotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
- int32 pgsize;
-
- USED(fd);
- pgsize = mach->pgsize;
- settext(fp, hp->e.exechdr.entry, pgsize+sizeof(Exec),
- hp->e.exechdr.text, sizeof(Exec));
- setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize),
- hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss);
- setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
- return 1;
-}
-
-static void
-commonboot(Fhdr *fp)
-{
- if (!(fp->entry & mach->ktmask))
- return;
-
- switch(fp->type) { /* boot image */
- case F68020:
- fp->type = F68020B;
- fp->name = "68020 plan 9 boot image";
- break;
- case FI386:
- fp->type = FI386B;
- fp->txtaddr = (u32int)fp->entry;
- fp->name = "386 plan 9 boot image";
- fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
- break;
- case FARM:
- fp->type = FARMB;
- fp->txtaddr = (u32int)fp->entry;
- fp->name = "ARM plan 9 boot image";
- fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
- return;
- case FALPHA:
- fp->type = FALPHAB;
- fp->txtaddr = (u32int)fp->entry;
- fp->name = "alpha plan 9 boot image";
- fp->dataddr = fp->txtaddr+fp->txtsz;
- break;
- case FPOWER:
- fp->type = FPOWERB;
- fp->txtaddr = (u32int)fp->entry;
- fp->name = "power plan 9 boot image";
- fp->dataddr = fp->txtaddr+fp->txtsz;
- break;
- case FAMD64:
- fp->type = FAMD64B;
- fp->txtaddr = fp->entry;
- fp->name = "amd64 plan 9 boot image";
- fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
- break;
- default:
- return;
- }
- fp->hdrsz = 0; /* header stripped */
-}
-
-/*
- * _MAGIC() style headers and
- * alpha plan9-style bootable images for axp "headerless" boot
- *
- */
-static int
-common(int fd, Fhdr *fp, ExecHdr *hp)
-{
- adotout(fd, fp, hp);
- if(hp->e.exechdr.magic & DYN_MAGIC) {
- fp->txtaddr = 0;
- fp->dataddr = fp->txtsz;
- return 1;
- }
- commonboot(fp);
- return 1;
-}
-
-static int
-commonllp64(int unused, Fhdr *fp, ExecHdr *hp)
-{
- int32 pgsize;
- uvlong entry;
-
- USED(unused);
-
- hswal(&hp->e, sizeof(Exec)/sizeof(int32), beswal);
- if(!(hp->e.exechdr.magic & HDR_MAGIC))
- return 0;
-
- /*
- * There can be more magic here if the
- * header ever needs more expansion.
- * For now just catch use of any of the
- * unused bits.
- */
- if((hp->e.exechdr.magic & ~DYN_MAGIC)>>16)
- return 0;
- union {
- char *p;
- uvlong *v;
- } u;
- u.p = (char*)&hp->e.exechdr;
- entry = beswav(*u.v);
-
- pgsize = mach->pgsize;
- settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz);
- setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
- hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss);
- setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
-
- if(hp->e.exechdr.magic & DYN_MAGIC) {
- fp->txtaddr = 0;
- fp->dataddr = fp->txtsz;
- return 1;
- }
- commonboot(fp);
- return 1;
-}
-
-/*
- * mips bootable image.
- */
-static int
-mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
- USED(fd);
- USED(fp);
- USED(hp);
-
-abort();
-#ifdef unused
- USED(fd);
- fp->type = FMIPSB;
- switch(hp->e.exechdr.amagic) {
- default:
- case 0407: /* some kind of mips */
- settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
- hp->e.tsize, sizeof(struct mipsexec)+4);
- setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
- fp->txtoff+hp->e.tsize, hp->e.bsize);
- break;
- case 0413: /* some kind of mips */
- settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start,
- hp->e.tsize, 0);
- setdata(fp, (u32int)hp->e.data_start, hp->e.dsize,
- hp->e.tsize, hp->e.bsize);
- break;
- }
- setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr);
- fp->hdrsz = 0; /* header stripped */
-#endif
- return 1;
-}
-
-/*
- * mips4k bootable image.
- */
-static int
-mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
- USED(fd);
- USED(fp);
- USED(hp);
-
-abort();
-#ifdef unused
- USED(fd);
- fp->type = FMIPSB;
- switch(hp->e.h.amagic) {
- default:
- case 0407: /* some kind of mips */
- settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
- hp->e.h.tsize, sizeof(struct mips4kexec));
- setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
- fp->txtoff+hp->e.h.tsize, hp->e.h.bsize);
- break;
- case 0413: /* some kind of mips */
- settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start,
- hp->e.h.tsize, 0);
- setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize,
- hp->e.h.tsize, hp->e.h.bsize);
- break;
- }
- setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr);
- fp->hdrsz = 0; /* header stripped */
-#endif
- return 1;
-}
-
-/*
- * sparc bootable image
- */
-static int
-sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
- USED(fd);
- USED(fp);
- USED(hp);
-
-abort();
-#ifdef unused
- USED(fd);
- fp->type = FSPARCB;
- settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext,
- sizeof(struct sparcexec));
- setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata,
- fp->txtoff+hp->e.stext, hp->e.sbss);
- setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata);
- fp->hdrsz = 0; /* header stripped */
-#endif
- return 1;
-}
-
-/*
- * next bootable image
- */
-static int
-nextboot(int fd, Fhdr *fp, ExecHdr *hp)
-{
- USED(fd);
- USED(fp);
- USED(hp);
-
-abort();
-#ifdef unused
- USED(fd);
- fp->type = FNEXTB;
- settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr,
- hp->e.texts.size, hp->e.texts.offset);
- setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size,
- hp->e.datas.offset, hp->e.bsss.size);
- setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff,
- hp->e.symc.symoff);
- fp->hdrsz = 0; /* header stripped */
-#endif
- return 1;
-}
-
-/*
- * Elf32 and Elf64 binaries.
- */
-static int
-elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
- uvlong (*swav)(uvlong);
- uint32 (*swal)(uint32);
- ushort (*swab)(ushort);
- Ehdr64 *ep;
- Phdr64 *ph, *pph;
- Shdr64 *sh;
- int i, it, id, is, phsz, shsz;
-
- /* bitswap the header according to the DATA format */
- ep = &hp->e.elfhdr64;
- if(ep->ident[CLASS] != ELFCLASS64) {
- werrstr("bad ELF class - not 32 bit or 64 bit");
- return 0;
- }
- if(ep->ident[DATA] == ELFDATA2LSB) {
- swab = leswab;
- swal = leswal;
- swav = leswav;
- } else if(ep->ident[DATA] == ELFDATA2MSB) {
- swab = beswab;
- swal = beswal;
- swav = beswav;
- } else {
- werrstr("bad ELF encoding - not big or little endian");
- return 0;
- }
-
- ep->type = swab(ep->type);
- ep->machine = swab(ep->machine);
- ep->version = swal(ep->version);
- ep->elfentry = swal(ep->elfentry);
- ep->phoff = swav(ep->phoff);
- ep->shoff = swav(ep->shoff);
- ep->flags = swav(ep->flags);
- ep->ehsize = swab(ep->ehsize);
- ep->phentsize = swab(ep->phentsize);
- ep->phnum = swab(ep->phnum);
- ep->shentsize = swab(ep->shentsize);
- ep->shnum = swab(ep->shnum);
- ep->shstrndx = swab(ep->shstrndx);
- if(ep->type != EXEC || ep->version != CURRENT)
- return 0;
-
- /* we could definitely support a lot more machines here */
- fp->magic = ELF_MAG;
- fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
- switch(ep->machine) {
- case AMD64:
- mach = &mamd64;
- fp->type = FAMD64;
- break;
- default:
- return 0;
- }
-
- if(ep->phentsize != sizeof(Phdr64)) {
- werrstr("bad ELF header size");
- return 0;
- }
- phsz = sizeof(Phdr64)*ep->phnum;
- ph = malloc(phsz);
- if(!ph)
- return 0;
- seek(fd, ep->phoff, 0);
- if(read(fd, ph, phsz) < 0) {
- free(ph);
- return 0;
- }
- hswal(ph, phsz/sizeof(uint32), swal);
-
- shsz = sizeof(Shdr64)*ep->shnum;
- sh = malloc(shsz);
- if(sh) {
- seek(fd, ep->shoff, 0);
- if(read(fd, sh, shsz) < 0) {
- free(sh);
- sh = 0;
- } else
- hswal(sh, shsz/sizeof(uint32), swal);
- }
-
- /* find text, data and symbols and install them */
- it = id = is = -1;
- for(i = 0; i < ep->phnum; i++) {
- if(ph[i].type == LOAD
- && (ph[i].flags & (R|X)) == (R|X) && it == -1)
- it = i;
- else if(ph[i].type == LOAD
- && (ph[i].flags & (R|W)) == (R|W) && id == -1)
- id = i;
- else if(ph[i].type == NOPTYPE && is == -1)
- is = i;
- }
- if(it == -1 || id == -1) {
- /*
- * The SPARC64 boot image is something of an ELF hack.
- * Text+Data+BSS are represented by ph[0]. Symbols
- * are represented by ph[1]:
- *
- * filesz, memsz, vaddr, paddr, off
- * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
- * ph[1] : symsz, lcsz, 0, 0, symoff
- */
- if(ep->machine == SPARC64 && ep->phnum == 2) {
- uint32 txtaddr, txtsz, dataddr, bsssz;
-
- txtaddr = ph[0].vaddr | 0x80000000;
- txtsz = ph[0].filesz - ph[0].paddr;
- dataddr = txtaddr + txtsz;
- bsssz = ph[0].memsz - ph[0].filesz;
- settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
- setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
- setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz);
- free(ph);
- return 1;
- }
-
- werrstr("No TEXT or DATA sections");
- free(ph);
- free(sh);
- return 0;
- }
-
- settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
- pph = ph + id;
- setdata(fp, pph->vaddr, pph->filesz, pph->offset, pph->memsz - pph->filesz);
- if(is != -1)
- setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz);
- else if(sh != 0){
- char *buf;
- uvlong symsize = 0;
- uvlong symoff = 0;
- uvlong pclnsz = 0;
- uvlong pclnoff = 0;
-
- /* load shstrtab names */
- buf = malloc(sh[ep->shstrndx].size);
- if (buf == 0)
- goto done;
- memset(buf, 0, sh[ep->shstrndx].size);
- seek(fd, sh[ep->shstrndx].offset, 0);
- i = read(fd, buf, sh[ep->shstrndx].size);
- USED(i); // shut up ubuntu gcc
-
- for(i = 0; i < ep->shnum; i++) {
- if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) {
- symsize = sh[i].size;
- symoff = sh[i].offset;
- }
- if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) {
- pclnsz = sh[i].size;
- pclnoff = sh[i].offset;
- }
- }
- setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsz);
- free(buf);
- }
-done:
- free(ph);
- free(sh);
- return 1;
-}
-
-static int
-elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
-
- uint32 (*swal)(uint32);
- ushort (*swab)(ushort);
- Ehdr32 *ep;
- Phdr32 *ph;
- int i, it, id, is, phsz, shsz;
- Shdr32 *sh;
-
- /* bitswap the header according to the DATA format */
- ep = &hp->e.elfhdr32;
- if(ep->ident[CLASS] != ELFCLASS32) {
- return elf64dotout(fd, fp, hp);
- }
- if(ep->ident[DATA] == ELFDATA2LSB) {
- swab = leswab;
- swal = leswal;
- } else if(ep->ident[DATA] == ELFDATA2MSB) {
- swab = beswab;
- swal = beswal;
- } else {
- werrstr("bad ELF encoding - not big or little endian");
- return 0;
- }
-
- ep->type = swab(ep->type);
- ep->machine = swab(ep->machine);
- ep->version = swal(ep->version);
- ep->elfentry = swal(ep->elfentry);
- ep->phoff = swal(ep->phoff);
- ep->shoff = swal(ep->shoff);
- ep->flags = swal(ep->flags);
- ep->ehsize = swab(ep->ehsize);
- ep->phentsize = swab(ep->phentsize);
- ep->phnum = swab(ep->phnum);
- ep->shentsize = swab(ep->shentsize);
- ep->shnum = swab(ep->shnum);
- ep->shstrndx = swab(ep->shstrndx);
- if(ep->type != EXEC || ep->version != CURRENT)
- return 0;
-
- /* we could definitely support a lot more machines here */
- fp->magic = ELF_MAG;
- fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
- switch(ep->machine) {
- case I386:
- mach = &mi386;
- fp->type = FI386;
- break;
- case MIPS:
- mach = &mmips;
- fp->type = FMIPS;
- break;
- case SPARC64:
- mach = &msparc64;
- fp->type = FSPARC64;
- break;
- case POWER:
- mach = &mpower;
- fp->type = FPOWER;
- break;
- case ARM:
- mach = &marm;
- fp->type = FARM;
- break;
- default:
- return 0;
- }
-
- if(ep->phentsize != sizeof(Phdr32)) {
- werrstr("bad ELF header size");
- return 0;
- }
- phsz = sizeof(Phdr32)*ep->phnum;
- ph = malloc(phsz);
- if(!ph)
- return 0;
- seek(fd, ep->phoff, 0);
- if(read(fd, ph, phsz) < 0) {
- free(ph);
- return 0;
- }
- hswal(ph, phsz/sizeof(uint32), swal);
-
- shsz = sizeof(Shdr32)*ep->shnum;
- sh = malloc(shsz);
- if(sh) {
- seek(fd, ep->shoff, 0);
- if(read(fd, sh, shsz) < 0) {
- free(sh);
- sh = 0;
- } else
- hswal(sh, shsz/sizeof(uint32), swal);
- }
-
- /* find text, data and symbols and install them */
- it = id = is = -1;
- for(i = 0; i < ep->phnum; i++) {
- if(ph[i].type == LOAD
- && (ph[i].flags & (R|X)) == (R|X) && it == -1)
- it = i;
- else if(ph[i].type == LOAD
- && (ph[i].flags & (R|W)) == (R|W) && id == -1)
- id = i;
- else if(ph[i].type == NOPTYPE && is == -1)
- is = i;
- }
- if(it == -1 || id == -1) {
- /*
- * The SPARC64 boot image is something of an ELF hack.
- * Text+Data+BSS are represented by ph[0]. Symbols
- * are represented by ph[1]:
- *
- * filesz, memsz, vaddr, paddr, off
- * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
- * ph[1] : symsz, lcsz, 0, 0, symoff
- */
- if(ep->machine == SPARC64 && ep->phnum == 2) {
- uint32 txtaddr, txtsz, dataddr, bsssz;
-
- txtaddr = ph[0].vaddr | 0x80000000;
- txtsz = ph[0].filesz - ph[0].paddr;
- dataddr = txtaddr + txtsz;
- bsssz = ph[0].memsz - ph[0].filesz;
- settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
- setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
- setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz);
- free(ph);
- return 1;
- }
-
- werrstr("No TEXT or DATA sections");
- free(sh);
- free(ph);
- return 0;
- }
-
- settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
- setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
- if(is != -1)
- setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz);
- else if(sh != 0){
- char *buf;
- uvlong symsize = 0;
- uvlong symoff = 0;
- uvlong pclnsize = 0;
- uvlong pclnoff = 0;
-
- /* load shstrtab names */
- buf = malloc(sh[ep->shstrndx].size);
- if (buf == 0)
- goto done;
- memset(buf, 0, sh[ep->shstrndx].size);
- seek(fd, sh[ep->shstrndx].offset, 0);
- i = read(fd, buf, sh[ep->shstrndx].size);
- USED(i); // shut up ubuntu gcc
-
- for(i = 0; i < ep->shnum; i++) {
- if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) {
- symsize = sh[i].size;
- symoff = sh[i].offset;
- }
- if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) {
- pclnsize = sh[i].size;
- pclnoff = sh[i].offset;
- }
- }
- setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
- free(buf);
- }
-done:
- free(sh);
- free(ph);
- return 1;
-}
-
-static int
-machdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
- uvlong (*swav)(uvlong);
- uint32 (*swal)(uint32);
- Machhdr *mp;
- MachCmd **cmd;
- MachSymSeg *symtab;
- MachSymSeg *pclntab;
- MachSeg64 *seg;
- MachSect64 *sect;
- MachSeg32 *seg32;
- MachSect32 *sect32;
- uvlong textsize, datasize, bsssize;
- uchar *cmdbuf;
- uchar *cmdp;
- int i, j, hdrsize;
- uint32 textva, textoff, datava, dataoff, symoff, symsize, pclnoff, pclnsize;
-
- mp = &hp->e.machhdr;
- if (leswal(mp->filetype) != MACH_EXECUTABLE_TYPE) {
- werrstr("bad MACH executable type %#ux", leswal(mp->filetype));
- return 0;
- }
-
- swal = leswal;
- swav = leswav;
-
- mp->magic = swal(mp->magic);
- mp->cputype = swal(mp->cputype);
- mp->cpusubtype = swal(mp->cpusubtype);
- mp->filetype = swal(mp->filetype);
- mp->ncmds = swal(mp->ncmds);
- mp->sizeofcmds = swal(mp->sizeofcmds);
- mp->flags = swal(mp->flags);
- mp->reserved = swal(mp->reserved);
-
- switch(mp->magic) {
- case 0xFEEDFACE: // 32-bit mach
- if (mp->cputype != MACH_CPU_TYPE_X86) {
- werrstr("bad MACH cpu type - not 386");
- return 0;
- }
- if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86) {
- werrstr("bad MACH cpu subtype - not 386");
- return 0;
- }
- if (mp->filetype != MACH_EXECUTABLE_TYPE) {
- werrstr("bad MACH executable type");
- return 0;
- }
- mach = &mi386;
- fp->type = FI386;
- hdrsize = 28;
- break;
-
- case 0xFEEDFACF: // 64-bit mach
- if (mp->cputype != MACH_CPU_TYPE_X86_64) {
- werrstr("bad MACH cpu type - not amd64");
- return 0;
- }
-
- if (mp->cpusubtype != MACH_CPU_SUBTYPE_X86 && mp->cpusubtype != MACH_CPU_SUBTYPE_X86_64) {
- werrstr("bad MACH cpu subtype - not amd64");
- return 0;
- }
- mach = &mamd64;
- fp->type = FAMD64;
- hdrsize = 32;
- break;
-
- default:
- werrstr("not mach %#ux", mp->magic);
- return 0;
- }
-
- cmdbuf = malloc(mp->sizeofcmds);
- if(!cmdbuf) {
- werrstr("out of memory");
- return 0;
- }
- seek(fd, hdrsize, 0);
- if(read(fd, cmdbuf, mp->sizeofcmds) != mp->sizeofcmds) {
- free(cmdbuf);
- return 0;
- }
- cmd = malloc(mp->ncmds * sizeof(MachCmd*));
- if(!cmd) {
- free(cmdbuf);
- werrstr("out of memory");
- return 0;
- }
- cmdp = cmdbuf;
- textva = 0;
- textoff = 0;
- dataoff = 0;
- datava = 0;
- symtab = 0;
- pclntab = 0;
- textsize = 0;
- datasize = 0;
- bsssize = 0;
- symoff = 0;
- symsize = 0;
- pclnoff = 0;
- pclnsize = 0;
- for (i = 0; i < mp->ncmds; i++) {
- MachCmd *c;
-
- cmd[i] = (MachCmd*)cmdp;
- c = cmd[i];
- c->type = swal(c->type);
- c->size = swal(c->size);
- switch(c->type) {
- case MACH_SEGMENT_32:
- if(mp->magic != 0xFEEDFACE) {
- werrstr("segment 32 in mach 64");
- goto bad;
- }
- seg32 = (MachSeg32*)c;
- seg32->vmaddr = swav(seg32->vmaddr);
- seg32->vmsize = swav(seg32->vmsize);
- seg32->fileoff = swav(seg32->fileoff);
- seg32->filesize = swav(seg32->filesize);
- seg32->maxprot = swal(seg32->maxprot);
- seg32->initprot = swal(seg32->initprot);
- seg32->nsects = swal(seg32->nsects);
- seg32->flags = swal(seg32->flags);
- if (strcmp(seg32->segname, "__TEXT") == 0) {
- textva = seg32->vmaddr;
- textoff = seg32->fileoff;
- textsize = seg32->vmsize;
- sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
- for(j = 0; j < seg32->nsects; j++, sect32++) {
- if (strcmp(sect32->sectname, "__gosymtab") == 0) {
- symoff = swal(sect32->offset);
- symsize = swal(sect32->size);
- }
- if (strcmp(sect32->sectname, "__gopclntab") == 0) {
- pclnoff = swal(sect32->offset);
- pclnsize = swal(sect32->size);
- }
- }
- }
- if (strcmp(seg32->segname, "__DATA") == 0) {
- datava = seg32->vmaddr;
- dataoff = seg32->fileoff;
- datasize = seg32->filesize;
- bsssize = seg32->vmsize - seg32->filesize;
- }
- break;
-
- case MACH_SEGMENT_64:
- if(mp->magic != 0xFEEDFACF) {
- werrstr("segment 32 in mach 64");
- goto bad;
- }
- seg = (MachSeg64*)c;
- seg->vmaddr = swav(seg->vmaddr);
- seg->vmsize = swav(seg->vmsize);
- seg->fileoff = swav(seg->fileoff);
- seg->filesize = swav(seg->filesize);
- seg->maxprot = swal(seg->maxprot);
- seg->initprot = swal(seg->initprot);
- seg->nsects = swal(seg->nsects);
- seg->flags = swal(seg->flags);
- if (strcmp(seg->segname, "__TEXT") == 0) {
- textva = seg->vmaddr;
- textoff = seg->fileoff;
- textsize = seg->vmsize;
- sect = (MachSect64*)(cmdp + sizeof(MachSeg64));
- for(j = 0; j < seg->nsects; j++, sect++) {
- if (strcmp(sect->sectname, "__gosymtab") == 0) {
- symoff = swal(sect->offset);
- symsize = swal(sect->size);
- }
- if (strcmp(sect->sectname, "__gopclntab") == 0) {
- pclnoff = swal(sect->offset);
- pclnsize = swal(sect->size);
- }
- }
- }
- if (strcmp(seg->segname, "__DATA") == 0) {
- datava = seg->vmaddr;
- dataoff = seg->fileoff;
- datasize = seg->filesize;
- bsssize = seg->vmsize - seg->filesize;
- }
- break;
- case MACH_UNIXTHREAD:
- break;
- case MACH_SYMSEG:
- if (symtab == 0) {
- symtab = (MachSymSeg*)c;
- symoff = swal(symtab->fileoff);
- symsize = swal(symtab->filesize);
- } else if (pclntab == 0) {
- pclntab = (MachSymSeg*)c;
- pclnoff = swal(pclntab->fileoff);
- pclnsize = swal(pclntab->filesize);
- }
- break;
- }
- cmdp += c->size;
- }
- if (textva == 0 || datava == 0) {
- free(cmd);
- free(cmdbuf);
- return 0;
- }
- /* compute entry by taking address after header - weird - BUG? */
- settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, textoff);
- setdata(fp, datava, datasize, dataoff, bsssize);
- if(symoff > 0)
- setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
- free(cmd);
- free(cmdbuf);
- return 1;
-bad:
- free(cmd);
- free(cmdbuf);
- return 0;
-}
-
-/*
- * (Free|Net)BSD ARM header.
- */
-static int
-armdotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
- uvlong kbase;
-
- USED(fd);
- settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeof(Exec));
- setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss);
- setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz);
-
- kbase = 0xF0000000;
- if ((fp->entry & kbase) == kbase) { /* Boot image */
- fp->txtaddr = kbase+sizeof(Exec);
- fp->name = "ARM *BSD boot image";
- fp->hdrsz = 0; /* header stripped */
- fp->dataddr = kbase+fp->txtsz;
- }
- return 1;
-}
-
-/*
- * Structures needed to parse PE image.
- */
-typedef struct {
- uint16 Machine;
- uint16 NumberOfSections;
- uint32 TimeDateStamp;
- uint32 PointerToSymbolTable;
- uint32 NumberOfSymbols;
- uint16 SizeOfOptionalHeader;
- uint16 Characteristics;
-} IMAGE_FILE_HEADER;
-
-typedef struct {
- uint8 Name[8];
- uint32 VirtualSize;
- uint32 VirtualAddress;
- uint32 SizeOfRawData;
- uint32 PointerToRawData;
- uint32 PointerToRelocations;
- uint32 PointerToLineNumbers;
- uint16 NumberOfRelocations;
- uint16 NumberOfLineNumbers;
- uint32 Characteristics;
-} IMAGE_SECTION_HEADER;
-
-typedef struct {
- uint32 VirtualAddress;
- uint32 Size;
-} IMAGE_DATA_DIRECTORY;
-
-typedef struct {
- uint16 Magic;
- uint8 MajorLinkerVersion;
- uint8 MinorLinkerVersion;
- uint32 SizeOfCode;
- uint32 SizeOfInitializedData;
- uint32 SizeOfUninitializedData;
- uint32 AddressOfEntryPoint;
- uint32 BaseOfCode;
- uint32 BaseOfData;
- uint32 ImageBase;
- uint32 SectionAlignment;
- uint32 FileAlignment;
- uint16 MajorOperatingSystemVersion;
- uint16 MinorOperatingSystemVersion;
- uint16 MajorImageVersion;
- uint16 MinorImageVersion;
- uint16 MajorSubsystemVersion;
- uint16 MinorSubsystemVersion;
- uint32 Win32VersionValue;
- uint32 SizeOfImage;
- uint32 SizeOfHeaders;
- uint32 CheckSum;
- uint16 Subsystem;
- uint16 DllCharacteristics;
- uint32 SizeOfStackReserve;
- uint32 SizeOfStackCommit;
- uint32 SizeOfHeapReserve;
- uint32 SizeOfHeapCommit;
- uint32 LoaderFlags;
- uint32 NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[16];
-} IMAGE_OPTIONAL_HEADER;
-
-typedef struct {
- uint16 Magic;
- uint8 MajorLinkerVersion;
- uint8 MinorLinkerVersion;
- uint32 SizeOfCode;
- uint32 SizeOfInitializedData;
- uint32 SizeOfUninitializedData;
- uint32 AddressOfEntryPoint;
- uint32 BaseOfCode;
- uint64 ImageBase;
- uint32 SectionAlignment;
- uint32 FileAlignment;
- uint16 MajorOperatingSystemVersion;
- uint16 MinorOperatingSystemVersion;
- uint16 MajorImageVersion;
- uint16 MinorImageVersion;
- uint16 MajorSubsystemVersion;
- uint16 MinorSubsystemVersion;
- uint32 Win32VersionValue;
- uint32 SizeOfImage;
- uint32 SizeOfHeaders;
- uint32 CheckSum;
- uint16 Subsystem;
- uint16 DllCharacteristics;
- uint64 SizeOfStackReserve;
- uint64 SizeOfStackCommit;
- uint64 SizeOfHeapReserve;
- uint64 SizeOfHeapCommit;
- uint32 LoaderFlags;
- uint32 NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[16];
-} PE64_IMAGE_OPTIONAL_HEADER;
-
-static int
-match8(void *buf, char *cmp)
-{
- return strncmp((char*)buf, cmp, 8) == 0;
-}
-
-/*
- * Read from Windows PE/COFF .exe file image.
- */
-static int
-pedotout(int fd, Fhdr *fp, ExecHdr *hp)
-{
- uint32 start, magic;
- uint32 symtab, esymtab, pclntab, epclntab;
- IMAGE_FILE_HEADER fh;
- IMAGE_SECTION_HEADER sh;
- IMAGE_OPTIONAL_HEADER oh;
- PE64_IMAGE_OPTIONAL_HEADER oh64;
- uint8 sym[18];
- uint32 *valp, ib, entry;
- int i, ohoffset;
-
- USED(hp);
- seek(fd, 0x3c, 0);
- if (readn(fd, &start, sizeof(start)) != sizeof(start)) {
- werrstr("crippled PE MSDOS header");
- return 0;
- }
- start = leswal(start);
-
- seek(fd, start, 0);
- if (readn(fd, &magic, sizeof(magic)) != sizeof(magic)) {
- werrstr("no PE magic number found");
- return 0;
- }
- if (beswal(magic) != 0x50450000) { /* "PE\0\0" */
- werrstr("incorrect PE magic number");
- return 0;
- }
-
- if (readn(fd, &fh, sizeof(fh)) != sizeof(fh)) {
- werrstr("crippled PE File Header");
- return 0;
- }
- if (fh.PointerToSymbolTable == 0) {
- werrstr("zero pointer to COFF symbol table");
- return 0;
- }
-
- ohoffset = seek(fd, 0, 1);
- if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) {
- werrstr("crippled PE Optional Header");
- return 0;
- }
-
- switch(oh.Magic) {
- case 0x10b: // PE32
- fp->type = FI386;
- ib = leswal(oh.ImageBase);
- entry = leswal(oh.AddressOfEntryPoint);
- break;
- case 0x20b: // PE32+
- fp->type = FAMD64;
- seek(fd, ohoffset, 0);
- if (readn(fd, &oh64, sizeof(oh64)) != sizeof(oh64)) {
- werrstr("crippled PE32+ Optional Header");
- return 0;
- }
- ib = leswal(oh64.ImageBase);
- entry = leswal(oh64.AddressOfEntryPoint);
- break;
- default:
- werrstr("invalid PE Optional Header magic number");
- return 0;
- }
-
- fp->txtaddr = 0;
- fp->dataddr = 0;
- for (i=0; i<leswab(fh.NumberOfSections); i++) {
- if (readn(fd, &sh, sizeof(sh)) != sizeof(sh)) {
- werrstr("could not read Section Header %d", i+1);
- return 0;
- }
- if (match8(sh.Name, ".text"))
- settext(fp, ib+entry, ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
- if (match8(sh.Name, ".data"))
- setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData));
- }
- if (fp->txtaddr==0 || fp->dataddr==0) {
- werrstr("no .text or .data");
- return 0;
- }
-
- seek(fd, leswal(fh.PointerToSymbolTable), 0);
- symtab = esymtab = pclntab = epclntab = 0;
- for (i=0; i<leswal(fh.NumberOfSymbols); i++) {
- if (readn(fd, sym, sizeof(sym)) != sizeof(sym)) {
- werrstr("crippled COFF symbol %d", i);
- return 0;
- }
- valp = (uint32 *)&sym[8];
- if (match8(sym, "symtab"))
- symtab = leswal(*valp);
- if (match8(sym, "esymtab"))
- esymtab = leswal(*valp);
- if (match8(sym, "pclntab"))
- pclntab = leswal(*valp);
- if (match8(sym, "epclntab"))
- epclntab = leswal(*valp);
- }
- if (symtab==0 || esymtab==0 || pclntab==0 || epclntab==0) {
- werrstr("no symtab or esymtab or pclntab or epclntab in COFF symbol table");
- return 0;
- }
- setsym(fp, symtab, esymtab-symtab, 0, 0, pclntab, epclntab-pclntab);
-
- return 1;
-}
-
-static void
-settext(Fhdr *fp, uvlong e, uvlong a, int32 s, vlong off)
-{
- fp->txtaddr = a;
- fp->entry = e;
- fp->txtsz = s;
- fp->txtoff = off;
-}
-
-static void
-setdata(Fhdr *fp, uvlong a, int32 s, vlong off, int32 bss)
-{
- fp->dataddr = a;
- fp->datsz = s;
- fp->datoff = off;
- fp->bsssz = bss;
-}
-
-static void
-setsym(Fhdr *fp, vlong symoff, int32 symsz, vlong sppcoff, int32 sppcsz, vlong lnpcoff, int32 lnpcsz)
-{
- fp->symoff = symoff;
- fp->symsz = symsz;
-
- if(sppcoff == 0)
- sppcoff = symoff+symsz;
- fp->sppcoff = symoff;
- fp->sppcsz = sppcsz;
-
- if(lnpcoff == 0)
- lnpcoff = sppcoff + sppcsz;
- fp->lnpcoff = lnpcoff;
- fp->lnpcsz = lnpcsz;
-}
-
-static uvlong
-_round(uvlong a, uint32 b)
-{
- uvlong w;
-
- w = (a/b)*b;
- if (a!=w)
- w += b;
- return(w);
-}