doc: Add serial to list of ci file reserved words
[charm.git] / src / conv-core / global-macho.C
1 /*  File: global-mach.C
2  *  Author: Isaac Dooley
3  *  
4  *  This file is not yet fully functional. The makefile is not aware of it
5  *  yet, but it is included if we decide to complete this functionality for
6  *  the Mach-O executable format and loader.
7  *
8  *  This code currently can swap in and out entire DATA segments as required,
9  *  but it needs some way of identifying the Cpv_* variables which should not
10  *  be swapped. Unfortunately there is no Global Offset Table as there is with
11  *  ELF, so we cannot just scan the variables and build our own table.
12  *
13  *  The PUP functions must also be written.
14  *  
15  */
16
17 #include "converse.h"
18 #include "cklists.h"
19 #include <string.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <strings.h>
23 #include <errno.h>
24 #include <assert.h>
25
26 #include "converse.h"
27 #include "pup.h"
28
29
30 #if CMK_HAS_MACHO_GETSECT_H
31
32
33 /* problems:
34  * the Cpv_mapCreated_[_Cmi_myrank] apparently gets unset after one call to install
35  * I'm not sure what is going on with it. Can I copy the entire DATA segment?
36  */
37
38
39 #include <mach-o/getsect.h>
40
41 /* A global magic cookie to make sure no routine swaps in some completely wrong DATA SEGMENT */
42 /* A check like this may be used also to verify that the segement is correctly manipulated */
43 long magic_num_machoassert = 0x0123456;
44 #define CHECK_MAGIC_NUM {assert(magic_num_machoassert == 0x0123456);printf("_origCtg=%p\n", _origCtg);}
45
46
47 /****************** Global Variable Storage and Swapping *********************/
48 CpvStaticDeclare(CtgGlobals,_curCtg);
49 CtgGlobals _origCtg; // should probably be registered like the others, but I couldn't get it to work, somehow it would be undefined in the first call to Install(g=0x0);
50
51 struct CtgGlobalStruct {
52 public:
53     int installed;
54     
55     void *data_seg;  /* The user copy of the data */
56     int seg_size; /* size in bytes of data segment */
57     
58     void allocate(int size) {
59         printf("CtgGlobalStruct::allocate()\n");
60         CHECK_MAGIC_NUM;
61         assert(!data_seg);
62         seg_size=size;
63         data_seg=malloc(seg_size);
64         CHECK_MAGIC_NUM;
65     }
66     
67     CtgGlobalStruct(void) {
68         printf("CtgGlobalStruct::constructor\n");
69         CHECK_MAGIC_NUM;
70         installed=0;
71         data_seg=0;
72         CHECK_MAGIC_NUM;
73     }
74     ~CtgGlobalStruct() {
75         printf("CtgGlobalStruct::destructor\n");
76         if (data_seg) {
77             CHECK_MAGIC_NUM;
78             free(data_seg);
79             CHECK_MAGIC_NUM;
80         }
81     }
82     
83     void pup(PUP::er &p);
84 };
85
86 void CtgGlobalStruct::pup(PUP::er &p) {
87     assert(0);
88     //    p | seg_size;
89     //if (p.isUnpacking()) allocate(seg_size);
90     //p(data_seg, seg_size);
91 }
92
93
94 /** Initialize the globals support (called on each processor). */
95 void CtgInit(void) {
96         CHECK_MAGIC_NUM;
97   
98     CmiPrintf("CtgInit()\n");
99     
100     if (CmiMyNode()==0) {
101         CmiPrintf("CHARM> -swapglobals enabled, but not yet finished for Mach-O\n");
102     }
103     
104     const struct segment_command *seg = getsegbyname("__DATA");
105     _origCtg = new CtgGlobalStruct;
106     _origCtg->allocate(seg->vmsize);
107     CHECK_MAGIC_NUM;
108     assert(_origCtg->data_seg);
109     memcpy(_origCtg->data_seg, (void *)seg->vmaddr, seg->vmsize);
110     CHECK_MAGIC_NUM;
111     CmiPrintf("_origCtg initialized\n");
112     assert(_origCtg);
113     CHECK_MAGIC_NUM;
114     
115     CtgGlobals cur = new CtgGlobalStruct;
116     cur->allocate(seg->vmsize);
117     CHECK_MAGIC_NUM;
118     assert(cur);
119     assert(cur->data_seg);
120     memcpy(cur->data_seg, (void *)seg->vmaddr, seg->vmsize);
121     CHECK_MAGIC_NUM;
122     CpvAccess(_curCtg) = cur;
123     assert(CpvAccess(_curCtg));
124     assert(CpvAccess(_curCtg)->data_seg);
125     assert(CpvAccess(_curCtg)->data_seg == cur->data_seg);
126     
127     CmiPrintf("_curCtg initialized\n");
128
129 }
130
131 /** Copy the current globals into this new set */
132 CtgGlobals CtgCreate(CthThread tid) {
133         CtgGlobalStruct *g=new CtgGlobalStruct;
134     const struct segment_command *seg = getsegbyname("__DATA");
135     CHECK_MAGIC_NUM;
136     printf("CtgCreate()\n");
137     assert(seg);
138         g->allocate(seg->vmsize);
139     CHECK_MAGIC_NUM;
140     memcpy(g->data_seg, (void *)seg->vmaddr, seg->vmsize);
141     CHECK_MAGIC_NUM;
142     return g;
143 }
144
145 /** PUP this (not currently installed) globals set */
146 CtgGlobals CtgPup(pup_er pv, CtgGlobals g) {
147     assert(0);
148
149 //      PUP::er *p=(PUP::er *)pv;
150 //      if (p->isUnpacking()) g=new CtgGlobalStruct;
151 //      if (g->installed) 
152 //              CmiAbort("CtgPup called on currently installed globals!\n");
153 //      g->pup(*p);
154 //      if (g->seg_size!=_ctgList->getSize())
155 //              CmiAbort("CtgPup: global variable size changed during migration!\n");
156         return g;
157 }
158
159 /** Install this set of globals. If g==NULL, returns to original globals. */
160 void CtgInstall(CtgGlobals g) {
161     CtgGlobals g_install;
162     printf("CtgInstall()\n");
163     CHECK_MAGIC_NUM;
164
165     if(g){
166         g_install = g; // install globals passed in as parameter
167         printf("installing g=%p\n", g_install);
168     }
169     else{
170         g_install = _origCtg; // install original globals
171         printf("installing original g=%p\n", g_install);
172     }
173
174     assert(g_install);
175     
176     CtgGlobals g_old = CtgCurrentGlobals();
177     const struct segment_command *seg = getsegbyname("__DATA");
178     assert(seg);
179     CHECK_MAGIC_NUM;
180
181     // First must uninstall the old data segment, if one is loaded
182     if(g_old){
183         memcpy(g_old->data_seg, (void *)seg->vmaddr, seg->vmsize);
184     }
185     else {
186         printf("no current data segment to copy out into\n");
187     }
188     
189     // Install the new data segment
190     memcpy((void *)seg->vmaddr, g_install->data_seg, seg->vmsize);
191     CpvAccess(_curCtg) = g_install;
192     CHECK_MAGIC_NUM;
193
194 }
195
196
197 /** Delete this (not currently installed) set of globals. */
198 void CtgFree(CtgGlobals g) {
199         if (g->installed) CmiAbort("CtgFree called on currently installed globals!\n");
200         delete g;
201     CHECK_MAGIC_NUM;
202 }
203
204
205 CtgGlobals CtgCurrentGlobals(void){
206     CHECK_MAGIC_NUM;
207         return CpvAccess(_curCtg);
208 }
209
210 #else
211
212 #include "global-nop.c"
213
214 #endif
215