/[gcl]/gcl/o/unexmacosx.c
ViewVC logotype

Diff of /gcl/o/unexmacosx.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by rlbk, Thu Oct 16 17:13:09 2003 UTC revision 1.6 by rlbk, Thu Nov 13 20:33:20 2003 UTC
# Line 18  along with GNU Emacs; see the file COPYI Line 18  along with GNU Emacs; see the file COPYI
18  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  Boston, MA 02111-1307, USA.  */  Boston, MA 02111-1307, USA.  */
20    
21    /*
22    
23    This file is part of GNU Common Lisp, herein referred to as GCL
24    
25    GCL is free software; you can redistribute it and/or modify it under
26    the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
27    the Free Software Foundation; either version 2, or (at your option)
28    any later version.
29    
30    GCL is distributed in the hope that it will be useful, but WITHOUT
31    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
33    License for more details.
34    
35    You should have received a copy of the GNU Library General Public License
36    along with GCL; see the file COPYING.  If not, write to the Free Software
37    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
38    
39    */
40    
41  /* Contributed by Andrew Choi (akochoi@mac.com).  */  /* Contributed by Andrew Choi (akochoi@mac.com).  */
42    
43  /* Documentation note.  /* Documentation note.
# Line 95  Boston, MA 02111-1307, USA.  */ Line 115  Boston, MA 02111-1307, USA.  */
115  #include <sys/types.h>  #include <sys/types.h>
116  #include <unistd.h>  #include <unistd.h>
117  #include <mach/mach.h>  #include <mach/mach.h>
118    #include <mach/mach_error.h>
119  #include <mach-o/loader.h>  #include <mach-o/loader.h>
120    #include <mach-o/nlist.h>
121  #include <objc/malloc.h>  #include <objc/malloc.h>
122    
123  #include <sys/mman.h>  #include <sys/mman.h>
# Line 111  Boston, MA 02111-1307, USA.  */ Line 133  Boston, MA 02111-1307, USA.  */
133  #define VM_DATA_TOP (20 * 1024 * 1024)  #define VM_DATA_TOP (20 * 1024 * 1024)
134    
135  /* Used by malloc_freezedry and malloc_jumpstart.  */  /* Used by malloc_freezedry and malloc_jumpstart.  */
136  int malloc_cookie;  extern int malloc_cookie;
137    
138  /* Type of an element on the list of regions to be dumped.  */  /* Type of an element on the list of regions to be dumped.  */
139  struct region_t {  struct region_t {
# Line 162  int in_dumped_exec = 0; Line 184  int in_dumped_exec = 0;
184    
185  malloc_zone_t *gcl_zone = 0L;  malloc_zone_t *gcl_zone = 0L;
186    
187  unsigned num_marked_regions;  #define MAX_MARKED_REGIONS 1024
188    
189  #include <mach/mach_error.h>  vm_range_t marked_regions [MAX_MARKED_REGIONS];
 #include <mach-o/nlist.h>  
190    
191  #ifndef BIG_HEAP_SIZE  unsigned num_marked_regions;
192  #define BIG_HEAP_SIZE   0x50000000  
193  #endif  /* Size of the heap.  */
194    int big_heap = BIG_HEAP_SIZE;
195    
196  int     big_heap = BIG_HEAP_SIZE;  /* Start of the heap.  */
197    char *mach_mapstart = 0;
198    
199  char    *mach_maplimit = 0;  /* End of the heap.  */
200  char    *mach_brkpt = 0;  char *mach_maplimit = 0;
 char    *mach_mapstart = 0;  
201    
202    /* Position ot the break within the heap.  */
203    char *mach_brkpt = 0;
204    
205  /* Read n bytes from infd into memory starting at address dest.  /* Read n bytes from infd into memory starting at address dest.
206     Return true if successful, false otherwise.  */     Return true if successful, false otherwise.  */
# Line 908  dump_it () Line 932  dump_it ()
932      unexec_error ("cannot write final header contents");      unexec_error ("cannot write final header contents");
933  }  }
934    
935  #define MAX_MARKED_REGIONS 1024  /* Mark a range of virtual memory to be dumped upon unexec()'ing.  */
   
 vm_range_t marked_regions[MAX_MARKED_REGIONS];  
