diff options
author | Jim Blandy <jimb@redhat.com> | 1992-01-13 22:04:23 +0000 |
---|---|---|
committer | Jim Blandy <jimb@redhat.com> | 1992-01-13 22:04:23 +0000 |
commit | 31fe8ae4d9ac80da34cf2d714ec5f6626c25ee9a (patch) | |
tree | f8f2127ad6d231db883844bf36b1fed70f78f271 /src/unexencap.c | |
parent | bd5cd35fd8b585ad3d87f8be98b45a415fea22c0 (diff) | |
download | emacs-31fe8ae4d9ac80da34cf2d714ec5f6626c25ee9a.tar.gz |
Initial revision
Diffstat (limited to 'src/unexencap.c')
-rw-r--r-- | src/unexencap.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/unexencap.c b/src/unexencap.c new file mode 100644 index 00000000000..4ffc41145a9 --- /dev/null +++ b/src/unexencap.c @@ -0,0 +1,116 @@ +/* Waiting for papers! */ + +/* + * Do an unexec() for coff encapsulation. Uses the approach I took + * for AKCL, so don't be surprised if it doesn't look too much like + * the other unexec() routines. Assumes NO_REMAP. Should be easy to + * adapt to the emacs style unexec() if that is desired, but this works + * just fine for me with GCC/GAS/GLD under System V. - Jordan + */ + +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/file.h> +#include <stdio.h> +#include "/usr/gnu/lib/gcc/gcc-include/a.out.h" + +filecpy(to, from, n) +FILE *to, *from; +register int n; +{ + char buffer[BUFSIZ]; + + for (;;) + if (n > BUFSIZ) { + fread(buffer, BUFSIZ, 1, from); + fwrite(buffer, BUFSIZ, 1, to); + n -= BUFSIZ; + } else if (n > 0) { + fread(buffer, 1, n, from); + fwrite(buffer, 1, n, to); + break; + } else + break; +} +/* **************************************************************** + * unexec + * + * driving logic. + * ****************************************************************/ +unexec (new_name, a_name, data_start, bss_start, entry_address) +char *new_name, *a_name; +unsigned data_start, bss_start, entry_address; +{ + struct coffheader header1; + struct coffscn *tp, *dp, *bp; + struct exec header; + int stsize; + char *original_file = a_name; + char *save_file = new_name; + + char *data_begin, *data_end; + int original_data; + FILE *original, *save; + register int n; + register char *p; + extern char *sbrk(); + char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ]; + + + fclose(stdin); + original = fopen(original_file, "r"); + if (stdin != original || original->_file != 0) { + fprintf(stderr, "unexec: Can't open the original file.\n"); + exit(1); + } + setbuf(original, stdin_buf); + fclose(stdout); + unlink(save_file); + n = open(save_file, O_CREAT|O_WRONLY, 0777); + if (n != 1 || (save = fdopen(n, "w")) != stdout) { + fprintf(stderr, "unexec: Can't open the save file.\n"); + exit(1); + } + setbuf(save, stdout_buf); + + fread(&header1, sizeof(header1), 1, original); + tp = &header1.scns[0]; + dp = &header1.scns[1]; + bp = &header1.scns[2]; + fread(&header, sizeof(header), 1, original); + data_begin=(char *)N_DATADDR(header); + data_end = sbrk(0); + original_data = header.a_data; + header.a_data = data_end - data_begin; + header.a_bss = 0; + dp->s_size = header.a_data; + bp->s_paddr = dp->s_vaddr + dp->s_size; + bp->s_vaddr = bp->s_paddr; + bp->s_size = 0; + header1.tsize = tp->s_size; + header1.dsize = dp->s_size; + header1.bsize = bp->s_size; + fwrite(&header1, sizeof(header1), 1, save); + fwrite(&header, sizeof(header), 1, save); + + filecpy(save, original, header.a_text); + + for (n = header.a_data, p = data_begin; ; n -= BUFSIZ, p += BUFSIZ) + if (n > BUFSIZ) + fwrite(p, BUFSIZ, 1, save); + else if (n > 0) { + fwrite(p, 1, n, save); + break; + } else + break; + + fseek(original, original_data, 1); + + filecpy(save, original, header.a_syms+header.a_trsize+header.a_drsize); + fread(&stsize, sizeof(stsize), 1, original); + fwrite(&stsize, sizeof(stsize), 1, save); + filecpy(save, original, stsize - sizeof(stsize)); + + fclose(original); + fclose(save); +} |