1bd389b36SDavid du Colombier #include <u.h> 2bd389b36SDavid du Colombier #include <libc.h> 3bd389b36SDavid du Colombier #include <bio.h> 4bd389b36SDavid du Colombier #include <bootexec.h> 5bd389b36SDavid du Colombier #include <mach.h> 67dd7cddfSDavid du Colombier #include "elf.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier /* 93e12c5d1SDavid du Colombier * All a.out header types. The dummy entry allows canonical 103e12c5d1SDavid du Colombier * processing of the union as a sequence of longs 113e12c5d1SDavid du Colombier */ 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier typedef struct { 143e12c5d1SDavid du Colombier union{ 154de34a7eSDavid du Colombier struct { 164de34a7eSDavid du Colombier Exec; /* a.out.h */ 174de34a7eSDavid du Colombier uvlong hdr[1]; 184de34a7eSDavid du Colombier }; 194de34a7eSDavid du Colombier Ehdr; /* elf.h */ 204de34a7eSDavid du Colombier struct mipsexec; /* bootexec.h */ 214de34a7eSDavid du Colombier struct mips4kexec; /* bootexec.h */ 224de34a7eSDavid du Colombier struct sparcexec; /* bootexec.h */ 234de34a7eSDavid du Colombier struct nextexec; /* bootexec.h */ 243e12c5d1SDavid du Colombier } e; 253e12c5d1SDavid du Colombier long dummy; /* padding to ensure extra long */ 263e12c5d1SDavid du Colombier } ExecHdr; 273e12c5d1SDavid du Colombier 287dd7cddfSDavid du Colombier static int nextboot(int, Fhdr*, ExecHdr*); 297dd7cddfSDavid du Colombier static int sparcboot(int, Fhdr*, ExecHdr*); 307dd7cddfSDavid du Colombier static int mipsboot(int, Fhdr*, ExecHdr*); 317dd7cddfSDavid du Colombier static int mips4kboot(int, Fhdr*, ExecHdr*); 327dd7cddfSDavid du Colombier static int common(int, Fhdr*, ExecHdr*); 334de34a7eSDavid du Colombier static int commonllp64(int, Fhdr*, ExecHdr*); 347dd7cddfSDavid du Colombier static int adotout(int, Fhdr*, ExecHdr*); 357dd7cddfSDavid du Colombier static int elfdotout(int, Fhdr*, ExecHdr*); 367dd7cddfSDavid du Colombier static int armdotout(int, Fhdr*, ExecHdr*); 374de34a7eSDavid du Colombier static void setsym(Fhdr*, long, long, long, vlong); 384de34a7eSDavid du Colombier static void setdata(Fhdr*, uvlong, long, vlong, long); 394de34a7eSDavid du Colombier static void settext(Fhdr*, uvlong, uvlong, long, vlong); 404de34a7eSDavid du Colombier static void hswal(void*, int, ulong(*)(ulong)); 414de34a7eSDavid du Colombier static uvlong _round(uvlong, ulong); 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier /* 443e12c5d1SDavid du Colombier * definition of per-executable file type structures 453e12c5d1SDavid du Colombier */ 463e12c5d1SDavid du Colombier 473e12c5d1SDavid du Colombier typedef struct Exectable{ 483e12c5d1SDavid du Colombier long magic; /* big-endian magic number of file */ 493e12c5d1SDavid du Colombier char *name; /* executable identifier */ 5012fd1c83SDavid du Colombier char *dlmname; /* dynamically loadable module identifier */ 51*2cca75a1SDavid du Colombier uchar type; /* Internal code */ 52*2cca75a1SDavid du Colombier uchar _magic; /* _MAGIC() magic */ 533e12c5d1SDavid du Colombier Mach *mach; /* Per-machine data */ 544de34a7eSDavid du Colombier long hsize; /* header size */ 554de34a7eSDavid du Colombier ulong (*swal)(ulong); /* beswal or leswal */ 567dd7cddfSDavid du Colombier int (*hparse)(int, Fhdr*, ExecHdr*); 573e12c5d1SDavid du Colombier } ExecTable; 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier extern Mach mmips; 607dd7cddfSDavid du Colombier extern Mach mmips2le; 617dd7cddfSDavid du Colombier extern Mach mmips2be; 623e12c5d1SDavid du Colombier extern Mach msparc; 63b0dcc5a8SDavid du Colombier extern Mach msparc64; 643e12c5d1SDavid du Colombier extern Mach m68020; 653e12c5d1SDavid du Colombier extern Mach mi386; 66b0dcc5a8SDavid du Colombier extern Mach mamd64; 677dd7cddfSDavid du Colombier extern Mach marm; 687dd7cddfSDavid du Colombier extern Mach mpower; 697dd7cddfSDavid du Colombier extern Mach malpha; 703e12c5d1SDavid du Colombier 713e12c5d1SDavid du Colombier ExecTable exectab[] = 723e12c5d1SDavid du Colombier { 733e12c5d1SDavid du Colombier { V_MAGIC, /* Mips v.out */ 743e12c5d1SDavid du Colombier "mips plan 9 executable", 7512fd1c83SDavid du Colombier "mips plan 9 dlm", 763e12c5d1SDavid du Colombier FMIPS, 77*2cca75a1SDavid du Colombier 1, 783e12c5d1SDavid du Colombier &mmips, 793e12c5d1SDavid du Colombier sizeof(Exec), 803e12c5d1SDavid du Colombier beswal, 813e12c5d1SDavid du Colombier adotout }, 827dd7cddfSDavid du Colombier { M_MAGIC, /* Mips 4.out */ 837dd7cddfSDavid du Colombier "mips 4k plan 9 executable BE", 8412fd1c83SDavid du Colombier "mips 4k plan 9 dlm BE", 857dd7cddfSDavid du Colombier FMIPS2BE, 86*2cca75a1SDavid du Colombier 1, 877dd7cddfSDavid du Colombier &mmips2be, 887dd7cddfSDavid du Colombier sizeof(Exec), 897dd7cddfSDavid du Colombier beswal, 907dd7cddfSDavid du Colombier adotout }, 917dd7cddfSDavid du Colombier { N_MAGIC, /* Mips 0.out */ 927dd7cddfSDavid du Colombier "mips 4k plan 9 executable LE", 9312fd1c83SDavid du Colombier "mips 4k plan 9 dlm LE", 947dd7cddfSDavid du Colombier FMIPS2LE, 95*2cca75a1SDavid du Colombier 1, 967dd7cddfSDavid du Colombier &mmips2le, 977dd7cddfSDavid du Colombier sizeof(Exec), 987dd7cddfSDavid du Colombier beswal, 997dd7cddfSDavid du Colombier adotout }, 1003e12c5d1SDavid du Colombier { 0x160<<16, /* Mips boot image */ 1013e12c5d1SDavid du Colombier "mips plan 9 boot image", 10212fd1c83SDavid du Colombier nil, 1033e12c5d1SDavid du Colombier FMIPSB, 104*2cca75a1SDavid du Colombier 0, 1053e12c5d1SDavid du Colombier &mmips, 1063e12c5d1SDavid du Colombier sizeof(struct mipsexec), 1073e12c5d1SDavid du Colombier beswal, 1083e12c5d1SDavid du Colombier mipsboot }, 109219b2ee8SDavid du Colombier { (0x160<<16)|3, /* Mips boot image */ 110219b2ee8SDavid du Colombier "mips 4k plan 9 boot image", 11112fd1c83SDavid du Colombier nil, 112219b2ee8SDavid du Colombier FMIPSB, 113*2cca75a1SDavid du Colombier 0, 11480ee5cbfSDavid du Colombier &mmips2be, 115219b2ee8SDavid du Colombier sizeof(struct mips4kexec), 1163e12c5d1SDavid du Colombier beswal, 117219b2ee8SDavid du Colombier mips4kboot }, 1183e12c5d1SDavid du Colombier { K_MAGIC, /* Sparc k.out */ 1193e12c5d1SDavid du Colombier "sparc plan 9 executable", 12012fd1c83SDavid du Colombier "sparc plan 9 dlm", 1213e12c5d1SDavid du Colombier FSPARC, 122*2cca75a1SDavid du Colombier 1, 1233e12c5d1SDavid du Colombier &msparc, 1243e12c5d1SDavid du Colombier sizeof(Exec), 1253e12c5d1SDavid du Colombier beswal, 1263e12c5d1SDavid du Colombier adotout }, 1273e12c5d1SDavid du Colombier { 0x01030107, /* Sparc boot image */ 1283e12c5d1SDavid du Colombier "sparc plan 9 boot image", 12912fd1c83SDavid du Colombier nil, 1303e12c5d1SDavid du Colombier FSPARCB, 131*2cca75a1SDavid du Colombier 0, 1323e12c5d1SDavid du Colombier &msparc, 1333e12c5d1SDavid du Colombier sizeof(struct sparcexec), 1343e12c5d1SDavid du Colombier beswal, 1353e12c5d1SDavid du Colombier sparcboot }, 136b0dcc5a8SDavid du Colombier { U_MAGIC, /* Sparc64 u.out */ 137b0dcc5a8SDavid du Colombier "sparc64 plan 9 executable", 138b0dcc5a8SDavid du Colombier "sparc64 plan 9 dlm", 139b0dcc5a8SDavid du Colombier FSPARC64, 140*2cca75a1SDavid du Colombier 1, 141b0dcc5a8SDavid du Colombier &msparc64, 142b0dcc5a8SDavid du Colombier sizeof(Exec), 143b0dcc5a8SDavid du Colombier beswal, 144b0dcc5a8SDavid du Colombier adotout }, 1453e12c5d1SDavid du Colombier { A_MAGIC, /* 68020 2.out & boot image */ 1463e12c5d1SDavid du Colombier "68020 plan 9 executable", 14712fd1c83SDavid du Colombier "68020 plan 9 dlm", 1483e12c5d1SDavid du Colombier F68020, 149*2cca75a1SDavid du Colombier 1, 1503e12c5d1SDavid du Colombier &m68020, 1513e12c5d1SDavid du Colombier sizeof(Exec), 1523e12c5d1SDavid du Colombier beswal, 1533e12c5d1SDavid du Colombier common }, 1543e12c5d1SDavid du Colombier { 0xFEEDFACE, /* Next boot image */ 1553e12c5d1SDavid du Colombier "next plan 9 boot image", 15612fd1c83SDavid du Colombier nil, 1573e12c5d1SDavid du Colombier FNEXTB, 158*2cca75a1SDavid du Colombier 0, 1593e12c5d1SDavid du Colombier &m68020, 1603e12c5d1SDavid du Colombier sizeof(struct nextexec), 1613e12c5d1SDavid du Colombier beswal, 1623e12c5d1SDavid du Colombier nextboot }, 1633e12c5d1SDavid du Colombier { I_MAGIC, /* I386 8.out & boot image */ 1643e12c5d1SDavid du Colombier "386 plan 9 executable", 16512fd1c83SDavid du Colombier "386 plan 9 dlm", 1663e12c5d1SDavid du Colombier FI386, 167*2cca75a1SDavid du Colombier 1, 1683e12c5d1SDavid du Colombier &mi386, 1693e12c5d1SDavid du Colombier sizeof(Exec), 1703e12c5d1SDavid du Colombier beswal, 1713e12c5d1SDavid du Colombier common }, 172b0dcc5a8SDavid du Colombier { S_MAGIC, /* amd64 6.out & boot image */ 173b0dcc5a8SDavid du Colombier "amd64 plan 9 executable", 174b0dcc5a8SDavid du Colombier "amd64 plan 9 dlm", 175b0dcc5a8SDavid du Colombier FAMD64, 176*2cca75a1SDavid du Colombier 1, 177b0dcc5a8SDavid du Colombier &mamd64, 1784de34a7eSDavid du Colombier sizeof(Exec)+8, 1794de34a7eSDavid du Colombier nil, 1804de34a7eSDavid du Colombier commonllp64 }, 1819a747e4fSDavid du Colombier { Q_MAGIC, /* PowerPC q.out & boot image */ 1827dd7cddfSDavid du Colombier "power plan 9 executable", 18312fd1c83SDavid du Colombier "power plan 9 dlm", 1847dd7cddfSDavid du Colombier FPOWER, 185*2cca75a1SDavid du Colombier 1, 1867dd7cddfSDavid du Colombier &mpower, 1877dd7cddfSDavid du Colombier sizeof(Exec), 1887dd7cddfSDavid du Colombier beswal, 1897dd7cddfSDavid du Colombier common }, 19070b8e010SDavid du Colombier { ELF_MAG, /* any elf32 */ 191b0dcc5a8SDavid du Colombier "elf executable", 19212fd1c83SDavid du Colombier nil, 19370b8e010SDavid du Colombier FNONE, 194*2cca75a1SDavid du Colombier 0, 19570b8e010SDavid du Colombier &mi386, 1967dd7cddfSDavid du Colombier sizeof(Ehdr), 1974de34a7eSDavid du Colombier nil, 1987dd7cddfSDavid du Colombier elfdotout }, 1997dd7cddfSDavid du Colombier { E_MAGIC, /* Arm 5.out */ 200b0dcc5a8SDavid du Colombier "arm plan 9 executable", 201b0dcc5a8SDavid du Colombier "arm plan 9 dlm", 2027dd7cddfSDavid du Colombier FARM, 203*2cca75a1SDavid du Colombier 1, 2047dd7cddfSDavid du Colombier &marm, 2057dd7cddfSDavid du Colombier sizeof(Exec), 2067dd7cddfSDavid du Colombier beswal, 2077dd7cddfSDavid du Colombier common }, 2087dd7cddfSDavid du Colombier { (143<<16)|0413, /* (Free|Net)BSD Arm */ 209b0dcc5a8SDavid du Colombier "arm *bsd executable", 21012fd1c83SDavid du Colombier nil, 2117dd7cddfSDavid du Colombier FARM, 212*2cca75a1SDavid du Colombier 0, 2137dd7cddfSDavid du Colombier &marm, 2147dd7cddfSDavid du Colombier sizeof(Exec), 2157dd7cddfSDavid du Colombier leswal, 2167dd7cddfSDavid du Colombier armdotout }, 2177dd7cddfSDavid du Colombier { L_MAGIC, /* alpha 7.out */ 2187dd7cddfSDavid du Colombier "alpha plan 9 executable", 21912fd1c83SDavid du Colombier "alpha plan 9 dlm", 2207dd7cddfSDavid du Colombier FALPHA, 221*2cca75a1SDavid du Colombier 1, 2227dd7cddfSDavid du Colombier &malpha, 2237dd7cddfSDavid du Colombier sizeof(Exec), 2247dd7cddfSDavid du Colombier beswal, 2257dd7cddfSDavid du Colombier common }, 2267dd7cddfSDavid du Colombier { 0x0700e0c3, /* alpha boot image */ 2277dd7cddfSDavid du Colombier "alpha plan 9 boot image", 22812fd1c83SDavid du Colombier nil, 229*2cca75a1SDavid du Colombier FALPHA, 230*2cca75a1SDavid du Colombier 0, 2317dd7cddfSDavid du Colombier &malpha, 2327dd7cddfSDavid du Colombier sizeof(Exec), 2337dd7cddfSDavid du Colombier beswal, 234*2cca75a1SDavid du Colombier common }, 2353e12c5d1SDavid du Colombier { 0 }, 2363e12c5d1SDavid du Colombier }; 2373e12c5d1SDavid du Colombier 2387dd7cddfSDavid du Colombier Mach *mach = &mi386; /* Global current machine table */ 2397dd7cddfSDavid du Colombier 2407dd7cddfSDavid du Colombier static ExecTable* 2417dd7cddfSDavid du Colombier couldbe4k(ExecTable *mp) 2427dd7cddfSDavid du Colombier { 2439a747e4fSDavid du Colombier Dir *d; 2447dd7cddfSDavid du Colombier ExecTable *f; 2457dd7cddfSDavid du Colombier 2469a747e4fSDavid du Colombier if((d=dirstat("/proc/1/regs")) == nil) 2477dd7cddfSDavid du Colombier return mp; 2489a747e4fSDavid du Colombier if(d->length < 32*8){ /* R3000 */ 2499a747e4fSDavid du Colombier free(d); 2507dd7cddfSDavid du Colombier return mp; 2519a747e4fSDavid du Colombier } 2529a747e4fSDavid du Colombier free(d); 2537dd7cddfSDavid du Colombier for (f = exectab; f->magic; f++) 2547dd7cddfSDavid du Colombier if(f->magic == M_MAGIC) { 2557dd7cddfSDavid du Colombier f->name = "mips plan 9 executable on mips2 kernel"; 2567dd7cddfSDavid du Colombier return f; 2577dd7cddfSDavid du Colombier } 2587dd7cddfSDavid du Colombier return mp; 2597dd7cddfSDavid du Colombier } 2607dd7cddfSDavid du Colombier 2613e12c5d1SDavid du Colombier int 2623e12c5d1SDavid du Colombier crackhdr(int fd, Fhdr *fp) 2633e12c5d1SDavid du Colombier { 2643e12c5d1SDavid du Colombier ExecTable *mp; 2653e12c5d1SDavid du Colombier ExecHdr d; 2664de34a7eSDavid du Colombier int nb, ret; 2674de34a7eSDavid du Colombier ulong magic; 2683e12c5d1SDavid du Colombier 2693e12c5d1SDavid du Colombier fp->type = FNONE; 2707dd7cddfSDavid du Colombier nb = read(fd, (char *)&d.e, sizeof(d.e)); 2717dd7cddfSDavid du Colombier if (nb <= 0) 2723e12c5d1SDavid du Colombier return 0; 2737dd7cddfSDavid du Colombier 2747dd7cddfSDavid du Colombier ret = 0; 275*2cca75a1SDavid du Colombier magic = beswal(d.e.magic); /* big-endian */ 2763e12c5d1SDavid du Colombier for (mp = exectab; mp->magic; mp++) { 27712fd1c83SDavid du Colombier if (nb < mp->hsize) 27812fd1c83SDavid du Colombier continue; 279*2cca75a1SDavid du Colombier 280*2cca75a1SDavid du Colombier /* 281*2cca75a1SDavid du Colombier * The magic number has morphed into something 282*2cca75a1SDavid du Colombier * with fields (the straw was DYN_MAGIC) so now 283*2cca75a1SDavid du Colombier * a flag is needed in Fhdr to distinguish _MAGIC() 284*2cca75a1SDavid du Colombier * magic numbers from foreign magic numbers. 285*2cca75a1SDavid du Colombier * 286*2cca75a1SDavid du Colombier * This code is creaking a bit and if it has to 287*2cca75a1SDavid du Colombier * be modified/extended much more it's probably 288*2cca75a1SDavid du Colombier * time to step back and redo it all. 289*2cca75a1SDavid du Colombier */ 290*2cca75a1SDavid du Colombier if(mp->_magic){ 291*2cca75a1SDavid du Colombier if(mp->magic != (magic & ~DYN_MAGIC)) 292*2cca75a1SDavid du Colombier continue; 293*2cca75a1SDavid du Colombier 2947dd7cddfSDavid du Colombier if(mp->magic == V_MAGIC) 2957dd7cddfSDavid du Colombier mp = couldbe4k(mp); 2967dd7cddfSDavid du Colombier 29712fd1c83SDavid du Colombier if ((magic & DYN_MAGIC) && mp->dlmname != nil) 29812fd1c83SDavid du Colombier fp->name = mp->dlmname; 29912fd1c83SDavid du Colombier else 3003e12c5d1SDavid du Colombier fp->name = mp->name; 301*2cca75a1SDavid du Colombier } 302*2cca75a1SDavid du Colombier else{ 303*2cca75a1SDavid du Colombier if(mp->magic != magic) 304*2cca75a1SDavid du Colombier continue; 305*2cca75a1SDavid du Colombier fp->name = mp->name; 306*2cca75a1SDavid du Colombier } 307*2cca75a1SDavid du Colombier fp->type = mp->type; 308*2cca75a1SDavid du Colombier fp->hdrsz = mp->hsize; /* will be zero on bootables */ 309*2cca75a1SDavid du Colombier fp->_magic = mp->_magic; 310*2cca75a1SDavid du Colombier fp->magic = magic; 311*2cca75a1SDavid du Colombier 3123e12c5d1SDavid du Colombier mach = mp->mach; 3134de34a7eSDavid du Colombier if(mp->swal != nil) 3144de34a7eSDavid du Colombier hswal(&d, sizeof(d.e)/sizeof(ulong), mp->swal); 3157dd7cddfSDavid du Colombier ret = mp->hparse(fd, fp, &d); 3163e12c5d1SDavid du Colombier seek(fd, mp->hsize, 0); /* seek to end of header */ 3177dd7cddfSDavid du Colombier break; 3183e12c5d1SDavid du Colombier } 3197dd7cddfSDavid du Colombier if(mp->magic == 0) 3207dd7cddfSDavid du Colombier werrstr("unknown header type"); 3217dd7cddfSDavid du Colombier return ret; 3223e12c5d1SDavid du Colombier } 3234de34a7eSDavid du Colombier 3243e12c5d1SDavid du Colombier /* 3253e12c5d1SDavid du Colombier * Convert header to canonical form 3263e12c5d1SDavid du Colombier */ 3273e12c5d1SDavid du Colombier static void 3284de34a7eSDavid du Colombier hswal(void *v, int n, ulong (*swap)(ulong)) 3293e12c5d1SDavid du Colombier { 3304de34a7eSDavid du Colombier ulong *ulp; 3314de34a7eSDavid du Colombier 3324de34a7eSDavid du Colombier for(ulp = v; n--; ulp++) 3334de34a7eSDavid du Colombier *ulp = (*swap)(*ulp); 3343e12c5d1SDavid du Colombier } 3354de34a7eSDavid du Colombier 33670b8e010SDavid du Colombier /* 3373e12c5d1SDavid du Colombier * Crack a normal a.out-type header 3383e12c5d1SDavid du Colombier */ 3397dd7cddfSDavid du Colombier static int 3407dd7cddfSDavid du Colombier adotout(int fd, Fhdr *fp, ExecHdr *hp) 3413e12c5d1SDavid du Colombier { 3427dd7cddfSDavid du Colombier long pgsize; 3433e12c5d1SDavid du Colombier 3447dd7cddfSDavid du Colombier USED(fd); 3457dd7cddfSDavid du Colombier pgsize = mach->pgsize; 346219b2ee8SDavid du Colombier settext(fp, hp->e.entry, pgsize+sizeof(Exec), 347219b2ee8SDavid du Colombier hp->e.text, sizeof(Exec)); 348219b2ee8SDavid du Colombier setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize), 349219b2ee8SDavid du Colombier hp->e.data, fp->txtsz+sizeof(Exec), hp->e.bss); 3503e12c5d1SDavid du Colombier setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz); 3517dd7cddfSDavid du Colombier return 1; 3523e12c5d1SDavid du Colombier } 3533e12c5d1SDavid du Colombier 3544de34a7eSDavid du Colombier static void 3554de34a7eSDavid du Colombier commonboot(Fhdr *fp) 3564de34a7eSDavid du Colombier { 357*2cca75a1SDavid du Colombier if (!(fp->entry & mach->ktmask)) 3584de34a7eSDavid du Colombier return; 3594de34a7eSDavid du Colombier 3604de34a7eSDavid du Colombier switch(fp->type) { /* boot image */ 3614de34a7eSDavid du Colombier case F68020: 3624de34a7eSDavid du Colombier fp->type = F68020B; 3634de34a7eSDavid du Colombier fp->name = "68020 plan 9 boot image"; 3644de34a7eSDavid du Colombier break; 3654de34a7eSDavid du Colombier case FI386: 3664de34a7eSDavid du Colombier fp->type = FI386B; 3674de34a7eSDavid du Colombier fp->txtaddr = (u32int)fp->entry; 3684de34a7eSDavid du Colombier fp->name = "386 plan 9 boot image"; 3694de34a7eSDavid du Colombier fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize); 3704de34a7eSDavid du Colombier break; 3714de34a7eSDavid du Colombier case FARM: 372*2cca75a1SDavid du Colombier fp->txtaddr = mach->kbase+0x8010; 3734de34a7eSDavid du Colombier fp->name = "ARM plan 9 boot image"; 3744de34a7eSDavid du Colombier fp->dataddr = fp->txtaddr+fp->txtsz; 3754de34a7eSDavid du Colombier return; 3764de34a7eSDavid du Colombier case FALPHA: 3774de34a7eSDavid du Colombier fp->type = FALPHAB; 3784de34a7eSDavid du Colombier fp->txtaddr = (u32int)fp->entry; 379*2cca75a1SDavid du Colombier fp->name = "alpha plan 9 boot image"; 3804de34a7eSDavid du Colombier fp->dataddr = fp->txtaddr+fp->txtsz; 3814de34a7eSDavid du Colombier break; 3824de34a7eSDavid du Colombier case FPOWER: 3834de34a7eSDavid du Colombier fp->type = FPOWERB; 3844de34a7eSDavid du Colombier fp->txtaddr = (u32int)fp->entry; 3854de34a7eSDavid du Colombier fp->name = "power plan 9 boot image"; 3864de34a7eSDavid du Colombier fp->dataddr = fp->txtaddr+fp->txtsz; 3874de34a7eSDavid du Colombier break; 3884de34a7eSDavid du Colombier case FAMD64: 3894de34a7eSDavid du Colombier fp->type = FAMD64B; 3904de34a7eSDavid du Colombier fp->txtaddr = fp->entry; 3914de34a7eSDavid du Colombier fp->name = "amd64 plan 9 boot image"; 3924de34a7eSDavid du Colombier fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize); 3934de34a7eSDavid du Colombier break; 3944de34a7eSDavid du Colombier default: 3954de34a7eSDavid du Colombier return; 3964de34a7eSDavid du Colombier } 3974de34a7eSDavid du Colombier fp->hdrsz = 0; /* header stripped */ 3984de34a7eSDavid du Colombier } 3994de34a7eSDavid du Colombier 4003e12c5d1SDavid du Colombier /* 401*2cca75a1SDavid du Colombier * _MAGIC() style headers and 4027dd7cddfSDavid du Colombier * alpha plan9-style bootable images for axp "headerless" boot 4033e12c5d1SDavid du Colombier * 4043e12c5d1SDavid du Colombier */ 4057dd7cddfSDavid du Colombier static int 4067dd7cddfSDavid du Colombier common(int fd, Fhdr *fp, ExecHdr *hp) 4073e12c5d1SDavid du Colombier { 4087dd7cddfSDavid du Colombier adotout(fd, fp, hp); 4099a747e4fSDavid du Colombier if(hp->e.magic & DYN_MAGIC) { 4109a747e4fSDavid du Colombier fp->txtaddr = 0; 4119a747e4fSDavid du Colombier fp->dataddr = fp->txtsz; 4129a747e4fSDavid du Colombier return 1; 4139a747e4fSDavid du Colombier } 4144de34a7eSDavid du Colombier commonboot(fp); 4157dd7cddfSDavid du Colombier return 1; 4163e12c5d1SDavid du Colombier } 4174de34a7eSDavid du Colombier 4184de34a7eSDavid du Colombier static int 4194de34a7eSDavid du Colombier commonllp64(int, Fhdr *fp, ExecHdr *hp) 4204de34a7eSDavid du Colombier { 4214de34a7eSDavid du Colombier long pgsize; 4224de34a7eSDavid du Colombier uvlong entry; 4234de34a7eSDavid du Colombier 4244de34a7eSDavid du Colombier hswal(&hp->e, sizeof(Exec)/sizeof(long), beswal); 4254de34a7eSDavid du Colombier if(!(hp->e.magic & HDR_MAGIC)) 4264de34a7eSDavid du Colombier return 0; 4274de34a7eSDavid du Colombier 4284de34a7eSDavid du Colombier /* 4294de34a7eSDavid du Colombier * There can be more magic here if the 4304de34a7eSDavid du Colombier * header ever needs more expansion. 4314de34a7eSDavid du Colombier * For now just catch use of any of the 4324de34a7eSDavid du Colombier * unused bits. 4334de34a7eSDavid du Colombier */ 4344de34a7eSDavid du Colombier if((hp->e.magic & ~DYN_MAGIC)>>16) 4354de34a7eSDavid du Colombier return 0; 4364de34a7eSDavid du Colombier entry = beswav(hp->e.hdr[0]); 4374de34a7eSDavid du Colombier 4384de34a7eSDavid du Colombier pgsize = mach->pgsize; 4394de34a7eSDavid du Colombier settext(fp, entry, pgsize+fp->hdrsz, hp->e.text, fp->hdrsz); 4404de34a7eSDavid du Colombier setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize), 4414de34a7eSDavid du Colombier hp->e.data, fp->txtsz+fp->hdrsz, hp->e.bss); 4424de34a7eSDavid du Colombier setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz); 4434de34a7eSDavid du Colombier 4444de34a7eSDavid du Colombier if(hp->e.magic & DYN_MAGIC) { 4454de34a7eSDavid du Colombier fp->txtaddr = 0; 4464de34a7eSDavid du Colombier fp->dataddr = fp->txtsz; 4474de34a7eSDavid du Colombier return 1; 4483e12c5d1SDavid du Colombier } 4494de34a7eSDavid du Colombier commonboot(fp); 4507dd7cddfSDavid du Colombier return 1; 4513e12c5d1SDavid du Colombier } 4523e12c5d1SDavid du Colombier 4533e12c5d1SDavid du Colombier /* 4543e12c5d1SDavid du Colombier * mips bootable image. 4553e12c5d1SDavid du Colombier */ 4567dd7cddfSDavid du Colombier static int 4577dd7cddfSDavid du Colombier mipsboot(int fd, Fhdr *fp, ExecHdr *hp) 4583e12c5d1SDavid du Colombier { 4597dd7cddfSDavid du Colombier USED(fd); 460*2cca75a1SDavid du Colombier fp->type = FMIPSB; 4613e12c5d1SDavid du Colombier switch(hp->e.amagic) { 4623e12c5d1SDavid du Colombier default: 4633e12c5d1SDavid du Colombier case 0407: /* some kind of mips */ 464*2cca75a1SDavid du Colombier settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start, 465*2cca75a1SDavid du Colombier hp->e.tsize, sizeof(struct mipsexec)+4); 466*2cca75a1SDavid du Colombier setdata(fp, (u32int)hp->e.data_start, hp->e.dsize, 4673e12c5d1SDavid du Colombier fp->txtoff+hp->e.tsize, hp->e.bsize); 4683e12c5d1SDavid du Colombier break; 4693e12c5d1SDavid du Colombier case 0413: /* some kind of mips */ 470*2cca75a1SDavid du Colombier settext(fp, (u32int)hp->e.mentry, (u32int)hp->e.text_start, 471*2cca75a1SDavid du Colombier hp->e.tsize, 0); 472*2cca75a1SDavid du Colombier setdata(fp, (u32int)hp->e.data_start, hp->e.dsize, 473*2cca75a1SDavid du Colombier hp->e.tsize, hp->e.bsize); 4743e12c5d1SDavid du Colombier break; 4753e12c5d1SDavid du Colombier } 4763e12c5d1SDavid du Colombier setsym(fp, hp->e.nsyms, 0, hp->e.pcsize, hp->e.symptr); 477219b2ee8SDavid du Colombier fp->hdrsz = 0; /* header stripped */ 4787dd7cddfSDavid du Colombier return 1; 4793e12c5d1SDavid du Colombier } 480219b2ee8SDavid du Colombier 4813e12c5d1SDavid du Colombier /* 482219b2ee8SDavid du Colombier * mips4k bootable image. 4833e12c5d1SDavid du Colombier */ 4847dd7cddfSDavid du Colombier static int 4857dd7cddfSDavid du Colombier mips4kboot(int fd, Fhdr *fp, ExecHdr *hp) 4863e12c5d1SDavid du Colombier { 4877dd7cddfSDavid du Colombier USED(fd); 488*2cca75a1SDavid du Colombier fp->type = FMIPSB; 489219b2ee8SDavid du Colombier switch(hp->e.h.amagic) { 490219b2ee8SDavid du Colombier default: 491219b2ee8SDavid du Colombier case 0407: /* some kind of mips */ 492*2cca75a1SDavid du Colombier settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start, 493*2cca75a1SDavid du Colombier hp->e.h.tsize, sizeof(struct mips4kexec)); 494*2cca75a1SDavid du Colombier setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize, 495219b2ee8SDavid du Colombier fp->txtoff+hp->e.h.tsize, hp->e.h.bsize); 496219b2ee8SDavid du Colombier break; 497219b2ee8SDavid du Colombier case 0413: /* some kind of mips */ 498*2cca75a1SDavid du Colombier settext(fp, (u32int)hp->e.h.mentry, (u32int)hp->e.h.text_start, 499*2cca75a1SDavid du Colombier hp->e.h.tsize, 0); 500*2cca75a1SDavid du Colombier setdata(fp, (u32int)hp->e.h.data_start, hp->e.h.dsize, 501*2cca75a1SDavid du Colombier hp->e.h.tsize, hp->e.h.bsize); 502219b2ee8SDavid du Colombier break; 5033e12c5d1SDavid du Colombier } 504219b2ee8SDavid du Colombier setsym(fp, hp->e.h.nsyms, 0, hp->e.h.pcsize, hp->e.h.symptr); 505219b2ee8SDavid du Colombier fp->hdrsz = 0; /* header stripped */ 5067dd7cddfSDavid du Colombier return 1; 507219b2ee8SDavid du Colombier } 508219b2ee8SDavid du Colombier 5093e12c5d1SDavid du Colombier /* 5103e12c5d1SDavid du Colombier * sparc bootable image 5113e12c5d1SDavid du Colombier */ 5127dd7cddfSDavid du Colombier static int 5137dd7cddfSDavid du Colombier sparcboot(int fd, Fhdr *fp, ExecHdr *hp) 5143e12c5d1SDavid du Colombier { 5157dd7cddfSDavid du Colombier USED(fd); 5163e12c5d1SDavid du Colombier fp->type = FSPARCB; 5173e12c5d1SDavid du Colombier settext(fp, hp->e.sentry, hp->e.sentry, hp->e.stext, 5183e12c5d1SDavid du Colombier sizeof(struct sparcexec)); 5193e12c5d1SDavid du Colombier setdata(fp, hp->e.sentry+hp->e.stext, hp->e.sdata, 5203e12c5d1SDavid du Colombier fp->txtoff+hp->e.stext, hp->e.sbss); 5213e12c5d1SDavid du Colombier setsym(fp, hp->e.ssyms, 0, hp->e.sdrsize, fp->datoff+hp->e.sdata); 522219b2ee8SDavid du Colombier fp->hdrsz = 0; /* header stripped */ 5237dd7cddfSDavid du Colombier return 1; 5243e12c5d1SDavid du Colombier } 5253e12c5d1SDavid du Colombier 5263e12c5d1SDavid du Colombier /* 5273e12c5d1SDavid du Colombier * next bootable image 5283e12c5d1SDavid du Colombier */ 5297dd7cddfSDavid du Colombier static int 5307dd7cddfSDavid du Colombier nextboot(int fd, Fhdr *fp, ExecHdr *hp) 5313e12c5d1SDavid du Colombier { 5327dd7cddfSDavid du Colombier USED(fd); 5333e12c5d1SDavid du Colombier fp->type = FNEXTB; 5343e12c5d1SDavid du Colombier settext(fp, hp->e.textc.vmaddr, hp->e.textc.vmaddr, 5353e12c5d1SDavid du Colombier hp->e.texts.size, hp->e.texts.offset); 5363e12c5d1SDavid du Colombier setdata(fp, hp->e.datac.vmaddr, hp->e.datas.size, 5373e12c5d1SDavid du Colombier hp->e.datas.offset, hp->e.bsss.size); 5383e12c5d1SDavid du Colombier setsym(fp, hp->e.symc.nsyms, hp->e.symc.spoff, hp->e.symc.pcoff, 5393e12c5d1SDavid du Colombier hp->e.symc.symoff); 540219b2ee8SDavid du Colombier fp->hdrsz = 0; /* header stripped */ 5417dd7cddfSDavid du Colombier return 1; 5423e12c5d1SDavid du Colombier } 5433e12c5d1SDavid du Colombier 5447dd7cddfSDavid du Colombier /* 54570b8e010SDavid du Colombier * Elf32 binaries. 5467dd7cddfSDavid du Colombier */ 5477dd7cddfSDavid du Colombier static int 5487dd7cddfSDavid du Colombier elfdotout(int fd, Fhdr *fp, ExecHdr *hp) 5497dd7cddfSDavid du Colombier { 5507dd7cddfSDavid du Colombier 5514de34a7eSDavid du Colombier ulong (*swal)(ulong); 55270b8e010SDavid du Colombier ushort (*swab)(ushort); 5537dd7cddfSDavid du Colombier Ehdr *ep; 55470b8e010SDavid du Colombier Phdr *ph; 55570b8e010SDavid du Colombier int i, it, id, is, phsz; 5567dd7cddfSDavid du Colombier 55770b8e010SDavid du Colombier /* bitswap the header according to the DATA format */ 5587dd7cddfSDavid du Colombier ep = &hp->e; 55970b8e010SDavid du Colombier if(ep->ident[CLASS] != ELFCLASS32) { 56070b8e010SDavid du Colombier werrstr("bad ELF class - not 32 bit"); 56170b8e010SDavid du Colombier return 0; 56270b8e010SDavid du Colombier } 56370b8e010SDavid du Colombier if(ep->ident[DATA] == ELFDATA2LSB) { 56470b8e010SDavid du Colombier swab = leswab; 56570b8e010SDavid du Colombier swal = leswal; 56670b8e010SDavid du Colombier } else if(ep->ident[DATA] == ELFDATA2MSB) { 56770b8e010SDavid du Colombier swab = beswab; 56870b8e010SDavid du Colombier swal = beswal; 56970b8e010SDavid du Colombier } else { 57070b8e010SDavid du Colombier werrstr("bad ELF encoding - not big or little endian"); 57170b8e010SDavid du Colombier return 0; 57270b8e010SDavid du Colombier } 57370b8e010SDavid du Colombier 57470b8e010SDavid du Colombier ep->type = swab(ep->type); 57570b8e010SDavid du Colombier ep->machine = swab(ep->machine); 57670b8e010SDavid du Colombier ep->version = swal(ep->version); 57770b8e010SDavid du Colombier ep->elfentry = swal(ep->elfentry); 57870b8e010SDavid du Colombier ep->phoff = swal(ep->phoff); 57970b8e010SDavid du Colombier ep->shoff = swal(ep->shoff); 58070b8e010SDavid du Colombier ep->flags = swal(ep->flags); 58170b8e010SDavid du Colombier ep->ehsize = swab(ep->ehsize); 58270b8e010SDavid du Colombier ep->phentsize = swab(ep->phentsize); 58370b8e010SDavid du Colombier ep->phnum = swab(ep->phnum); 58470b8e010SDavid du Colombier ep->shentsize = swab(ep->shentsize); 58570b8e010SDavid du Colombier ep->shnum = swab(ep->shnum); 58670b8e010SDavid du Colombier ep->shstrndx = swab(ep->shstrndx); 58770b8e010SDavid du Colombier if(ep->type != EXEC || ep->version != CURRENT) 5887dd7cddfSDavid du Colombier return 0; 5897dd7cddfSDavid du Colombier 59070b8e010SDavid du Colombier /* we could definitely support a lot more machines here */ 5917dd7cddfSDavid du Colombier fp->magic = ELF_MAG; 5927dd7cddfSDavid du Colombier fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15; 59370b8e010SDavid du Colombier switch(ep->machine) { 59470b8e010SDavid du Colombier case I386: 59570b8e010SDavid du Colombier mach = &mi386; 59670b8e010SDavid du Colombier fp->type = FI386; 59770b8e010SDavid du Colombier break; 59870b8e010SDavid du Colombier case MIPS: 59970b8e010SDavid du Colombier mach = &mmips; 60070b8e010SDavid du Colombier fp->type = FMIPS; 60170b8e010SDavid du Colombier break; 602b0dcc5a8SDavid du Colombier case SPARC64: 603b0dcc5a8SDavid du Colombier mach = &msparc64; 604b0dcc5a8SDavid du Colombier fp->type = FSPARC64; 605b0dcc5a8SDavid du Colombier break; 60670b8e010SDavid du Colombier case POWER: 60770b8e010SDavid du Colombier mach = &mpower; 60870b8e010SDavid du Colombier fp->type = FPOWER; 60970b8e010SDavid du Colombier break; 610b0dcc5a8SDavid du Colombier case AMD64: 611b0dcc5a8SDavid du Colombier mach = &mamd64; 612b0dcc5a8SDavid du Colombier fp->type = FAMD64; 613b0dcc5a8SDavid du Colombier break; 61470b8e010SDavid du Colombier default: 6157dd7cddfSDavid du Colombier return 0; 6167dd7cddfSDavid du Colombier } 6177dd7cddfSDavid du Colombier 61870b8e010SDavid du Colombier if(ep->phentsize != sizeof(Phdr)) { 61970b8e010SDavid du Colombier werrstr("bad ELF header size"); 62070b8e010SDavid du Colombier return 0; 62170b8e010SDavid du Colombier } 62270b8e010SDavid du Colombier phsz = sizeof(Phdr)*ep->phnum; 62370b8e010SDavid du Colombier ph = malloc(phsz); 62470b8e010SDavid du Colombier if(!ph) 62570b8e010SDavid du Colombier return 0; 62670b8e010SDavid du Colombier seek(fd, ep->phoff, 0); 62770b8e010SDavid du Colombier if(read(fd, ph, phsz) < 0) { 62870b8e010SDavid du Colombier free(ph); 62970b8e010SDavid du Colombier return 0; 63070b8e010SDavid du Colombier } 6314de34a7eSDavid du Colombier hswal(ph, phsz/sizeof(ulong), swal); 6327dd7cddfSDavid du Colombier 63370b8e010SDavid du Colombier /* find text, data and symbols and install them */ 63470b8e010SDavid du Colombier it = id = is = -1; 63570b8e010SDavid du Colombier for(i = 0; i < ep->phnum; i++) { 63670b8e010SDavid du Colombier if(ph[i].type == LOAD 63770b8e010SDavid du Colombier && (ph[i].flags & (R|X)) == (R|X) && it == -1) 63870b8e010SDavid du Colombier it = i; 63970b8e010SDavid du Colombier else if(ph[i].type == LOAD 64070b8e010SDavid du Colombier && (ph[i].flags & (R|W)) == (R|W) && id == -1) 64170b8e010SDavid du Colombier id = i; 64270b8e010SDavid du Colombier else if(ph[i].type == NOPTYPE && is == -1) 64370b8e010SDavid du Colombier is = i; 64470b8e010SDavid du Colombier } 64570b8e010SDavid du Colombier if(it == -1 || id == -1) { 646b0dcc5a8SDavid du Colombier /* 647b0dcc5a8SDavid du Colombier * The SPARC64 boot image is something of an ELF hack. 648b0dcc5a8SDavid du Colombier * Text+Data+BSS are represented by ph[0]. Symbols 649b0dcc5a8SDavid du Colombier * are represented by ph[1]: 650b0dcc5a8SDavid du Colombier * 651b0dcc5a8SDavid du Colombier * filesz, memsz, vaddr, paddr, off 652b0dcc5a8SDavid du Colombier * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff 653b0dcc5a8SDavid du Colombier * ph[1] : symsz, lcsz, 0, 0, symoff 654b0dcc5a8SDavid du Colombier */ 655b0dcc5a8SDavid du Colombier if(ep->machine == SPARC64 && ep->phnum == 2) { 656b0dcc5a8SDavid du Colombier ulong txtaddr, txtsz, dataddr, bsssz; 657b0dcc5a8SDavid du Colombier 658b0dcc5a8SDavid du Colombier txtaddr = ph[0].vaddr | 0x80000000; 659b0dcc5a8SDavid du Colombier txtsz = ph[0].filesz - ph[0].paddr; 660b0dcc5a8SDavid du Colombier dataddr = txtaddr + txtsz; 661b0dcc5a8SDavid du Colombier bsssz = ph[0].memsz - ph[0].filesz; 662b0dcc5a8SDavid du Colombier settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset); 663b0dcc5a8SDavid du Colombier setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz); 664b0dcc5a8SDavid du Colombier setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset); 665b0dcc5a8SDavid du Colombier free(ph); 666b0dcc5a8SDavid du Colombier return 1; 667b0dcc5a8SDavid du Colombier } 668b0dcc5a8SDavid du Colombier 66970b8e010SDavid du Colombier werrstr("No TEXT or DATA sections"); 67070b8e010SDavid du Colombier free(ph); 67170b8e010SDavid du Colombier return 0; 6727dd7cddfSDavid du Colombier } 6737dd7cddfSDavid du Colombier 67470b8e010SDavid du Colombier settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); 675603dff34SDavid du Colombier setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz); 67670b8e010SDavid du Colombier if(is != -1) 67770b8e010SDavid du Colombier setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset); 67870b8e010SDavid du Colombier free(ph); 6797dd7cddfSDavid du Colombier return 1; 6807dd7cddfSDavid du Colombier } 6817dd7cddfSDavid du Colombier 6827dd7cddfSDavid du Colombier /* 6837dd7cddfSDavid du Colombier * (Free|Net)BSD ARM header. 6847dd7cddfSDavid du Colombier */ 6857dd7cddfSDavid du Colombier static int 6867dd7cddfSDavid du Colombier armdotout(int fd, Fhdr *fp, ExecHdr *hp) 6877dd7cddfSDavid du Colombier { 6884de34a7eSDavid du Colombier uvlong kbase; 6897dd7cddfSDavid du Colombier 6907dd7cddfSDavid du Colombier USED(fd); 6917dd7cddfSDavid du Colombier settext(fp, hp->e.entry, sizeof(Exec), hp->e.text, sizeof(Exec)); 6927dd7cddfSDavid du Colombier setdata(fp, fp->txtsz, hp->e.data, fp->txtsz, hp->e.bss); 6937dd7cddfSDavid du Colombier setsym(fp, hp->e.syms, hp->e.spsz, hp->e.pcsz, fp->datoff+fp->datsz); 6947dd7cddfSDavid du Colombier 6957dd7cddfSDavid du Colombier kbase = 0xF0000000; 6967dd7cddfSDavid du Colombier if ((fp->entry & kbase) == kbase) { /* Boot image */ 6977dd7cddfSDavid du Colombier fp->txtaddr = kbase+sizeof(Exec); 6987dd7cddfSDavid du Colombier fp->name = "ARM *BSD boot image"; 6997dd7cddfSDavid du Colombier fp->hdrsz = 0; /* header stripped */ 7007dd7cddfSDavid du Colombier fp->dataddr = kbase+fp->txtsz; 7017dd7cddfSDavid du Colombier } 7027dd7cddfSDavid du Colombier return 1; 7037dd7cddfSDavid du Colombier } 7043e12c5d1SDavid du Colombier 7053e12c5d1SDavid du Colombier static void 7064de34a7eSDavid du Colombier settext(Fhdr *fp, uvlong e, uvlong a, long s, vlong off) 7073e12c5d1SDavid du Colombier { 7083e12c5d1SDavid du Colombier fp->txtaddr = a; 7093e12c5d1SDavid du Colombier fp->entry = e; 7103e12c5d1SDavid du Colombier fp->txtsz = s; 7113e12c5d1SDavid du Colombier fp->txtoff = off; 7123e12c5d1SDavid du Colombier } 7134de34a7eSDavid du Colombier 7143e12c5d1SDavid du Colombier static void 7154de34a7eSDavid du Colombier setdata(Fhdr *fp, uvlong a, long s, vlong off, long bss) 7163e12c5d1SDavid du Colombier { 7173e12c5d1SDavid du Colombier fp->dataddr = a; 7183e12c5d1SDavid du Colombier fp->datsz = s; 7193e12c5d1SDavid du Colombier fp->datoff = off; 7203e12c5d1SDavid du Colombier fp->bsssz = bss; 7213e12c5d1SDavid du Colombier } 7224de34a7eSDavid du Colombier 7233e12c5d1SDavid du Colombier static void 7244de34a7eSDavid du Colombier setsym(Fhdr *fp, long symsz, long sppcsz, long lnpcsz, vlong symoff) 7253e12c5d1SDavid du Colombier { 7264de34a7eSDavid du Colombier fp->symsz = symsz; 7273e12c5d1SDavid du Colombier fp->symoff = symoff; 7284de34a7eSDavid du Colombier fp->sppcsz = sppcsz; 7293e12c5d1SDavid du Colombier fp->sppcoff = fp->symoff+fp->symsz; 7304de34a7eSDavid du Colombier fp->lnpcsz = lnpcsz; 7313e12c5d1SDavid du Colombier fp->lnpcoff = fp->sppcoff+fp->sppcsz; 7323e12c5d1SDavid du Colombier } 7333e12c5d1SDavid du Colombier 734219b2ee8SDavid du Colombier 7354de34a7eSDavid du Colombier static uvlong 7364de34a7eSDavid du Colombier _round(uvlong a, ulong b) 737219b2ee8SDavid du Colombier { 7384de34a7eSDavid du Colombier uvlong w; 739219b2ee8SDavid du Colombier 740219b2ee8SDavid du Colombier w = (a/b)*b; 741219b2ee8SDavid du Colombier if (a!=w) 742219b2ee8SDavid du Colombier w += b; 743219b2ee8SDavid du Colombier return(w); 744219b2ee8SDavid du Colombier } 745