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); } }
/* 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); } }