Skip to content
coreparse.c 4.34 KiB
Newer Older
Raymond Toy's avatar
Raymond Toy committed
/*

 This code was written as part of the CMU Common Lisp project at
 Carnegie Mellon University, and has been placed in the public domain.

*/

wlott's avatar
wlott committed
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>

hallgren's avatar
hallgren committed
#include <fcntl.h>
#include <stdlib.h>
cshapiro's avatar
cshapiro committed
#include <unistd.h>
hallgren's avatar
hallgren committed

wlott's avatar
wlott committed
#include "os.h"
#include "lisp.h"
#include "globals.h"
#include "core.h"
wlott's avatar
wlott committed

extern int version;

static void
process_directory(int fd, long *ptr, int count)
wlott's avatar
wlott committed
{
    long id, offset, len;
    lispobj *free_pointer;
    os_vm_address_t addr;
    struct ndir_entry *entry;

    entry = (struct ndir_entry *) ptr;

    while (count-- > 0) {
	id = entry->identifier;
	offset = CORE_PAGESIZE * (1 + entry->data_page);
	addr = (os_vm_address_t) (CORE_PAGESIZE * entry->address);
	free_pointer = (lispobj *) addr + entry->nwords;
	len = CORE_PAGESIZE * entry->page_count;

	if (len != 0) {
	    os_vm_address_t real_addr;
wlott's avatar
wlott committed
#ifdef PRINTNOISE
ram's avatar
ram committed
	    printf("Mapping %ld bytes at 0x%lx.\n", len, addr);
wlott's avatar
wlott committed
#endif
	    real_addr = os_map(fd, offset, addr, len);
	    if (real_addr != addr)
		fprintf(stderr,
			"process_directory: file mapped in wrong place! (0x%p != 0x%p)\n",
			(void *) real_addr, (void *) addr);
pw's avatar
pw committed
#if 0
	printf("Space ID = %d, free pointer = 0x%08x.\n", id, free_pointer);
wlott's avatar
wlott committed
#endif

	switch (id) {
	  case DYNAMIC_SPACE_ID:
	      if (addr != (os_vm_address_t) dynamic_0_space
		  && addr != (os_vm_address_t) dynamic_1_space)
		  printf("Strange ... dynamic space lossage.\n");
	      current_dynamic_space = (lispobj *) addr;
cwang's avatar
cwang committed
#if defined(ibmrt) || defined(i386) || defined(__x86_64)
	      SetSymbolValue(ALLOCATION_POINTER, (lispobj) free_pointer);
wlott's avatar
wlott committed
#else
	      current_dynamic_space_free_pointer = free_pointer;
wlott's avatar
wlott committed
#endif
	      static_space = (lispobj *) addr;
Raymond Toy's avatar
Raymond Toy committed
              if (len >= static_space_size) {
                  fprintf(stderr, "Error:  Static space size (%ld) exceeds allocated space (%ld)!\n",
Raymond Toy's avatar
Raymond Toy committed
                          len, static_space_size);
                  exit(1);
              }
	      /* Don't care about read only space */
Raymond Toy's avatar
Raymond Toy committed
              if (len >= read_only_space_size) {
                  fprintf(stderr, "Error:  Read only space size (%ld) exceeds allocated space (%lu)!\n",
Raymond Toy's avatar
Raymond Toy committed
                          len, read_only_space_size);
                  exit(1);
              }
	      printf("Strange space ID: %ld; ignored.\n", id);
	      break;
wlott's avatar
wlott committed
	}
wlott's avatar
wlott committed
}

load_core_file(const char *file, fpu_mode_t* fpu_type)
wlott's avatar
wlott committed
{
    int fd = open(file, O_RDONLY), count;
cwang's avatar
cwang committed
#if !(defined(alpha) || defined(__x86_64))
wlott's avatar
wlott committed
    long header[CORE_PAGESIZE / sizeof(long)], val, len, *ptr;
hallgren's avatar
hallgren committed
#else
    u32 header[CORE_PAGESIZE / sizeof(u32)], val, len, *ptr;
#endif
    lispobj initial_function = NIL;
wlott's avatar
wlott committed

    if (fd < 0) {
	fprintf(stderr, "Could not open file \"%s\".\n", file);
	perror("open");
	exit(1);
wlott's avatar
wlott committed
    }

    count = read(fd, header, CORE_PAGESIZE);
    if (count < 0) {
wlott's avatar
wlott committed
    }
    if (count < CORE_PAGESIZE) {
	fprintf(stderr, "Premature EOF.\n");
	exit(1);
wlott's avatar
wlott committed

    ptr = header;
    val = *ptr++;

    if (val != CORE_MAGIC) {
ram's avatar
ram committed
	fprintf(stderr, "Invalid magic number: 0x%lx should have been 0x%x.\n",
wlott's avatar
wlott committed
    }

    while (val != CORE_END) {
	val = *ptr++;
	len = *ptr++;

	switch (val) {
	  case CORE_END:
	      if (*ptr != version) {
		  fprintf(stderr,
			  "WARNING: startup-code version (%d) different from core version (%ld).\nYou may lose big.\n",
			  version, *ptr);
	      }
	      if (len == 4) {
                *fpu_type = (fpu_mode_t) ptr[1];
	      fprintf(stderr, "Validation no longer supported; ignored.\n");
	      break;
	      process_directory(fd, ptr,
cwang's avatar
cwang committed
#if !(defined(alpha) || defined(__x86_64))
				(len - 2) / (sizeof(struct ndir_entry) / sizeof(long)));
hallgren's avatar
hallgren committed
#else
				(len - 2) / (sizeof(struct ndir_entry) / sizeof(u32)));
hallgren's avatar
hallgren committed
#endif
	      initial_function = (lispobj) * ptr;
	      break;
	      fprintf(stderr, "Obsolete core file.\n");
	      exit(1);
	      break;
	      printf("Unknown core file entry: %ld; skipping.\n", val);
	      break;
wlott's avatar
wlott committed
    }

wlott's avatar
wlott committed
}