936    
937  void  void
938  mark_region (unsigned long address, unsigned long size)  mark_region (unsigned long address, unsigned long size)
939  {  {
940      if (num_marked_regions < MAX_MARKED_REGIONS)      if (num_marked_regions < MAX_MARKED_REGIONS)
941      {      {
942          marked_regions[num_marked_regions].address = address;        marked_regions[num_marked_regions].address = address;
943          marked_regions[num_marked_regions].size = size;        marked_regions[num_marked_regions].size = size;
944            
945          num_marked_regions++;        num_marked_regions++;
946      }      }
947      else {      else {
948          printf ("warning: too many marked regions\n");        fprintf (stderr, "warning: too many marked regions\n");
949          fflush (stderr);
950      }      }
951  }  }
952    
# Line 948  void Line 971  void
971  unexec (char *outfile, char *infile, void *start_data, void *start_bss,  unexec (char *outfile, char *infile, void *start_data, void *start_bss,
972          void *entry_address)          void *entry_address)
973  {  {
 /*extern malloc_zone_t *debug_zone __attribute__((weak_import));*/  
     
974    infd = open (infile, O_RDONLY, 0);    infd = open (infile, O_RDONLY, 0);
975    if (infd < 0)    if (infd < 0)
976      {      {
# Line 978  unexec (char *outfile, char *infile, voi Line 999  unexec (char *outfile, char *infile, voi
999  /*find_gcl_zone_regions ();*/  /*find_gcl_zone_regions ();*/
1000    add_marked_regions ();    add_marked_regions ();
1001        
   /*  
   if (debug_zone != NULL)  
   debug_zone->introspect->enumerator (mach_task_self(), 0,  
                                       MALLOC_PTR_REGION_RANGE_TYPE  
                                       | MALLOC_ADMIN_REGION_RANGE_TYPE,  
                                       (vm_address_t) debug_zone,  
                                       unexec_reader,  
                                       unexec_regions_recorder);  
   */  
     
1002    in_dumped_exec = 1;    in_dumped_exec = 1;
1003    
1004    dump_it ();    dump_it ();
# Line 1038  static void stub_free (malloc_zone_t *zo Line 1049  static void stub_free (malloc_zone_t *zo
1049      my_free (ptr);      my_free (ptr);
1050  }  }
1051    
1052    /* Create a new zone to accommodate GCL's heap and make it the default zone.  */
1053    
1054  void init_darwin_zone_compat ()  void init_darwin_zone_compat ()
1055  {  {
1056      extern unsigned malloc_num_zones;    extern unsigned malloc_num_zones;
1057      malloc_zone_t *default_zone;    extern malloc_zone_t **malloc_zones;
1058              unsigned malloc_num_zones_copy;
1059      default_zone = malloc_default_zone ();    malloc_zone_t **malloc_zones_copy;
1060          malloc_zone_t *default_zone;
1061      gcl_zone = malloc_create_zone (0,0);    kern_return_t rtn;
1062          vm_size_t s;
1063      gcl_zone->size       = (void *) stub_size;    unsigned i;
1064      gcl_zone->malloc     = (void *) stub_malloc;  
1065      gcl_zone->calloc     = (void *) stub_calloc;    default_zone = malloc_default_zone ();
1066      gcl_zone->valloc     = (void *) stub_valloc;    
1067      gcl_zone->realloc    = (void *) stub_realloc;    if ((gcl_zone = malloc_create_zone (0,0)) == NULL) {
1068      gcl_zone->free       = (void *) stub_free;      fprintf (stderr, "init_darwin_zone_compat(): malloc_create_zone() failed\n");
1069   /* if the zone introspector is ever called, the program will crash */      exit (1);
1070          }
  /* we could support any number of zones, but I'm being lazy */  
     assert (malloc_num_zones <= 2);  
1071            
1072      if (default_zone)    gcl_zone->size       = (void *) stub_size;
1073      {    gcl_zone->malloc     = (void *) stub_malloc;
1074          malloc_zone_unregister (default_zone);    gcl_zone->calloc     = (void *) stub_calloc;
1075          malloc_zone_unregister (gcl_zone);    gcl_zone->valloc     = (void *) stub_valloc;
1076                  gcl_zone->realloc    = (void *) stub_realloc;
1077          malloc_zone_register (gcl_zone);    gcl_zone->free       = (void *) stub_free;
1078          malloc_zone_register (default_zone);  
1079      }    /* Maybe we'll want to implement the zone introspector some day.  */
1080            
1081      malloc_set_zone_name (gcl_zone, "GNU Common Lisp");    malloc_num_zones_copy = malloc_num_zones;
1082      s = malloc_num_zones * sizeof (malloc_zone_t *);
1083      
1084      if ((rtn = vm_allocate (mach_task_self (), (vm_address_t *) &malloc_zones_copy, s, 1)) != KERN_SUCCESS) {
1085        mach_error ("init_darwin_zone_compat(): vm_allocate() failed", rtn);
1086        exit (1);
1087      }
1088    
1089      memcpy (malloc_zones_copy, malloc_zones, s);
1090    
1091      for (i=0 ; i < malloc_num_zones_copy ; i++) {
1092        malloc_zone_unregister (malloc_zones_copy [i]);
1093      }
1094    
1095      /* Make our zone the default zone.  */
1096      malloc_zone_register (gcl_zone);
1097      
1098      for (i=0 ; i < malloc_num_zones_copy ; i++) {
1099        if (malloc_zones_copy [i] != gcl_zone)
1100          malloc_zone_register (malloc_zones_copy [i]);
1101      }
1102    
1103      vm_deallocate (mach_task_self (), (vm_address_t) malloc_zones_copy, s);
1104      
1105      malloc_set_zone_name (gcl_zone, "GNU Common Lisp");
1106  }  }
1107    
1108    /* Replacement for broken sbrk(2).  */
1109    
1110  char *my_sbrk (int incr)  char *my_sbrk (int incr)
1111  {  {
1112      char               *temp, *ptr;      char               *temp, *ptr;
1113      kern_return_t       rtn;      kern_return_t       rtn;
1114            
1115      if (mach_brkpt == 0) {      if (mach_brkpt == 0) {
1116         if ((rtn = vm_allocate(mach_task_self(), (vm_address_t *) &mach_brkpt, big_heap, 1)) != KERN_SUCCESS) {         if ((rtn = vm_allocate (mach_task_self (), (vm_address_t *) &mach_brkpt, big_heap, 1)) != KERN_SUCCESS) {
1117              mach_error ("my_sbrk(): vm_allocate() failed", rtn);              mach_error ("my_sbrk(): vm_allocate() failed", rtn);
1118              return ((char *)-1);              return ((char *)-1);
1119          }          }
1120          if (!mach_brkpt) {          if (!mach_brkpt) {
1121           /* FIX-ME: this fprintf call will most probably fail because memory isn't initialized */           /* Call this instead of fprintf() because no allocation is performed.  */
1122              fprintf (stderr, "my_sbrk(): cannot allocate heap\n");              malloc_printf ("my_sbrk(): cannot allocate heap\n");
1123              return ((char *)-1);                      return ((char *)-1);        
1124          }          }
1125          mark_region ((unsigned long) mach_brkpt, (unsigned long) big_heap);          mark_region ((unsigned long) mach_brkpt, (unsigned long) big_heap);
# Line 1099  char *my_sbrk (int incr) Line 1136  char *my_sbrk (int incr)
1136              mach_brkpt = ptr;              mach_brkpt = ptr;
1137              return (temp);              return (temp);
1138          } else {          } else {
1139              fprintf (stderr, "my_sbrk(): no more memory\n");              malloc_printf ("my_sbrk(): no more memory\n");
             fflush (stderr);  
1140              return ((char *)-1);              return ((char *)-1);
1141          }          }
1142      }      }
1143  }  }
1144    
1145    /* The file has non Mach-O stuff appended.  We need to now where the Mach-O stuff ends.
1146       Put this here, although it pertains to fasload()'ing, because we'll stop using sfaslmacosx.c.  */
1147    
1148    int seek_to_end_ofile (FILE *fp)
1149    {
1150        struct mach_header mach_header;
1151        char *hdrbuf;
1152        struct load_command *load_command;
1153        struct segment_command *segment_command;
1154        struct section *section;
1155        struct symtab_command *symtab_command;
1156        struct symseg_command *symseg_command;
1157        int len, cmd, seg;
1158        int end_sec, end_ofile;
1159        
1160        end_ofile = 0;
1161        fseek(fp, 0L, 0);
1162        len = fread((char *)&mach_header, sizeof(struct mach_header), 1, fp);
1163        if (len == 1 && mach_header.magic == MH_MAGIC) {
1164            hdrbuf = (char *)malloc(mach_header.sizeofcmds);
1165            len = fread(hdrbuf, mach_header.sizeofcmds, 1, fp);
1166            if (len != 1) {
1167                fprintf(stderr, "seek_to_end_ofile(): failure reading Mach-O load commands\n");
1168                return 0;
1169            }
1170            load_command = (struct load_command *) hdrbuf;
1171            for (cmd = 0; cmd < mach_header.ncmds; ++cmd) {
1172                switch (load_command->cmd) {
1173                case LC_SEGMENT:
1174                    segment_command = (struct segment_command *) load_command;
1175                    section = (struct section *) ((char *)(segment_command + 1));
1176                    for (seg = 0; seg < segment_command->nsects; ++seg, ++section) {
1177                        end_sec = section->offset + section->size;
1178                        if (end_sec > end_ofile)
1179                            end_ofile = end_sec;
1180                    }
1181                    break;
1182                case LC_SYMTAB:
1183                    symtab_command = (struct symtab_command *) load_command;
1184                    end_sec = symtab_command->symoff + symtab_command->nsyms * sizeof(struct nlist);
1185                    if (end_sec > end_ofile)
1186                        end_ofile = end_sec;
1187                    end_sec = symtab_command->stroff + symtab_command->strsize;
1188                    if (end_sec > end_ofile)
1189                        end_ofile = end_sec;
1190                    break;
1191                case LC_SYMSEG:
1192                    symseg_command = (struct symseg_command *) load_command;
1193                    end_sec = symseg_command->offset + symseg_command->size;
1194                    if (end_sec > end_ofile)
1195                        end_ofile = end_sec;
1196                    break;
1197                }
1198                load_command = (struct load_command *)
1199                  ((char *)load_command + load_command->cmdsize);
1200            }
1201            free(hdrbuf);
1202            fseek(fp, end_ofile, 0);
1203            return 1;
1204        }
1205        return 0;
1206    }
1207    
1208  #ifdef UNIXSAVE  #ifdef UNIXSAVE
1209  #include "save.c"  #include "save.c"
1210  #endif  #endif

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26