diff options
author | aiju <devnull@localhost> | 2020-01-08 02:22:20 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2020-01-08 02:22:20 +0000 |
commit | 76ed5d2e4b0279eea6dd6e3ddb03690d027b059d (patch) | |
tree | 10670885661f4516914f466f45ccf6c6880ae004 /sys/src/cmd/aux/aout2uimage.c | |
parent | c43700f5690722e4226bedf07f457a206dc7b2d1 (diff) |
add aux/aout2uimage
Diffstat (limited to 'sys/src/cmd/aux/aout2uimage.c')
-rw-r--r-- | sys/src/cmd/aux/aout2uimage.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/aout2uimage.c b/sys/src/cmd/aux/aout2uimage.c new file mode 100644 index 000000000..8898a6df7 --- /dev/null +++ b/sys/src/cmd/aux/aout2uimage.c @@ -0,0 +1,167 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <mach.h> +#include <flate.h> + +int infd, outfd; +ulong dcrc; +ulong *tab; +uchar buf[65536]; + +enum { + IH_ARCH_INVALID = 0, + IH_ARCH_ALPHA, + IH_ARCH_ARM, + IH_ARCH_I386, + IH_ARCH_IA64, + IH_ARCH_MIPS, + IH_ARCH_MIPS64, + IH_ARCH_PPC, + IH_ARCH_S390, + IH_ARCH_SH, + IH_ARCH_SPARC, + IH_ARCH_SPARC64, + IH_ARCH_M68K, + IH_ARCH_NIOS, + IH_ARCH_MICROBLAZE, + IH_ARCH_NIOS2, + IH_ARCH_BLACKFIN, + IH_ARCH_AVR32, + IH_ARCH_ST200, + IH_ARCH_SANDBOX, + IH_ARCH_NDS32, + IH_ARCH_OPENRISC, + IH_ARCH_ARM64, + IH_ARCH_ARC, + IH_ARCH_X86_64, + IH_ARCH_XTENSA, + IH_ARCH_RISCV, +}; + +uchar archtab[] = { + [MMIPS] IH_ARCH_MIPS, + [MSPARC] IH_ARCH_SPARC, + [MI386] IH_ARCH_I386, + [MMIPS2] IH_ARCH_MIPS, + [NMIPS2] IH_ARCH_MIPS, + [MARM] IH_ARCH_ARM, + [MPOWER] IH_ARCH_PPC, + [MALPHA] IH_ARCH_ALPHA, + [NMIPS] IH_ARCH_MIPS, + [MSPARC64] IH_ARCH_SPARC64, + [MAMD64] IH_ARCH_X86_64, + [MPOWER64] IH_ARCH_PPC, + [MARM64] IH_ARCH_ARM64, +}; + +void +put(uchar *p, u32int v) +{ + *p++ = v >> 24; + *p++ = v >> 16; + *p++ = v >> 8; + *p = v; +} + +void +usage(void) +{ + fprint(2, "usage: %s a.out", argv0); + exits("usage"); +} + +void +block(int n) +{ + int rc; + + rc = readn(infd, buf, n); + if(rc < 0) sysfatal("read: %r"); + if(rc < n) sysfatal("input file truncated"); + if(write(outfd, buf, n) < 0) sysfatal("write error"); + dcrc = blockcrc(tab, dcrc, buf, n); +} + +void +copy(int n) +{ + int i; + + for(i = sizeof(buf) - 1; i < n; i += sizeof(buf)) + block(sizeof(buf)); + i = n & sizeof(buf) - 1; + if(i > 0) + block(i); +} + +void +main(int argc, char **argv) +{ + Fhdr fhdr; + u64int kzero; + uchar header[64]; + char *ofile, *iname; + int n, arch; + + kzero = 0xF0000000; + ofile = nil; + ARGBEGIN { + case 'Z': kzero = strtoull(EARGF(usage()), 0, 0); break; + case 'o': ofile = strdup(EARGF(usage())); break; + default: usage(); + } ARGEND; + + if(argc != 1) usage(); + infd = open(argv[0], OREAD); + if(infd < 0) sysfatal("infd: %r"); + if(crackhdr(infd, &fhdr) == 0) sysfatal("crackhdr: %r"); + + iname = strrchr(argv[0], '/'); + if(iname != nil) + iname++; + else + iname = argv[1]; + if(ofile == nil) ofile = smprint("%s.u", iname); + outfd = create(ofile, OWRITE|OTRUNC, 0666); + if(outfd < 0) sysfatal("create: %r"); + + tab = mkcrctab(0xEDB88320); + assert(sizeof(buf) >= mach->pgsize); + seek(infd, 0, 0); + seek(outfd, sizeof(header), 0); + dcrc = 0; + + copy(fhdr.hdrsz + fhdr.txtsz); + n = -(fhdr.hdrsz + fhdr.txtsz) & mach->pgsize - 1; + if(n > 0){ + memset(buf, 0, n); + if(write(outfd, buf, n) < 0) sysfatal("write: %r"); + dcrc = blockcrc(tab, dcrc, buf, n); + } + copy(fhdr.datsz); + + if((uint)mach->mtype >= nelem(archtab) || archtab[mach->mtype] == 0) + sysfatal("archloch"); + arch = archtab[mach->mtype]; + + memset(header, 0, sizeof(header)); + put(&header[0], 0x27051956); /* magic */ + put(&header[8], time(0)); /* time */ + put(&header[12], -(-(fhdr.hdrsz + fhdr.txtsz) & -mach->pgsize) + fhdr.datsz); /* image size */ + put(&header[16], fhdr.txtaddr - fhdr.hdrsz - kzero); /* load address */ + put(&header[20], fhdr.entry - kzero); /* entry point */ + put(&header[24], dcrc); /* data crc */ + header[28] = 23; /* os = plan 9 */ + header[29] = arch; + header[30] = 2; /* type = kernel */ + header[31] = 0; /* compressed = no */ + + strncpy((char*)&header[32], iname, sizeof(header)-32); + put(&header[4], blockcrc(tab, 0, header, sizeof(header))); + + seek(outfd, 0, 0); + if(write(outfd, header, sizeof(header)) < sizeof(header)) sysfatal("write: %r"); + + exits(nil); +} |