示例#1
0
static void
process_directory(int fd, lispobj *ptr, int count, os_vm_offset_t file_offset)
{
    extern void immobile_space_coreparse(uword_t,uword_t);
    struct ndir_entry *entry;
    int compressed;

    FSHOW((stderr, "/process_directory(..), count=%d\n", count));

    for (entry = (struct ndir_entry *) ptr; --count>= 0; ++entry) {

        compressed = 0;
        sword_t id = entry->identifier;
        if (id <= (MAX_CORE_SPACE_ID | DEFLATED_CORE_SPACE_ID_FLAG)) {
            if (id & DEFLATED_CORE_SPACE_ID_FLAG)
                compressed = 1;
            id &= ~(DEFLATED_CORE_SPACE_ID_FLAG);
        }
        sword_t offset = os_vm_page_size * (1 + entry->data_page);
        os_vm_address_t addr =
            (os_vm_address_t) (os_vm_page_size * entry->address);
        lispobj *free_pointer = (lispobj *) addr + entry->nwords;
        uword_t len = os_vm_page_size * entry->page_count;
        if (len != 0) {
            os_vm_address_t real_addr;
            FSHOW((stderr, "/mapping %ld(0x%lx) bytes at 0x%lx\n",
                   len, len, (uword_t)addr));
            if (compressed) {
#ifdef LISP_FEATURE_SB_CORE_COMPRESSION
                real_addr = inflate_core_bytes(fd, offset + file_offset, addr, len);
#else
                lose("This runtime was not built with zlib-compressed core support... aborting\n");
#endif
            } else {
#ifdef LISP_FEATURE_HPUX
                real_addr = copy_core_bytes(fd, offset + file_offset, addr, len);
#else
                real_addr = os_map(fd, offset + file_offset, addr, len);
#endif
            }
            if (real_addr != addr) {
                lose("file mapped in wrong place! "
                     "(0x%08x != 0x%08lx)\n",
                     real_addr,
                     addr);
            }
        }

#ifdef MADV_MERGEABLE
        if ((merge_core_pages == 1)
            || ((merge_core_pages == -1) && compressed)) {
                madvise(addr, len, MADV_MERGEABLE);
        }
#endif
        FSHOW((stderr, "/space id = %ld, free pointer = %p\n",
               id, (uword_t)free_pointer));

        switch (id) {
        case DYNAMIC_CORE_SPACE_ID:
            if (len > dynamic_space_size) {
                fprintf(stderr,
                        "dynamic space too small for core: %luKiB required, %luKiB available.\n",
                        (unsigned long)len >> 10,
                        (unsigned long)dynamic_space_size >> 10);
                exit(1);
            }
#ifdef LISP_FEATURE_GENCGC
            if (addr != (os_vm_address_t)DYNAMIC_SPACE_START) {
                fprintf(stderr, "in core: %p; in runtime: %p \n",
                        (void*)addr, (void*)DYNAMIC_SPACE_START);
                lose("core/runtime address mismatch: DYNAMIC_SPACE_START\n");
            }
#else
            if ((addr != (os_vm_address_t)DYNAMIC_0_SPACE_START) &&
                (addr != (os_vm_address_t)DYNAMIC_1_SPACE_START)) {
                fprintf(stderr, "in core: %p; in runtime: %p or %p\n",
                        (void*)addr,
                        (void*)DYNAMIC_0_SPACE_START,
                        (void*)DYNAMIC_1_SPACE_START);
                lose("warning: core/runtime address mismatch: DYNAMIC_SPACE_START\n");
            }
#endif
#if defined(ALLOCATION_POINTER)
            SetSymbolValue(ALLOCATION_POINTER, (lispobj)free_pointer,0);
#else
            dynamic_space_free_pointer = free_pointer;
#endif
            /* For stop-and-copy GC, this will be whatever the GC was
             * using at the time. With GENCGC, this will always be
             * space 0. (We checked above that for GENCGC,
             * addr==DYNAMIC_SPACE_START.) */
            current_dynamic_space = (lispobj *)addr;
            break;
        case STATIC_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)STATIC_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)STATIC_SPACE_START);
                lose("core/runtime address mismatch: STATIC_SPACE_START\n");
            }
            break;
        case READ_ONLY_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)READ_ONLY_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)READ_ONLY_SPACE_START);
                lose("core/runtime address mismatch: READ_ONLY_SPACE_START\n");
            }
            break;
