source: icGREP/icgrep-devel/cudd-2.5.1/util/saveimage.c @ 5820

Last change on this file since 5820 was 4597, checked in by nmedfort, 4 years ago

Upload of the CUDD library.

File size: 5.0 KB
RevLine 
[4597]1/* LINTLIBRARY */
2
3
4/*
5 * saveimage.c --
6 *
7 * Function to save an executable copy of the current process's
8 * image in a file.
9 *
10 */
11
12#include <stdio.h>
13#include "util.h"
14
15#ifdef BSD
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <a.out.h>
19#include <errno.h>
20
21extern int errno;
22
23#define BUFSIZE         8192
24
25extern long lseek();    /* For lint */
26extern int getpagesize();
27extern char *sbrk();
28
29static int copy_file();
30static int pad_file();
31
32
33int
34util_save_image(char const *orig_file_name, char const *save_file_name)
35{
36    int origFd = -1, saveFd = -1;
37    char *start_data, *end_data, *start_text, *end_round;
38    struct exec old_hdr, new_hdr;
39    struct stat old_stat;
40    int n, page_size, length_text, length_data;
41
42    if ((origFd = open(orig_file_name, 0)) < 0) {
43        perror(orig_file_name);
44        (void) fprintf(stderr, "Cannot open original a.out file\n");
45        goto bad;
46    }
47
48    if (fstat(origFd, &old_stat) < 0) {
49        perror(orig_file_name);
50        (void) fprintf(stderr, "Cannot stat original a.out file\n");
51        goto bad;
52    }
53
54    /*
55     * Read the a.out header from the original file.
56     */
57    if (read(origFd, (char *) &old_hdr, sizeof(old_hdr)) != sizeof(old_hdr)) {
58        perror(orig_file_name);
59        (void) fprintf(stderr, "Cannot read original a.out header\n");
60        goto bad;
61    }
62    if (N_BADMAG(old_hdr)) {
63        (void) fprintf(stderr, "File %s has a bad magic number (%o)\n",
64                        orig_file_name, old_hdr.a_magic);
65        goto bad;
66    }
67    if (old_hdr.a_magic != ZMAGIC) {
68        (void) fprintf(stderr, "File %s is not demand-paged\n", orig_file_name);
69        goto bad;
70    }
71
72    /*
73     * Open the output file.
74     */
75    if (access(save_file_name, /* F_OK */ 0) == 0) {
76        (void) unlink(save_file_name);
77    }
78    if ((saveFd = creat(save_file_name, 0777)) < 0) {
79        if (errno == ETXTBSY) {
80            (void) unlink(save_file_name);
81            saveFd = creat(save_file_name, 0777);
82        }
83        if (saveFd < 0) {
84            perror(save_file_name);
85            (void) fprintf(stderr, "Cannot create save file.\n");
86            goto bad;
87        }
88    }
89
90    /*
91     * Find out how far the data segment extends.
92     */
93    new_hdr = old_hdr;
94    end_data = sbrk(0);
95    page_size = getpagesize();
96    n = ((((int) end_data) + page_size - 1) / page_size) * page_size;
97    end_round = (char *) n;
98    if (end_round > end_data) {
99        end_data = sbrk(end_round - end_data);
100    }
101
102#ifdef vax
103    start_text = 0;
104    length_text = new_hdr.a_text;
105    start_data = (char *) old_hdr.a_text;
106    length_data = end_data - start_data;
107#endif vax
108#ifdef  sun
109    start_text = (char *) N_TXTADDR(old_hdr) + sizeof(old_hdr);
110    length_text = old_hdr.a_text - sizeof(old_hdr);
111    start_data = (char *) N_DATADDR(old_hdr);
112    length_data = end_data - start_data;
113#endif  sun
114    new_hdr.a_data = end_data - start_data;
115    new_hdr.a_bss = 0;
116
117    /*
118     * First, the header plus enough pad to extend up to N_TXTOFF.
119     */
120    if (write(saveFd, (char *) &new_hdr, (int) sizeof(new_hdr)) !=
121                                sizeof(new_hdr)) {
122        perror("write");
123        (void) fprintf(stderr, "Error while copying header.\n");
124        goto bad;
125    }
126    if (! pad_file(saveFd, N_TXTOFF(old_hdr) - sizeof(new_hdr))) {
127        (void) fprintf(stderr, "Error while padding.\n");
128        goto bad;
129    }
130
131
132    /*
133     *  Copy our text segment
134     */
135    if (write(saveFd, start_text, length_text) != length_text) {
136        perror("write");
137        (void) fprintf(stderr, "Error while copying text segment.\n");
138        goto bad;
139    }
140
141
142    /*
143     *  Copy our data segment
144     */
145    if (write(saveFd, start_data, length_data) != length_data) {
146        perror("write");
147        (void) fprintf(stderr, "Error while copying data segment.\n");
148        goto bad;
149    }
150
151    /*
152     * Copy the symbol table and everything else.
153     * This takes us to the end of the original file.
154     */
155    (void) lseek(origFd, (long) N_SYMOFF(old_hdr), 0);
156    if (! copy_file(origFd, saveFd, old_stat.st_size - N_SYMOFF(old_hdr))) {
157        (void) fprintf(stderr, "Error while copying symbol table.\n");
158        goto bad;
159    }
160    (void) close(origFd);
161    (void) close(saveFd);
162    return 1;
163
164bad:
165    if (origFd >= 0) (void) close(origFd);
166    if (saveFd >= 0) (void) close(saveFd);
167    return 0;
168}
169
170
171static int
172copy_file(inFd, outFd, nbytes)
173int inFd, outFd;
174unsigned long nbytes;
175{
176    char buf[BUFSIZE];
177    int nread, ntoread;
178
179    while (nbytes > 0) {
180        ntoread = nbytes;
181        if (ntoread > sizeof buf) ntoread = sizeof buf;
182        if ((nread = read(inFd, buf, ntoread)) != ntoread) {
183            perror("read");
184            return (0);
185        }
186        if (write(outFd, buf, nread) != nread) {
187            perror("write");
188            return (0);
189        }
190        nbytes -= nread;
191    }
192
193    return (1);
194}
195
196
197static int
198pad_file(outFd, nbytes)
199int outFd;
200int nbytes;
201{
202    char buf[BUFSIZE];
203    int nzero;
204
205    nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes;
206    bzero(buf, nzero);
207    while (nbytes > 0) {
208        nzero = (nbytes > sizeof(buf)) ? sizeof(buf) : nbytes;
209        if (write(outFd, buf, nzero) != nzero) {
210            perror("write");
211            return (0);
212        }
213        nbytes -= nzero;
214    }
215
216    return (1);
217}
218#else
219
220/* ARGSUSED */
221int
222util_save_image(char const *orig_file_name, char const *save_file_name)
223{
224    (void) fprintf(stderr, 
225        "util_save_image: not implemented on your operating system\n");
226    return 0;
227}
228
229#endif
Note: See TracBrowser for help on using the repository browser.