|
|
1.1 ! root 1: /* VMS mapping of data and alloc arena for GNU Emacs. ! 2: Copyright (C) 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU Emacs. ! 5: ! 6: GNU Emacs is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GNU Emacs is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU Emacs; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: /* Written by Mukesh Prasad. */ ! 21: ! 22: #ifdef VMS ! 23: ! 24: #include "config.h" ! 25: #include "lisp.h" ! 26: #include <rab.h> ! 27: #include <fab.h> ! 28: #include <rmsdef.h> ! 29: #include <secdef.h> ! 30: ! 31: /* RMS block size */ ! 32: #define BLOCKSIZE 512 ! 33: ! 34: /* Maximum number of bytes to be written in one RMS write. ! 35: * Must be a multiple of BLOCKSIZE. ! 36: */ ! 37: #define MAXWRITE (BLOCKSIZE * 30) ! 38: ! 39: /* This funniness is to ensure that sdata occurs alphabetically BEFORE the ! 40: $DATA psect and that edata occurs after ALL Emacs psects. This is ! 41: because the VMS linker sorts all psects in a cluster alphabetically ! 42: during the linking, unless you use the cluster_psect command. Emacs ! 43: uses the cluster command to group all Emacs psects into one cluster; ! 44: this keeps the dumped data separate from any loaded libraries. */ ! 45: ! 46: #ifdef __GNUC__ ! 47: /* We need a large sdata array because otherwise the impure storage will end up ! 48: in low memory, and this will screw up garbage collection (Emacs will not ! 49: be able to tell the difference between a string length and an address). ! 50: This array guarantees that the impure storage is at a sufficiently high ! 51: address so that this problem will not occur. */ ! 52: char sdata[8192] asm("_$$PsectAttributes_NOOVR$$$D$ATA") ; ! 53: char edata[512] asm("_$$PsectAttributes_NOOVR$$__DATA") ; ! 54: #else ! 55: globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */ ! 56: globaldef {"__DATA"} char edata[512]; /* End of saved data area */ ! 57: #endif ! 58: ! 59: /* Structure to write into first block of map file. ! 60: */ ! 61: ! 62: struct map_data ! 63: { ! 64: char * sdata; /* Start of data area */ ! 65: char * edata; /* End of data area */ ! 66: int datablk; /* Block in file to map data area from/to */ ! 67: }; ! 68: ! 69: static void fill_fab (), fill_rab (); ! 70: static int write_data (); ! 71: ! 72: extern char *start_of_data (); ! 73: extern int vms_out_initial; /* Defined in malloc.c */ ! 74: ! 75: /* Maps in the data and alloc area from the map file. ! 76: */ ! 77: ! 78: int ! 79: mapin_data (name) ! 80: char * name; ! 81: { ! 82: struct FAB fab; ! 83: struct RAB rab; ! 84: int status, size; ! 85: int inadr[2]; ! 86: struct map_data map_data; ! 87: ! 88: ! 89: /* Open map file. */ ! 90: fab = cc$rms_fab; ! 91: fab.fab$b_fac = FAB$M_BIO|FAB$M_GET; ! 92: fab.fab$l_fna = name; ! 93: fab.fab$b_fns = strlen (name); ! 94: status = sys$open (&fab); ! 95: if (status != RMS$_NORMAL) ! 96: { ! 97: printf ("Map file not available, running bare Emacs....\n"); ! 98: return 0; /* Map file not available */ ! 99: } ! 100: /* Connect the RAB block */ ! 101: rab = cc$rms_rab; ! 102: rab.rab$l_fab = &fab; ! 103: rab.rab$b_rac = RAB$C_SEQ; ! 104: rab.rab$l_rop = RAB$M_BIO; ! 105: status = sys$connect (&rab); ! 106: if (status != RMS$_NORMAL) ! 107: lib$stop (status); ! 108: /* Read the header data */ ! 109: rab.rab$l_ubf = (char *) &map_data; ! 110: rab.rab$w_usz = sizeof (map_data); ! 111: rab.rab$l_bkt = 0; ! 112: status = sys$read (&rab); ! 113: if (status != RMS$_NORMAL) ! 114: lib$stop (status); ! 115: status = sys$close (&fab); ! 116: if (status != RMS$_NORMAL) ! 117: lib$stop (status); ! 118: if (map_data.sdata != start_of_data ()) ! 119: { ! 120: printf ("Start of data area has moved: cannot map in data.\n"); ! 121: return 0; ! 122: } ! 123: if (map_data.edata != edata) ! 124: { ! 125: printf ("End of data area has moved: cannot map in data.\n"); ! 126: return 0; ! 127: } ! 128: fab.fab$l_fop |= FAB$M_UFO; ! 129: status = sys$open (&fab); ! 130: if (status != RMS$_NORMAL) ! 131: lib$stop (status); ! 132: /* Map data area. */ ! 133: inadr[0] = (int) map_data.sdata; ! 134: inadr[1] = (int) map_data.edata; ! 135: status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0, ! 136: fab.fab$l_stv, 0, map_data.datablk, 0, 0); ! 137: if (! (status & 1)) ! 138: lib$stop (status); ! 139: } ! 140: ! 141: /* Writes the data and alloc area to the map file. ! 142: */ ! 143: mapout_data (into) ! 144: char * into; ! 145: { ! 146: struct FAB fab; ! 147: struct RAB rab; ! 148: int status; ! 149: struct map_data map_data; ! 150: int datasize, msize; ! 151: ! 152: if (vms_out_initial) ! 153: { ! 154: error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE)."); ! 155: return 0; ! 156: } ! 157: map_data.sdata = start_of_data (); ! 158: map_data.edata = edata; ! 159: datasize = map_data.edata - map_data.sdata + 1; ! 160: map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE; ! 161: /* Create map file. */ ! 162: fab = cc$rms_fab; ! 163: fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT; ! 164: fab.fab$l_fna = into; ! 165: fab.fab$b_fns = strlen (into); ! 166: fab.fab$l_fop = FAB$M_CBT; ! 167: fab.fab$b_org = FAB$C_SEQ; ! 168: fab.fab$b_rat = 0; ! 169: fab.fab$b_rfm = FAB$C_VAR; ! 170: fab.fab$l_alq = 1 + map_data.datablk + ! 171: ((datasize + BLOCKSIZE - 1) / BLOCKSIZE); ! 172: status = sys$create (&fab); ! 173: if (status != RMS$_NORMAL) ! 174: { ! 175: error ("Could not create map file"); ! 176: return 0; ! 177: } ! 178: /* Connect the RAB block */ ! 179: rab = cc$rms_rab; ! 180: rab.rab$l_fab = &fab; ! 181: rab.rab$b_rac = RAB$C_SEQ; ! 182: rab.rab$l_rop = RAB$M_BIO; ! 183: status = sys$connect (&rab); ! 184: if (status != RMS$_NORMAL) ! 185: { ! 186: error ("RMS connect to map file failed"); ! 187: return 0; ! 188: } ! 189: /* Write the header */ ! 190: rab.rab$l_rbf = (char *) &map_data; ! 191: rab.rab$w_rsz = sizeof (map_data); ! 192: status = sys$write (&rab); ! 193: if (status != RMS$_NORMAL) ! 194: { ! 195: error ("RMS write (header) to map file failed"); ! 196: return 0; ! 197: } ! 198: if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize)) ! 199: return 0; ! 200: status = sys$close (&fab); ! 201: if (status != RMS$_NORMAL) ! 202: { ! 203: error ("RMS close on map file failed"); ! 204: return 0; ! 205: } ! 206: return 1; ! 207: } ! 208: ! 209: static int ! 210: write_data (rab, firstblock, data, length) ! 211: struct RAB * rab; ! 212: char * data; ! 213: { ! 214: int status; ! 215: ! 216: rab->rab$l_bkt = firstblock; ! 217: while (length > 0) ! 218: { ! 219: rab->rab$l_rbf = data; ! 220: rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length; ! 221: status = sys$write (rab, 0, 0); ! 222: if (status != RMS$_NORMAL) ! 223: { ! 224: error ("RMS write to map file failed"); ! 225: return 0; ! 226: } ! 227: data = &data[MAXWRITE]; ! 228: length -= MAXWRITE; ! 229: rab->rab$l_bkt = 0; ! 230: } ! 231: return 1; ! 232: } /* write_data */ ! 233: ! 234: #endif /* VMS */ ! 235:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.