diff --git a/lisp/elf.c b/lisp/elf.c index a627bc5495724e66e51228f96d1f870ca7f13791..e962e553c27cadd0228b5fe0903d6b4e181882a0 100644 --- a/lisp/elf.c +++ b/lisp/elf.c @@ -8,7 +8,7 @@ Above changes put into main CVS branch. 05-Jul-2007. - $Id: elf.c,v 1.22 2010/07/30 20:26:11 rtoy Exp $ + $Id: elf.c,v 1.23 2010/07/31 00:03:23 rtoy Exp $ */ #include <stdio.h> @@ -278,7 +278,7 @@ write_object_section(int fd, long length, os_vm_address_t real_addr) int -write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t end) +write_space_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t end) { int out = create_elf_file(dir, id); int ret = 0; @@ -316,7 +316,7 @@ write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t } void -elf_cleanup(const char *dirname) +obj_cleanup(const char *dirname) { char filename[FILENAME_MAX + 1]; int i; @@ -330,7 +330,7 @@ elf_cleanup(const char *dirname) } int -elf_run_linker(long init_func_address, char *file) +obj_run_linker(long init_func_address, char *file) { lispobj libstring = SymbolValue(CMUCL_LIB); /* Get library: */ struct vector *vec = (struct vector *)PTR(libstring); diff --git a/lisp/elf.h b/lisp/elf.h index 22918f257900f55eb579eb3a2ef6bd8a3181e358..50824a051c9d6379db6850df51070514eaefaa26 100644 --- a/lisp/elf.h +++ b/lisp/elf.h @@ -1,14 +1,19 @@ -/* $Id: elf.h,v 1.11 2010/07/29 04:34:10 rtoy Exp $ */ +/* $Id: elf.h,v 1.12 2010/07/31 00:03:23 rtoy Exp $ */ /* This code was written by Fred Gilham and has been placed in the public domain. It is provided "AS-IS" and without warranty of any kind. */ +/* + * Despite the fact that this file is named elf.h, it's really the + * interface to both elf and mach-o support. I (rtoy) was too lazy to + * change the name to something more descriptive. + */ #if !defined(_ELF_H_INCLUDED_) #define _ELF_H_INCLUDED_ -#if defined(__linux__) +#if defined(__linux__) || defined(DARWIN) #define LINKER_SCRIPT "linker-x86.sh" #else #define LINKER_SCRIPT "linker.sh" @@ -16,10 +21,13 @@ #if defined(SOLARIS) #include <sys/elf.h> +#elif defined(DARWIN) +#include <mach-o/loader.h> #else #include <elf.h> #endif + /* * We need to know which compiler was used to build lisp. I think gcc * is used everywhere, except on Solaris/sparc, where we can use @@ -31,13 +39,14 @@ #define C_COMPILER "gcc" #endif -int write_elf_object(const char *, int, os_vm_address_t, os_vm_address_t); -void elf_cleanup(const char *); -int elf_run_linker(long, char *); +int write_space_object(const char *, int, os_vm_address_t, os_vm_address_t); +void obj_cleanup(const char *); +int obj_run_linker(long, char *); void map_core_sections(const char *); -#if defined(SOLARIS) || defined(linux) || defined(__NetBSD__) +#if defined(DARWIN) +#elif defined(SOLARIS) || defined(linux) || defined(__NetBSD__) typedef Elf32_Ehdr Elf_Ehdr; typedef Elf32_Shdr Elf_Shdr; typedef Elf32_Word Elf_Word; diff --git a/lisp/mach-o.c b/lisp/mach-o.c index 096be872b8feb579d2a0c58498cb47bc9e0f0712..40b51f610bd166a29a2892d001473e7324d0738b 100644 --- a/lisp/mach-o.c +++ b/lisp/mach-o.c @@ -12,10 +12,7 @@ #include "globals.h" #include "validate.h" -#include "mach-o/loader.h" - -#define LINKER_SCRIPT "linker-x86.sh" -#define C_COMPILER "cc" +#include "elf.h" typedef struct mach_header MachO_hdr; @@ -67,9 +64,8 @@ elseek(int d, off_t o, int whence, const char *func) } } - static int -create_elf_file (const char *dir, int id) +create_mach_o_file (const char *dir, int id) { char outfilename[FILENAME_MAX + 1]; int out; @@ -80,16 +76,15 @@ create_elf_file (const char *dir, int id) out = open(outfilename, O_WRONLY | O_CREAT | O_TRUNC, 0666); if(!out) { - perror("write_elf_object: can't open file"); + perror("create_mach_o_file: can't open file"); fprintf(stderr, "%s\n", outfilename); } return out; } - static int -write_elf_header(int fd) +write_mach_o_header(int fd) { extern MachO_hdr eh; @@ -162,11 +157,10 @@ write_section_data(int fd, long length, os_vm_address_t real_addr) return ewrite(fd, (void *)real_addr, length, __func__); } - int -write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t end) +write_space_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t end) { - int out = create_elf_file(dir, id); + int out = create_mach_o_file(dir, id); int ret = 0; /* The length should be a multiple of the page size. */ size_t length = end - start + (os_vm_page_size - @@ -181,7 +175,7 @@ write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t /* Make id be 0-based to match array. */ id--; - if ((write_elf_header(out) == -1) + if ((write_mach_o_header(out) == -1) || (write_load_command(out, section_names[id], length, start) == -1) || (write_section(out, length, start, section_names[id]) == -1) || (write_section_data(out, length, start) == -1)) { @@ -194,7 +188,7 @@ write_elf_object(const char *dir, int id, os_vm_address_t start, os_vm_address_t } void -elf_cleanup(const char *dirname) +obj_cleanup(const char *dirname) { char filename[FILENAME_MAX + 1]; int i; @@ -208,7 +202,7 @@ elf_cleanup(const char *dirname) } int -elf_run_linker(long init_func_address, char *file) +obj_run_linker(long init_func_address, char *file) { lispobj libstring = SymbolValue(CMUCL_LIB); /* Get library: */ struct vector *vec = (struct vector *)PTR(libstring); @@ -240,7 +234,7 @@ elf_run_linker(long init_func_address, char *file) strptr = strtok(paths, ":"); if (debug_lisp_search) { - printf("Searching for linker.sh script\n"); + printf("Searching for %s script\n", LINKER_SCRIPT); } while(strptr != NULL) { @@ -263,7 +257,7 @@ elf_run_linker(long init_func_address, char *file) (unsigned long) STATIC_SPACE_START, (unsigned long) DYNAMIC_0_SPACE_START); ret = system(command_line); - if(ret == -1) { + if (ret == -1) { perror("Can't run link script"); } else { printf("\tdone]\n"); @@ -281,16 +275,18 @@ elf_run_linker(long init_func_address, char *file) } -/* Read the ELF header from a file descriptor and stuff it into a - structure. Make sure it is really an elf header etc. */ +/* + * Read the Mach-O header from a file descriptor and stuff it into a + * structure. Make sure it is really an elf header etc. + */ static void -read_elf_header(int fd, MachO_hdr *ehp) +read_mach_o_header(int fd, MachO_hdr *ehp) { eread(fd, ehp, sizeof(MachO_hdr), __func__); if (ehp->magic != MH_MAGIC) { fprintf(stderr, - "Bad ELF magic number --- not an elf file. Exiting in %s.\n", + "Bad Mach-O magic number --- not a Mach-O file. Exiting in %s.\n", __func__); exit(-1); } @@ -298,11 +294,11 @@ read_elf_header(int fd, MachO_hdr *ehp) /* - 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. -*/ + * 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) { @@ -318,25 +314,27 @@ map_core_sections(const char *exec_name) exit(-1); } - read_elf_header(exec_fd, &eh); + read_mach_o_header(exec_fd, &eh); for (i = 0; i < eh.ncmds && sections_remaining > 0; i++) { struct load_command lc; struct segment_command sc; - /* Read the load command and see if its segname matches one of - * our section names. If it does, save the file offset for - * later so we can map the data */ + /* + * Read the load command to see what kind of command it is and + * how big it is. + */ eread(exec_fd, &lc, sizeof(lc), __func__); fprintf(stderr, "Load %d: cmd = %d, cmdsize = %d\n", i, lc.cmd, lc.cmdsize); if (lc.cmd == LC_SEGMENT) { - /* Read the segment command and save the file offset */ + /* Read the rest of the command, which is a segment command. */ fprintf(stderr, "Reading next %d bytes for SEGMENT\n", sizeof(sc) - sizeof(lc)); eread(exec_fd, &sc.segname, sizeof(sc) - sizeof(lc), __func__); fprintf(stderr, "LC_SEGMENT: name = %s\n", sc.segname); - + + /* See if the segment name matches any of our section names */ for (j = 0; j < 3; ++j) { if (strncmp(sc.segname, section_names[j], sizeof(sc.segname)) == 0) { /* Found a core segment. Map it! */ @@ -373,7 +371,7 @@ map_core_sections(const char *exec_name) break; } } - fprintf(stderr, "Reading %d remainder bytes left in command\n", + fprintf(stderr, "Skipping %d remainder bytes left in command\n", lc.cmdsize - sizeof(sc)); elseek(exec_fd, lc.cmdsize - sizeof(sc), SEEK_CUR, __func__); } else { @@ -390,4 +388,3 @@ map_core_sections(const char *exec_name) exit(-1); } } - diff --git a/lisp/save.c b/lisp/save.c index c7e66f0671cd80d0742961dfea4196b3a43f74d6..51618e74929eb43e1ad9356cd1df6638072294b2 100644 --- a/lisp/save.c +++ b/lisp/save.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/save.c,v 1.26 2010/07/30 22:51:58 rtoy Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/save.c,v 1.27 2010/07/31 00:03:23 rtoy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -28,9 +28,9 @@ #endif #ifdef FEATURE_EXECUTABLE +#include "elf.h" #if !defined(DARWIN) #include <libgen.h> -#include "elf.h" #endif #endif @@ -289,10 +289,10 @@ save_executable(char *filename, lispobj init_function) printf("\t[Writing core objects\n"); fflush(stdout); - write_elf_object(dir_name, READ_ONLY_SPACE_ID, (os_vm_address_t)read_only_space, - (os_vm_address_t)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)); - write_elf_object(dir_name, STATIC_SPACE_ID, (os_vm_address_t)static_space, - (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER)); + write_space_object(dir_name, READ_ONLY_SPACE_ID, (os_vm_address_t)read_only_space, + (os_vm_address_t)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)); + write_space_object(dir_name, STATIC_SPACE_ID, (os_vm_address_t)static_space, + (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER)); #ifdef GENCGC /* Flush the current_region updating the tables. */ #ifdef DEBUG_BAD_HEAP @@ -345,11 +345,11 @@ save_executable(char *filename, lispobj init_function) #endif #ifdef reg_ALLOC - write_elf_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space, - (os_vm_address_t)current_dynamic_space_free_pointer); + write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space, + (os_vm_address_t)current_dynamic_space_free_pointer); #else - write_elf_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space, - (os_vm_address_t)SymbolValue(ALLOCATION_POINTER)); + write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space, + (os_vm_address_t)SymbolValue(ALLOCATION_POINTER)); #endif printf("\tdone]\n"); @@ -357,9 +357,9 @@ save_executable(char *filename, lispobj init_function) printf("Linking executable...\n"); fflush(stdout); - elf_run_linker(init_function, filename); + obj_run_linker(init_function, filename); #if 0 - elf_cleanup(dir_name); + obj_cleanup(dir_name); #endif printf("done.\n"); exit(0);