175 lines
4.5 KiB
C
175 lines
4.5 KiB
C
/*
|
|
* d u m p . c -- Image creation
|
|
*
|
|
* Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
|
*
|
|
*
|
|
* Permission to use, copy, modify, distribute,and license this
|
|
* software and its documentation for any purpose is hereby granted,
|
|
* provided that existing copyright notices are retained in all
|
|
* copies and that this notice is included verbatim in any
|
|
* distributions. No written agreement, license, or royalty fee is
|
|
* required for any of the authorized uses.
|
|
* This software is provided ``AS IS'' without express or implied
|
|
* warranty.
|
|
*
|
|
* Author: Erick Gallesio [eg@unice.fr]
|
|
* Creation date: ??-Jul-1993 ??:??
|
|
* Last file update: 3-Sep-1999 20:19 (eg)
|
|
*/
|
|
|
|
#include "stk.h"
|
|
|
|
int STk_dumped_core = 0;
|
|
|
|
#if defined (SUNOS4) || defined(FREEBSD) || defined(LINUX)
|
|
static caddr_t current_break = (caddr_t) -1;
|
|
static long data_size = 0;
|
|
static long data_start = 0;
|
|
static int restoring_image = 0;
|
|
|
|
#include <a.out.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <setjmp.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
|
|
#define TEXT_START(x) (N_TXTADDR(x)+(sizeof(x)-N_TXTOFF(x)))
|
|
#define TEXT_SIZE(x) ((x).a_text - (sizeof(x)-N_TXTOFF(x)))
|
|
#define DATA_START(x) (N_DATADDR(x))
|
|
|
|
|
|
static int dump_data_file(char *argv0, char *name)
|
|
{
|
|
int fd1, fd2;
|
|
struct exec header;
|
|
|
|
/* find the header of current running program */
|
|
if ((fd1 = open(argv0, O_RDONLY)) < 0)
|
|
Err("dump: cannot open myself", STk_makestring(argv0));
|
|
|
|
read(fd1, &header, sizeof header);
|
|
|
|
/* Now that this header is read, create the new file */
|
|
if ((fd2=open(name, O_WRONLY|O_CREAT|O_TRUNC, 0755)) < 0) {
|
|
close(fd1);
|
|
Err("dump: cannot open file", STk_makestring(name));
|
|
}
|
|
|
|
/* write in fd2 the current sbrk followed by data segment size */
|
|
current_break = (caddr_t) sbrk(0);
|
|
data_size = (char *)current_break - (char *) DATA_START(header);
|
|
data_start = DATA_START(header);
|
|
|
|
write(fd2, ¤t_break, sizeof(caddr_t));
|
|
write(fd2, &data_size, sizeof(long));
|
|
write(fd2, &data_start, sizeof(long));
|
|
|
|
/* Copy data segment */
|
|
write(fd2, (void *)DATA_START(header), data_size);
|
|
|
|
close(fd1); close(fd2);
|
|
return 1;
|
|
}
|
|
|
|
|
|
static int Restore_data_file(char *name)
|
|
{
|
|
int fd;
|
|
|
|
/* find the header of current running program */
|
|
if ((fd = open(name, O_RDONLY)) < 0)
|
|
Err("Cannot open image file", STk_makestring(name));
|
|
|
|
/* read the break we have to set and data segment size */
|
|
read(fd, ¤t_break, sizeof(caddr_t));
|
|
read(fd, &data_size, sizeof(long));
|
|
read(fd, &data_start, sizeof(long));
|
|
|
|
/* read data segment */
|
|
brk(current_break);
|
|
read(fd, (void *)data_start, data_size);
|
|
|
|
close(fd);
|
|
return 1;
|
|
}
|
|
|
|
|
|
static void internal_dump(char *s)
|
|
{
|
|
/* Store current continuation in a global Scheme variable */
|
|
STk_eval_C_string("(define *global-continuation* (call/cc (lambda(e) e)))", NIL);
|
|
|
|
if (restoring_image) {
|
|
/*
|
|
* Since the primitive dump is in the call stack when we saved
|
|
* continuation, we go back here on image restoration. If restoring_image is
|
|
* is equal to 1, we are restoring an image, so we can return.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
STk_dumped_core = 1;
|
|
dump_data_file(STk_Argv0, CHARS(STk_internal_expand_file_name(s)));
|
|
STk_dumped_core = 0;
|
|
}
|
|
|
|
|
|
void STk_restore_image(char *s)
|
|
{
|
|
SCM gcont;
|
|
|
|
Restore_data_file(s);
|
|
STk_dumped_core = restoring_image = 1;
|
|
|
|
gcont = STk_lookup_variable("*global-continuation*", NIL);
|
|
/* After reading the file we must have a continuation in *global-continuation* */
|
|
if (NCONTINUATIONP(gcont)) {
|
|
Err("restore: file loaded is corrupted. DANGER.", NIL);
|
|
}
|
|
Apply1(gcont, Ntruth);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* d u m p p r i m i t i v e
|
|
*
|
|
******************************************************************************/
|
|
|
|
PRIMITIVE STk_dump(SCM s)
|
|
{
|
|
if (NSTRINGP(s)) Err("dump: bad file name", s);
|
|
#ifdef USE_TK
|
|
if (Tk_initialized) Err("dump: cannot dump an image if you have "
|
|
"not used the `-no-tk' option.\nSorry.", NIL);
|
|
#endif
|
|
internal_dump(CHARS(s));
|
|
return UNDEFINED;
|
|
}
|
|
|
|
#else
|
|
|
|
/********************************************/
|
|
/**** ****/
|
|
/**** Architectures without Dump support ****/
|
|
/**** ****/
|
|
/********************************************/
|
|
|
|
static void dump_error()
|
|
{
|
|
Err("dump/restore not available on this architecture", NIL);
|
|
}
|
|
|
|
void STk_restore_image(char *s)
|
|
{
|
|
dump_error();
|
|
}
|
|
|
|
PRIMITIVE STk_dump(SCM s)
|
|
{
|
|
dump_error();
|
|
return UNDEFINED; /* never reached */
|
|
}
|
|
#endif
|