#ifdef LISP_FEATURE_IMMOBILE_SPACE
         // Immobile space is subdivided into fixed-size and variable-size.
         // There is no margin between the two, though for efficiency
         // they are written separately to eliminate waste in the core file.
        case IMMOBILE_FIXEDOBJ_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)IMMOBILE_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)IMMOBILE_SPACE_START);
                lose("core/runtime address mismatch: IMMOBILE_SPACE_START\n");
            }
            immobile_space_coreparse(IMMOBILE_SPACE_START, len);
            break;
        case IMMOBILE_VARYOBJ_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)IMMOBILE_VARYOBJ_SUBSPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)IMMOBILE_VARYOBJ_SUBSPACE_START);
                lose("core/runtime address mismatch: IMMOBILE_VARYOBJ_SUBSPACE_START\n");
            }
            immobile_space_coreparse(IMMOBILE_VARYOBJ_SUBSPACE_START, len);
            break;
#endif
        default:
            lose("unknown space ID %ld addr %p\n", id, addr);
        }
    }
示例#2
0
文件: elf.c 项目: Distrotech/cmucl
/*
  Map the built-in lisp core sections.

  NOTE!  We need to do this without using malloc because the memory layout
  is not set until some time after this is done.
*/
void
map_core_sections(const char *exec_name)
{
    int exec_fd;
    Elf_Shdr sh;		/* A section header entry. */
    Elf_Shdr strsecent;
    char nambuf[10];
    int soff;
    int strsecoff;		/* File offset to string table section. */
    int sections_remaining = 3;
    int i, j;
    extern int
	image_dynamic_space_size,
	image_static_space_size,
	image_read_only_space_size;

    if (!(exec_fd = open(exec_name, O_RDONLY))) {
	perror("Can't open executable!");
	exit(-1);
    }

    read_elf_header(exec_fd, &eh);

    /* Find the section name string section.	Save its file offset. */
    soff = eh.e_shoff + eh.e_shstrndx * eh.e_shentsize;
    elseek(exec_fd, soff, __func__);
    read_section_header_entry(exec_fd, &strsecent);
    strsecoff = strsecent.sh_offset;

    for (i = 0; i < eh.e_shnum && sections_remaining > 0; i++) {

	/* Read an entry from the section header table. */
	elseek(exec_fd, eh.e_shoff + i * eh.e_shentsize, __func__);
	read_section_header_entry(exec_fd, &sh);

	/* Read the name from the string section. */
	elseek(exec_fd, strsecoff + sh.sh_name, __func__);
	eread(exec_fd, nambuf, 6, __func__);

	if (sh.sh_type == SHT_PROGBITS) {
	    /* See if this section is one of the lisp core sections. */
	    for (j = 0; j < 3; j++) {
		if (!strncmp(nambuf, section_names[j], 6)) {
		    os_vm_address_t addr;
		    /*
                     * Found a core section. Map it!
                     *
                     * Although the segment may contain the correct
                     * address for the start of the segment, we don't
                     * care.  We infer the address from the segment
                     * name.  (The names better be unique!!!!)  This
                     * approach allows for a possibly simpler linking
                     * operation because we don't have to figure out
                     * how to get the linker to give segments the
                     * correct address.
		     */
		    addr = section_addr[j];
		    if ((os_vm_address_t) os_map(exec_fd, sh.sh_offset,
						 addr, sh.sh_size)
			== (os_vm_address_t) -1) {
			fprintf(stderr, "%s: Can't map section %s\n", __func__, section_names[j]);
			exit(-1);
		    }
		    switch(j) {
                      case 0: /* Dynamic space. */
                          /* Dynamic space variables are set in lisp.c. */
                          image_dynamic_space_size = sh.sh_size;
                          break;
                      case 1: /* Static space. */
                          image_static_space_size = sh.sh_size;
                          break;
                      case 2: /* Read-only space. */
                          image_read_only_space_size = sh.sh_size;
                          break;
                      default:
                          /* Should never get here. */
                          abort();
                          break;
		    }

		    sections_remaining--;
		    /* Found a core section, don't check the other core section names. */
		    break;
		}
	    }
	}
    }

    close(exec_fd);

    if (sections_remaining != 0) {
	fprintf(stderr, "Couldn't map all core sections!	Exiting!\n");
	exit(-1);
    }
}