Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / rpcMgr.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "common/h/headers.h"
33 #include "dyninstAPI/src/dyn_lwp.h"
34 #include "dyninstAPI/src/dyn_thread.h"
35 #include "dyninstAPI/src/instP.h" // initTramps
36 #include "dyninstAPI/src/baseTramp.h" // irpc code
37 #include "dyninstAPI/src/process.h"
38 #include "common/h/stats.h"
39 #include "dyninstAPI/src/debug.h"
40 #include "dyninstAPI/src/ast.h"
41 #include "dyninstAPI/src/rpcMgr.h"
42 #include "dyninstAPI/src/signalgenerator.h"
43 #include "dyninstAPI/src/registerSpace.h"
44
45 #if defined(arch_x86_64)
46 #include "dyninstAPI/src/emit-x86.h"
47 #endif
48 #ifndef CASE_RETURN_STR
49 #define CASE_RETURN_STR(x) case x: return #x
50 #endif
51 const char *irpcState2Str(irpcState_t s)
52 {
53         switch (s) {
54                 CASE_RETURN_STR(irpcNotValid);
55                 CASE_RETURN_STR(irpcNotRunning);
56                 CASE_RETURN_STR(irpcRunning);
57                 CASE_RETURN_STR(irpcWaitingForSignal);
58                 CASE_RETURN_STR(irpcNotReadyForIRPC);
59         };
60         return "bad_rpc_state";
61 }
62
63
64 rpcMgr::rpcMgr(process *proc) :
65     processingProcessRPC(false),
66     proc_(proc),
67     lwps_(rpcLwpHash),
68     recursionGuard(false)
69 {
70     // We use a base tramp skeleton to generate iRPCs.
71     irpcTramp = new baseTramp(NULL, callUnset);
72     irpcTramp->rpcMgr_ = this;
73     irpcTramp->setRecursive(true);
74 }
75
76 // Fork constructor. For each thread/LWP in the parent, check to 
77 // see if it still exists, and if so copy over all state. Also 
78 // copy all current RPC state. Oy.
79 rpcMgr::rpcMgr(rpcMgr *pRM, process *child) :
80     processingProcessRPC(pRM->processingProcessRPC),
81     proc_(child),
82     lwps_(rpcLwpHash),
83     recursionGuard(pRM->recursionGuard)
84 {
85     // We use a base tramp skeleton to generate iRPCs.
86     irpcTramp = new baseTramp(NULL, callUnset);
87     irpcTramp->rpcMgr_ = this;
88     irpcTramp->setRecursive(true);
89
90     // Make all necessary thread and LWP managelets.
91
92     for (unsigned i = 0; i < pRM->thrs_.size(); i++) {
93       if (pRM->thrs_[i]) {
94         dynthread_t tid = pRM->thrs_[i]->thr_->get_tid();
95         dyn_thread *cthr = child->getThread(tid);
96         if (!cthr) continue; // Whee, not there any more. 
97         rpcThr *newT = new rpcThr(pRM->thrs_[i],
98                                   this,
99                                   cthr);
100         thrs_.push_back(newT);
101       }
102       else {
103           thrs_.push_back(NULL); // Can happen if indices were skipped
104       }
105     }
106
107     // Check LWPS
108     dictionary_hash_iter<unsigned, rpcLWP *> lwp_iter = pRM->lwps_.begin();
109     for (; lwp_iter; lwp_iter++) {
110         unsigned lwp_id = lwp_iter.currkey();
111
112         // This doesn't handle the case if the LWP ID changed (linux PID)
113         // but I'm _really_ not worried about this.
114
115         dyn_lwp *clwp = child->lookupLWP(lwp_id);
116         if (!clwp) {
117             continue;
118         }
119         rpcLWP *newL = new rpcLWP(lwp_iter.currval(),
120                                   this,
121                                   clwp);
122         lwps_[lwp_id] = newL;
123     }
124
125     // Okay, we have those... we need to build:
126     // allPostedRPCs_;
127     // postedProcessRPCs_;
128     // allRunningRPCs_;
129     // allPendingRPCs_;
130
131     // allPosted is built from thr+lwp+proc, and thr/lwp already built internally;
132     // but we create it so that we get ordering right. 
133     // postedProcess we create
134     // allRunning already done;
135     // allPending already done.
136         
137     for (unsigned ii = 0; ii < pRM->postedProcessRPCs_.size(); ii++) {
138         inferiorRPCtoDo *newRPC = new inferiorRPCtoDo;
139         inferiorRPCtoDo *oldRPC = pRM->postedProcessRPCs_[ii];
140         
141         newRPC->action = oldRPC->action;
142         newRPC->noCost = oldRPC->noCost;
143         newRPC->callbackFunc = oldRPC->callbackFunc;
144         newRPC->userData = oldRPC->userData;
145         newRPC->lowmem = oldRPC->lowmem;
146         newRPC->id = oldRPC->id;
147         assert(!oldRPC->thr); // It's a process RPC
148         assert(!oldRPC->lwp);
149         postedProcessRPCs_.push_back(newRPC);
150     }
151
152     // This is horridly inefficient
153     for (unsigned iii = 0; iii < pRM->allPostedRPCs_.size(); iii++) {
154         inferiorRPCtoDo *oldRPC = pRM->postedProcessRPCs_[iii];
155         bool found = false;
156         if (oldRPC->thr) {
157             dynthread_t tid = oldRPC->thr->get_tid();
158             for (unsigned j = 0; j < thrs_.size(); j++) {
159               if (thrs_[j] == NULL) continue;
160                 if (thrs_[j]->thr_->get_tid() == tid) {
161                     rpcThr *thr = thrs_[j];
162                     // Now find the matching (ID) RPC
163                     for (unsigned k = 0; k < thr->postedRPCs_.size(); k++)
164                         if (thr->postedRPCs_[k]->id == oldRPC->id) {
165                             found = true;
166                             allPostedRPCs_.push_back(thr->postedRPCs_[k]);
167                             break;
168                         }
169
170                 }
171                 if (found) break;
172             }
173         }
174         else if (oldRPC->lwp) {
175             unsigned lid = oldRPC->lwp->get_lwp_id();
176             rpcLWP *lwp = lwps_[lid];
177             assert(lwp);
178             // Now find the matching (ID) RPC
179             for (unsigned k = 0; k < lwp->postedRPCs_.size(); k++) {
180                 if (lwp->postedRPCs_[k]->id == oldRPC->id) {
181                     found = true;
182                     allPostedRPCs_.push_back(lwp->postedRPCs_[k]);
183                     break;
184                 }
185             }
186         }
187         else {
188             for (unsigned i = 0; i < postedProcessRPCs_.size(); i++) {
189                 if (postedProcessRPCs_[i]->id == oldRPC->id) {
190                     found = true;
191                     allPostedRPCs_.push_back(postedProcessRPCs_[i]);
192                     break;
193                 }
194             }
195         }
196         assert(found);
197     }
198 }
199     
200 rpcMgr::~rpcMgr() {
201     delete irpcTramp;
202 }
203
204 // post RPC toDo for process
205 unsigned rpcMgr::postRPCtoDo(AstNodePtr action, bool noCost,
206                              inferiorRPCcallbackFunc callbackFunc,
207                              void *userData, 
208                              bool runWhenFinished,
209                              bool lowmem,
210                              dyn_thread *thr, dyn_lwp *lwp)
211 {
212     static int sequence_num = 0;
213     process *proc = NULL;
214     // posts an RPC, but does NOT make any effort to launch it.
215     inferiorRPCtoDo *theStruct = new inferiorRPCtoDo;
216     theStruct->action = action;
217     theStruct->noCost = noCost;
218     theStruct->callbackFunc = callbackFunc;
219     theStruct->userData = userData;
220     theStruct->lowmem = lowmem;
221     theStruct->id = sequence_num++;
222     theStruct->thr = thr;
223     theStruct->lwp = lwp;
224     theStruct->runProcessWhenDone = runWhenFinished;
225     if (thr)
226        proc = thr->get_proc();
227     else if (lwp)
228        proc = lwp->proc();
229     theStruct->saveFPState = proc ? proc->shouldSaveFPState() : true;
230  
231     if (thr) {
232        int index = thr->get_index();
233        rpcThr *rpc_thr = thrs_[index];
234        assert(rpc_thr != NULL);
235        rpc_thr->postIRPC(theStruct);
236     }
237     else if (lwp) {
238        int index = lwp->get_lwp_id();
239        rpcLWP *rpc_lwp;
240        bool foundIt = lwps_.find(index, rpc_lwp);
241        assert(foundIt == true);
242        rpc_lwp->postIRPC(theStruct);
243     }
244     else {
245        postedProcessRPCs_.push_back(theStruct);
246     }
247     
248     // Stick it in the global listing as well
249     allPostedRPCs_.push_back(theStruct);
250
251     inferiorrpc_printf("%s[%d]: Posting new RPC: seq %d, thr %u, lwp %d\n", FILE__, __LINE__, theStruct->id,
252                        thr ? thr->get_tid() : 0,
253                        lwp ? (int) lwp->get_lwp_id() : -1);
254
255     return theStruct->id;
256 }
257
258 inferiorRPCtoDo *rpcMgr::getProcessRPC() {
259     if (postedProcessRPCs_.size() == 0) return NULL;
260
261     inferiorRPCtoDo *rpc = postedProcessRPCs_[0];
262
263     VECTOR_ERASE(postedProcessRPCs_,0,0);
264     return rpc;
265 }
266
267 #if defined(RPC_SHOWSTATE)  // def is ifdefed out since not normally used
268 void rpcMgr::showState() const {
269    cerr << "   there are " << allRunningRPCs_.size() << " running rpcs\n";
270    for (unsigned i = 0; i < allRunningRPCs_.size(); i++) {
271       Frame activeFrame;
272       inferiorRPCinProgress *currRPC = allRunningRPCs_[i];
273       
274       rpcThr *rpcThr = currRPC->rpcthr;
275       rpcLWP *rpcLwp = currRPC->rpclwp;
276       struct inferiorRPCtoDo *rpc = currRPC->rpc;
277
278        if(rpcThr) {
279           cerr << "     [" << i << "] id: " << rpc->id << ", lwp: "
280                << rpcThr->get_thr()->get_lwp()->get_lwp_id()
281                << ", state: ";
282           switch(currRPC->state) {
283             case irpcNotValid:  cerr << "irpcNotValid";  break;
284             case irpcNotRunning:  cerr << "irpcNotRunning";  break;
285             case irpcRunning:  cerr << "irpcRunning";  break;
286             case irpcWaitingForSignal:  cerr << "irpcWaitingForSignal"; break;
287             case irpcNotReadyForIRPC:  cerr << "irpcNotReadyForIRPC";  break;
288           }
289           cerr << endl;
290        } else {
291           assert(rpcLwp != NULL);
292           cerr << "     [" << i << "] id: " << rpc->id << ", an lwp rpc\n";
293        }
294    }
295 }
296 #endif
297
298 bool rpcMgr::existsActiveIRPC() const {
299     for (unsigned i = 0; i < thrs_.size(); i++) {
300        if (thrs_[i] == NULL) continue;
301        if (thrs_[i]->isRunningIRPC()) {
302           inferiorrpc_printf("%s[%d]: active IRPC on thread %d (slot %d), ret true\n",
303                              FILE__, __LINE__, thrs_[i]->thr_->get_tid(), i);
304           return true;
305        }
306     }
307     dictionary_hash<unsigned, rpcLWP *>::iterator rpc_iter = lwps_.begin();
308     while(rpc_iter != lwps_.end()) {
309         if ((*rpc_iter)->isRunningIRPC()) {
310             inferiorrpc_printf("%s[%d]: active IRPC on lwp %d, ret true\n",
311                                FILE__, __LINE__, (*rpc_iter)->lwp_->get_lwp_id());
312             return true;
313         }
314         rpc_iter++;
315     }
316     inferiorrpc_printf("%s[%d]: No active IRPC\n", FILE__, __LINE__);
317     return false;
318 }
319
320 bool rpcMgr::existsPendingIRPC() const {
321     for (unsigned i = 0; i < thrs_.size(); i++) {
322       if (thrs_[i] == NULL) continue;
323         if (thrs_[i]->isWaitingForBreakpoint()) {
324             inferiorrpc_printf("%s[%d]: thread %d (slot %d) waiting for breakpoint, ret true\n",
325                                FILE__, __LINE__, thrs_[i]->thr_->get_tid(), i);
326             return true;
327         }
328     }
329     dictionary_hash<unsigned, rpcLWP *>::iterator rpc_iter = lwps_.begin();
330     while(rpc_iter != lwps_.end()) {
331         if ((*rpc_iter)->isWaitingForBreakpoint()) {
332             inferiorrpc_printf("%s[%d]: pending IRPC on lwp %d, ret true\n",
333                                FILE__, __LINE__, (*rpc_iter)->lwp_->get_lwp_id());
334             return true;
335         }
336         rpc_iter++;
337     }
338     inferiorrpc_printf("%s[%d]: No pending IRPC\n", FILE__, __LINE__);
339     return false;
340 }
341
342 bool rpcMgr::existsWaitingIRPC() const {
343     for (unsigned i = 0; i < thrs_.size(); i++) {
344       if (thrs_[i] == NULL) continue;
345         if (thrs_[i]->isReadyForIRPC()) {
346             inferiorrpc_printf("%s[%d]: thread %d (slot %d) has ready RPC, ret true\n",
347                                FILE__, __LINE__, thrs_[i]->thr_->get_tid(), i);
348             return true;
349         }
350     }
351     dictionary_hash<unsigned, rpcLWP *>::iterator rpc_iter = lwps_.begin();
352     while(rpc_iter != lwps_.end()) {
353         if ((*rpc_iter)->isReadyForIRPC()) {
354             inferiorrpc_printf("%s[%d]: ready IRPC on lwp %d, ret true\n",
355                                FILE__, __LINE__, (*rpc_iter)->lwp_->get_lwp_id());
356             return true;
357         }
358         rpc_iter++;
359     }
360     inferiorrpc_printf("%s[%d]: No ready IRPC\n", FILE__, __LINE__);
361     return false;
362 }
363
364 inferiorRPCinProgress *rpcMgr::findRunningRPCWithResultAddress(Address where)
365 {
366   inferiorRPCinProgress *ret = NULL;
367   inferiorrpc_printf("%s[%d]: %d running RPCs\n", FILE__, __LINE__, allRunningRPCs_.size());
368   for (int i = allRunningRPCs_.size() -1; i >= 0; --i) {
369       inferiorrpc_printf("%s[%d]: comparing curr addr 0x%lx to RPC result addr 0x%lx\n",
370                          FILE__, __LINE__, where, allRunningRPCs_[i]->rpcResultAddr); 
371       if (allRunningRPCs_[i]->rpcResultAddr == where) {
372           ret = allRunningRPCs_[i];
373           break;
374       }
375   }
376   return ret;
377 }
378
379 inferiorRPCinProgress *rpcMgr::findRunningRPCWithCompletionAddress(Address where)
380 {
381   inferiorRPCinProgress *ret = NULL;
382   inferiorrpc_printf("%s[%d]: %d running RPCs\n", FILE__, __LINE__, allRunningRPCs_.size());
383   for (int i = allRunningRPCs_.size() -1; i >= 0; --i) {
384       inferiorrpc_printf("%s[%d]: comparing curr addr 0x%lx to RPC completion addr 0x%lx\n",
385                          FILE__, __LINE__, where, allRunningRPCs_[i]->rpcCompletionAddr); 
386       if (allRunningRPCs_[i]->rpcCompletionAddr == where) {
387           ret = allRunningRPCs_[i];
388           break;
389       }
390   }
391   return ret;
392 }
393
394 bool rpcMgr::decodeEventIfDueToIRPC(EventRecord &ev)
395 {
396    dyn_lwp *lwp_of_trap  = ev.lwp;
397
398    inferiorrpc_printf("%s[%d]:  decodeEventIfDueToIRPC:  allRunningRPCs_.size = %d\n", FILE__, __LINE__, allRunningRPCs_.size());
399
400    int curr_rpc_index = allRunningRPCs_.size();
401    pdvector<inferiorRPCinProgress *>::iterator iter = allRunningRPCs_.end();
402    while(iter != allRunningRPCs_.begin()) {
403        inferiorRPCinProgress *currRPC = *(--iter);
404        curr_rpc_index--;
405
406        Frame activeFrame;
407
408        rpcThr *rpcThr = currRPC->rpcthr;
409        rpcLWP *rpcLwp = currRPC->rpclwp;
410
411        if(rpcThr) {
412           dyn_thread *cur_dthr = rpcThr->get_thr();
413
414           // skip comparing against any outstanding rpcs from threads/lwps
415           // that aren't stopped; couldn't be the one if not stopped
416           // Only for independently-controlled LWPs. Otherwise they're in
417           // the same state as the process.      
418           if(process::IndependentLwpControl()) {
419              if(cur_dthr->get_lwp()->status() != stopped) {
420                 continue;
421              }
422           }
423
424           if(cur_dthr->get_lwp()->get_lwp_id() != lwp_of_trap->get_lwp_id()) {
425               signal_printf("%s[%d]: trap LWP id %d mismatch against internal lwp ID %d\n",
426                             FILE__, __LINE__, 
427                             lwp_of_trap->get_lwp_id(), 
428                             cur_dthr->get_lwp()->get_lwp_id());
429              continue;
430           }
431
432           activeFrame = cur_dthr->getActiveFrame();
433        } else {
434           assert(rpcLwp != NULL);
435
436           dyn_lwp *cur_dlwp = rpcLwp->get_lwp();
437
438           // See thread comment
439           if(process::IndependentLwpControl()) {
440              if(cur_dlwp->status() != stopped) {
441                 continue;
442              }
443           }
444           if(cur_dlwp->get_lwp_id() != lwp_of_trap->get_lwp_id()) {
445              continue;
446           }
447           activeFrame = rpcLwp->get_lwp()->getActiveFrame();
448        }
449
450        signal_printf("%s[%d]: reported active frame PC is 0x%lx; thread %d, lwp %d\n",
451                      FILE__, __LINE__, activeFrame.getPC(), 
452                      activeFrame.getThread() ? (int) activeFrame.getThread()->get_tid() : -1,
453                      activeFrame.getLWP() ? (int) activeFrame.getLWP()->get_lwp_id() : -1);
454                     
455        
456        if (activeFrame.getPC() == currRPC->rpcResultAddr) {
457            signal_printf("%s[%d]: PC at 0x%lx for lwp %u matches RPC result addr 0x%lx on RPC %p\n",
458                          FILE__, __LINE__, activeFrame.getPC(), activeFrame.getLWP()->get_lwp_id(),
459                          currRPC->rpcResultAddr, currRPC);
460           ev.type = evtRPCSignal;
461           ev.status = statusRPCAtReturn;
462           ev.what = (eventWhat_t) curr_rpc_index;
463           ev.address = activeFrame.getPC();
464           return true;
465        }
466        else if (activeFrame.getPC() == currRPC->rpcCompletionAddr) {
467            signal_printf("%s[%d]: PC at 0x%lx for lwp %u matches RPC completion addr 0x%lx on RPC %p\n",
468                          FILE__, __LINE__, activeFrame.getPC(), activeFrame.getLWP()->get_lwp_id(),
469                          currRPC->rpcCompletionAddr, currRPC);
470           ev.type = evtRPCSignal;
471           ev.status = statusRPCDone;
472           ev.what = (eventWhat_t) curr_rpc_index;
473           ev.address = activeFrame.getPC();
474           return true;
475        }
476    }
477           
478    return false;
479 }
480
481 bool rpcMgr::handleRPCEvent(EventRecord &ev, bool &continueHint) 
482 {
483   if (ev.type != evtRPCSignal) return false;
484
485   inferiorRPCinProgress *currRPC = NULL;
486   rpcThr *rpcThr = NULL;
487   rpcLWP *rpcLwp = NULL;
488
489   inferiorrpc_printf("%s[%d]: handleRPCEvent, status %d, addr 0x%lx\n", 
490                      FILE__, __LINE__, ev.status, ev.address);
491
492   if (ev.status == statusRPCAtReturn) {
493     currRPC = findRunningRPCWithResultAddress(ev.address);
494     assert(currRPC);
495     assert(ev.address == currRPC->rpcResultAddr); 
496     rpcThr = currRPC->rpcthr;
497     rpcLwp = currRPC->rpclwp;
498
499     if (rpcThr) 
500        rpcThr->getReturnValueIRPC();
501     else 
502        rpcLwp->getReturnValueIRPC();
503     
504     continueHint = true;
505   }
506   else if (ev.status == statusRPCDone) {
507     currRPC = findRunningRPCWithCompletionAddress(ev.address);
508
509     assert(currRPC);
510     assert(ev.address == currRPC->rpcCompletionAddr); 
511
512     // currRPC goes away in handleCompleted... so slurp the result here
513     if (currRPC->rpc->runProcessWhenDone) {
514           continueHint = true;
515     }
516     
517     rpcThr = currRPC->rpcthr;
518     rpcLwp = currRPC->rpclwp;
519     if(rpcThr) {
520         if (rpcThr->handleCompletedIRPC()) {
521             continueHint = true;
522         }
523     }
524     else if (rpcLwp) {
525         if (rpcLwp->handleCompletedIRPC()) {
526             continueHint = true;
527         }
528     }
529     else {
530         assert(0);
531     }
532   }
533   else 
534     assert(0);
535
536   // Do we want this to be pending? What if someone says
537   // "run iRPC" and waits for it to finish, on a thread in a
538   // syscall.... we need to re-investigate aborting syscalls.
539
540   if (process::IndependentLwpControl()) {
541     // Linux can be harmlessly activated; this is _bad_ on 
542     // Solaris/AIX (as we'll immediately get the latest event again)
543
544     if (existsActiveIRPC()) {
545       // Be sure that we keep consuming events on other threads,
546       // even if we're paused in this one...
547        signal_printf("%s[%d]: Active RPC, signaling active process\n",
548                      FILE__, __LINE__);
549       ev.proc->sh->signalActiveProcess();
550     }
551     else {
552        signal_printf("%s[%d]: No active RPC, belaying active process\n",
553                      FILE__, __LINE__);
554       ev.proc->sh->belayActiveProcess();
555     }
556   }
557   else 
558   {
559       // We stopped everything, and there's an iRPC that needs
560       // running...
561       // Should this be moved to whoever's waiting on the iRPC?
562       // Better, go to independent control on more platforms.
563     if (existsActiveIRPC()) {
564        continueHint = true;
565     }
566     
567   }
568   return true;
569 }
570   
571 // Run da suckers
572 // Take all RPCs posted and run them (if possible)
573 // Return true if any RPCs were launched (and the process is running),
574 //   false if none were (and the process hasn't changed state)
575 // wasRunning: desired state of the process (as opposed to current
576 //  state).
577 // Note: if there are no RPCs running but wasRunning is true, launchRPCs
578 // will continue the process!
579
580 bool rpcMgr::launchRPCs(bool &needsToRun, 
581                         bool wasRunning) {
582     // First, idiot check. If there aren't any RPCs to run, then
583     // don't do anything. Reason: launchRPCs is called several times
584     // a second in the daemon main loop
585     //inferiorrpc_printf("Call to launchRPCs, recursionGuard %d\n", recursionGuard);
586     if (recursionGuard) {
587         // Error case: somehow launchRPCs was entered recursively
588         cerr <<  "Error: inferior RPC mechanism was used in an unsafe way!" << endl;
589         // Umm....
590         return false;
591     }
592
593     recursionGuard = true;
594
595
596     bool readyProcessRPC = false;
597     bool readyLWPRPC = false;
598     bool readyThrRPC = false;
599     bool processingLWPRPC = false;
600     bool processingThrRPC = false;
601     // We check LWP RPCs first. If there are any they are run first -- even
602     // if there is a thread RPC currently running. Only use LWP RPCs for very low
603     // level operations. 
604     
605     // We have a central list of all posted or pending RPCs... if those are empty
606     // then don't bother doing work
607     //inferiorrpc_printf("%d posted RPCss...\n", allPostedRPCs_.size());
608     if (allPostedRPCs_.size() == 0) {
609       // Here's an interesting design question. "wasRunning" means "what do I do
610       // after the RPCs are done". Now, if there weren't any RPCs, do we 
611       // run the process? 
612       if (wasRunning && proc_->isStopped()) {
613           needsToRun = true;
614       }
615       recursionGuard = false;
616       inferiorrpc_printf("%s[%d]: no posted RPCs, returning immediately\n", FILE__, __LINE__);
617       return true;
618     }
619
620       inferiorrpc_printf("%s[%d]: launchRPCs checking for RPCs\n", FILE__, __LINE__);
621
622     dictionary_hash<unsigned, rpcLWP *>::iterator rpc_iter = lwps_.begin();
623     while(rpc_iter != lwps_.end()) {
624        rpcLWP *cur_rpc_lwp = (*rpc_iter);
625        if (cur_rpc_lwp) {
626           if(cur_rpc_lwp->isReadyForIRPC()) {
627              inferiorrpc_printf("%s[%d]: LWP %u ready for RPC...\n", 
628                                 FILE__, __LINE__, cur_rpc_lwp->get_lwp()->get_lwp_id());
629              readyLWPRPC = true;
630              break;
631           }
632           else
633              inferiorrpc_printf("%s[%d]: LWP %u not for RPC...\n", 
634                                 FILE__, __LINE__, cur_rpc_lwp->get_lwp()->get_lwp_id());             
635           if (cur_rpc_lwp->isProcessingIRPC()) {
636              inferiorrpc_printf("%s[%d]: LWP %u currently processing RPC...\n", 
637                                 FILE__, __LINE__, cur_rpc_lwp->get_lwp()->get_lwp_id());
638              processingLWPRPC = true;
639           }
640        }
641        rpc_iter++;
642     }
643
644     // Only run thread RPCs if there are no LWP RPCs either waiting or in flight.
645
646     if (!readyLWPRPC && !processingLWPRPC && !readyProcessRPC && !processingProcessRPC) {
647         inferiorrpc_printf("%s[%d]: examining %d threads for RPCs...\n",
648                            FILE__, __LINE__, thrs_.size());
649         assert(thrs_.size());
650        for (unsigned i = 0; i < thrs_.size(); i++) {
651           rpcThr *curThr = thrs_[i];
652           if(curThr == NULL) {
653               continue;
654           }
655           if (curThr->isReadyForIRPC()) {
656              inferiorrpc_printf("%s[%d]: Thread %u ready for RPC...\n", 
657                                 FILE__, __LINE__, curThr->get_thr()->get_tid());
658              readyThrRPC = true;
659              break;
660           }
661           else
662              inferiorrpc_printf("%s[%d]: Thread %u not ready for RPC...\n", 
663                                 FILE__, __LINE__, curThr->get_thr()->get_tid());
664              
665           if (curThr->isRunningIRPC()) {
666              inferiorrpc_printf("%s[%d]: Thread %u currently processing RPC...\n", 
667                                 FILE__, __LINE__, curThr->get_thr()->get_tid());
668              processingThrRPC = true;
669           }
670           inferiorrpc_printf("%s[%d]: ---------------------------------------\n",
671                              FILE__, __LINE__);
672        }
673     }
674     inferiorrpc_printf("%s[%d]: RPC status dump: readyLWP %d, readyThr %d, readyProcess %d;\n",
675                        FILE__, __LINE__, readyLWPRPC, readyThrRPC, readyProcessRPC);
676     inferiorrpc_printf("%s[%d]: RPC status dump: wasRunning %d, processingLWP %d, processingThr %d\n",
677                        FILE__, __LINE__, wasRunning, processingLWPRPC, processingThrRPC);
678     if (!readyLWPRPC && !readyThrRPC && !readyProcessRPC) {
679         if (wasRunning || processingLWPRPC || processingThrRPC) {
680             // the caller expects the process to be running after
681             // iRPCs finish, so continue the process here
682             // ... or there is an iRPC in progress.
683             needsToRun = true;
684         }
685         recursionGuard = false;
686         inferiorrpc_printf("%s[%d]: Nothing to do, going home\n",
687                            FILE__, __LINE__);
688         return true;
689     }
690
691     // We have work to do. Pause the process.
692     if (!proc()->IndependentLwpControl()) {
693        if (!proc_->pause()) {
694           recursionGuard = false;
695           return false;
696        }
697     }
698     
699     // Okay, there is an inferior RPC to do somewhere. Now we just need
700     // to launch ze sucker
701     bool runProcessWhenDone = false;
702     // Run LWP RPCs (if there are any)
703     if (readyLWPRPC) {
704         dictionary_hash<unsigned, rpcLWP *>::iterator lwp_iter = lwps_.begin();
705         while(lwp_iter != lwps_.end()) {
706             rpcLWP *cur_rpc_lwp = (*lwp_iter);
707             if (cur_rpc_lwp) {            
708                 irpcLaunchState_t lwpState = cur_rpc_lwp->launchLWPIRPC(wasRunning);
709                 inferiorrpc_printf("%s[%d]: Result of posting RPC on LWP %d: %s\n",
710                                    FILE__, __LINE__, cur_rpc_lwp->get_lwp()->get_lwp_id(),
711                                    irpcLaunchStateAsString(lwpState));
712                 if (lwpState == irpcBreakpointSet ||
713                     lwpState == irpcAgain ||
714                     lwpState == irpcStarted) {
715                     runProcessWhenDone = true;
716                 }
717             }
718             lwp_iter++;
719         }
720     }
721     else if (readyThrRPC) {
722         // Loop over all threads and try to run an inferior RPC
723         for (unsigned iter = 0; iter < thrs_.size(); iter++) {
724            rpcThr *curThr = thrs_[iter];
725            if(curThr == NULL)
726               continue;
727
728             irpcLaunchState_t thrState = curThr->launchThrIRPC(wasRunning);
729             // If an IRPC was launched we've got it in the allRunningRPCs
730             // vector (For bookkeeping)
731             // And pick out whether the process should be run
732
733             inferiorrpc_printf("%s[%d]: Result of posting RPC on thread %lu: %s\n",
734                                FILE__, __LINE__, 
735                                curThr->get_thr()->get_tid(),
736                                irpcLaunchStateAsString(thrState));
737             
738             if (thrState == irpcBreakpointSet ||
739                 thrState == irpcAgain ||
740                 thrState == irpcStarted) {
741                 runProcessWhenDone = true;
742             }
743         }
744     }
745     else
746         assert(0);
747
748     // Return value states whether the process should be run or not.
749     // If we have an inferior RPC going then always return true (since
750     // the RPC needs to complete). If we have a _pending_ RPC then run
751     // the process (since it needs to get ready). And if we have an RPC
752     // pending with no inserted breakpoint then run the process (but
753     // poll for completion)
754     if (runProcessWhenDone || 
755         allRunningRPCs_.size() > 0) {
756         needsToRun = true;
757         recursionGuard = false;
758
759         if (!proc()->IndependentLwpControl())
760             proc()->continueProc();
761
762         return true;
763     }
764
765     // Weird... not sure how we can get here...
766     if (wasRunning) {
767         needsToRun = true;
768     }
769     
770     recursionGuard = false;
771     return false;
772 }
773
774 Address rpcMgr::createRPCImage(AstNodePtr action,
775                                bool noCost,
776                                bool shouldStopForResult,
777                                Address &startAddr,
778                                Address &breakAddr,
779                                Address &stopForResultAddr,
780                                Address &justAfter_stopForResultAddr,
781                                Register &resultReg,
782                                bool lowmem, 
783                                dyn_thread *thr,
784                                dyn_lwp * lwp) 
785 {
786    // Returns addr of temp tramp, which was allocated in the inferior heap.
787    // You must free it yourself when done.
788    // Note how this is, in many ways, a greatly simplified version of
789    // addInstFunc().
790
791     // Rather than worrying about saving mutator-side, we run this as a
792     // conservative base tramp. They're really the same thing, 
793     // with some extra bits at the end.
794
795    // Temp tramp structure: save; code; restore; trap; illegal
796    // the illegal is just to make sure that the trap never returns
797    // note that we may not need to save and restore anything, since we've
798    // already done a GETREGS and we'll restore with a SETREGS, right?
799    // unsigned char insnBuffer[4096];
800     codeGen irpcBuf(MAX_IRPC_SIZE);
801     irpcBuf.setAddrSpace(proc());
802     irpcBuf.setLWP(lwp);
803     irpcBuf.setThread(thr);
804     
805     irpcBuf.setRegisterSpace(registerSpace::irpcRegSpace(proc()));
806
807 #if defined(bug_syscall_changepc_rewind)
808     // See comment in linux-power.C/linux-x86.C; search for "SGI"
809     irpcBuf.fill(proc()->getAddressWidth(), codeGen::cgNOP);
810 #endif
811
812
813     // Saves registers (first half of the base tramp) and whatever other
814     // irpc-specific magic is necessary
815     if (!emitInferiorRPCheader(irpcBuf)) {
816         // a fancy dialog box is probably called for here...
817         cerr << "createRPCtempTramp failed because emitInferiorRPCheader failed."
818              << endl;
819         return 0;
820     }
821
822     resultReg = REG_NULL;
823
824     if (!action->generateCode(irpcBuf,
825                               noCost,
826                               resultReg)) assert(0);
827     if (!shouldStopForResult) {
828         irpcBuf.rs()->freeRegister(resultReg);
829     }
830
831     // Now, the trailer (restore, TRAP, illegal)
832     // (the following is implemented in an arch-specific source file...)   
833     // breakOffset: where the irpc ends
834     // stopForResultOffset: we expect a trap here if we're getting a result back
835     // justAfter_stopForResultOffset: where to continue the process at (next insn)
836
837     unsigned breakOffset, stopForResultOffset, justAfter_stopForResultOffset;
838     if (!emitInferiorRPCtrailer(irpcBuf, breakOffset,
839                                 shouldStopForResult, stopForResultOffset,
840                                 justAfter_stopForResultOffset)) {
841         // last 4 args except shouldStopForResult are modified by the call
842         cerr << "createRPCtempTramp failed because "
843              << "emitInferiorRPCtrailer failed." << endl;
844         return 0;
845     }
846     Address tempTrampBase;
847     inferiorrpc_printf("Allocating RPC image... lowmem %d, count %d\n",
848                        lowmem, irpcBuf.used());
849     if (lowmem)
850         {
851             /* lowmemHeap should always have free space, so this will not
852                require a recursive inferior RPC. */
853             tempTrampBase = proc_->inferiorMalloc(irpcBuf.used(), lowmemHeap);
854         }
855     else
856         {
857             /* May cause another inferior RPC to dynamically allocate a new heap
858                in the inferior. */
859             // This is currently broken; noticed when I wasn't adding
860             // the heaps correctly. Problem is, I'm not sure how to fix
861             // it up, so leaving for now -- bernat, 12MAY05
862             // The recursive allocation, that is. We don't like starting another
863             // RPC at this point.
864             
865             /* 2006-04-20: Rather than try to fix recursive iRPCs, necessary if we
866                need to allocate more room in the mutatee, just use the newly-enlarged
867                lowmemHeap for everything and assume that we won't be running more than
868                512k worth of iRPCs at any given time.  This needs to be fixed later.
869                
870                  -- bernat via tlmiller */
871             tempTrampBase = proc_->inferiorMalloc(irpcBuf.used(), lowmemHeap);
872         }
873     assert(tempTrampBase);
874     
875     breakAddr                      = tempTrampBase + breakOffset;
876     if (shouldStopForResult) {
877         stopForResultAddr           = tempTrampBase + stopForResultOffset;
878         justAfter_stopForResultAddr = tempTrampBase + 
879             justAfter_stopForResultOffset;
880     } 
881     else {
882         stopForResultAddr = justAfter_stopForResultAddr = 0;
883     }
884     
885     inferiorrpc_cerr << "createRPCtempTramp: temp tramp base=" << (void*)tempTrampBase
886                      << ", stopForResultAddr=" << (void*)stopForResultAddr
887                      << ", justAfter_stopForResultAddr="
888                      << (void*)justAfter_stopForResultAddr
889                      << ", breakAddr=" << (void*)breakAddr
890                      << ", count=" << irpcBuf.used() << " so end addr="
891                      << (void*)(tempTrampBase + irpcBuf.used()) << endl;
892     
893     
894     /* Now, write to the tempTramp, in the inferior addr's data space
895        (all tramps are allocated in data space) */
896     /*
897       bperr( "IRPC:\n");
898       for (unsigned i = 0; i < count/4; i++)
899       bperr( "0x%x\n", ((int *)insnBuffer)[i]);
900       bperr("\n\n\n\n\n");
901     */
902     
903     if (!proc_->writeDataSpace((void*)tempTrampBase, irpcBuf.used(), irpcBuf.start_ptr())) {
904         // should put up a nice error dialog window
905         cerr << "createRPCtempTramp failed because writeDataSpace failed" <<endl;
906         return 0;
907     }
908
909     startAddr = tempTrampBase;
910
911 #if defined(bug_syscall_changepc_rewind)
912     // Some Linux kernels have the following behavior:
913     // Process is in a system call;
914     // We interrupt the system call;
915     // We say "change PC to address N"
916     // The kernel helpfully changes it to (N - address width)
917     // The program crashes
918     // See a more complete comment in linux-x86.C (search for "SGI"). 
919     // For now, we pad the start of our code with NOOPS and change to just
920     // after those; if we hit rewind behavior, then we're executing safe code.
921     startAddr += proc()->getAddressWidth();
922 #endif
923
924     return tempTrampBase;
925 }
926
927 /* ***************************************************** */
928
929
930 #if !defined(arch_ia64)
931
932 // IA64 has to figure out what to save before it can do things correctly. This is very
933 // nasty (see inst-ia64.C), and so we're leaving it alone. Everyone else
934 // is relatively normal. If the saves are ever wrapped into a function we could
935 // probably get rid of the ifdef
936
937 bool rpcMgr::emitInferiorRPCheader(codeGen &gen) 
938 {
939     assert(irpcTramp);
940     gen.beginTrackRegDefs();
941     irpcTramp->generateSaves(gen, gen.rs(), NULL);
942     return true;
943 }
944
945 bool rpcMgr::emitInferiorRPCtrailer(codeGen &gen,
946                                     unsigned &breakOffset,
947                                     bool shouldStopForResult,
948                                     unsigned &stopForResultOffset,
949                                     unsigned &justAfter_stopForResultOffset) {
950     if (shouldStopForResult) {
951         // Trappity!
952         stopForResultOffset = gen.used();
953         instruction::generateTrap(gen);
954         justAfter_stopForResultOffset = gen.used();
955     }
956     assert(irpcTramp);
957     //irpcTramp->generateBT(gen);
958     // Should already be built by the call to generateBT in emit... header
959     irpcTramp->generateRestores(gen, gen.rs(), NULL);
960
961     breakOffset = gen.used();
962     instruction::generateTrap(gen);
963     
964     instruction::generateTrap(gen);
965
966 #if (defined(arch_x86) || defined(arch_x86_64))
967      // X86 traps at the next insn, not the trap. So shift the
968      // offsets accordingly
969
970      if (shouldStopForResult) {
971          stopForResultOffset += 1;
972      }
973      breakOffset += 1;
974 #endif
975      gen.endTrackRegDefs();
976
977     return true;
978 }
979
980 #endif
981
982
983 bool rpcMgr::cancelRPC(unsigned id) {
984   inferiorrpc_printf("Cancelling RPC %d...\n", id);
985     // We can cancel posted or pending RPCs
986     for (unsigned i = 0; i < allPostedRPCs_.size(); i++) {
987        inferiorRPCtoDo *rpc = allPostedRPCs_[i];
988        inferiorrpc_printf("Checking RPC %d against %d\n", rpc->id, id);
989        if (rpc->id == id) {
990           if (rpc->thr)
991              thrs_[rpc->thr->get_index()]->deleteThrIRPC(id);
992           else if (rpc->lwp)
993              lwps_[rpc->lwp->get_lwp_id()]->deleteLWPIRPC(id);
994           else
995              deleteProcessRPC(id);
996           removePostedRPC(rpc);
997           return true;
998        }
999     }
1000     
1001     // Check pending
1002     for (unsigned j = 0; j < allPendingRPCs_.size(); j++) {
1003        inferiorRPCinProgress *inprog = allPendingRPCs_[j];
1004        inferiorrpc_printf("Checking pending RPC %d against %d\n", inprog->rpc->id, id);
1005
1006         if (inprog->rpc->id == id) {
1007             if (inprog->rpc->thr)
1008                 thrs_[inprog->rpc->thr->get_index()]->deleteThrIRPC(id);
1009             else if (inprog->rpc->lwp)
1010                 lwps_[inprog->rpc->lwp->get_lwp_id()]->deleteLWPIRPC(id);
1011             removePendingRPC(inprog);
1012             return true;
1013         }
1014     }
1015
1016     // And running...
1017     for (unsigned l = 0; l < allRunningRPCs_.size(); l++) {
1018         inferiorRPCinProgress *running = allRunningRPCs_[l];
1019         inferiorrpc_printf("Checking running RPC %d against %d\n", running->rpc->id, id);
1020         if (running->rpc->id == id) {
1021             // Oops... nothing we can do. 
1022             fprintf(stderr, "[%s:%d] WARNING: cancelling currently active iRPC\n",
1023                     __FILE__, __LINE__);
1024             return false;
1025         }
1026     }
1027     return false;
1028 }
1029
1030 void rpcMgr::addThread(dyn_thread *thr) {
1031     rpcThr *newThread = new rpcThr(this, thr);
1032     int index = newThread->get_thr()->get_index();
1033
1034     // this code will fill in NULLs in any array entries that haven't yet
1035     // been assigned a thread
1036     unsigned new_size = static_cast<unsigned>(index) + 1;
1037     if(new_size > thrs_.size()) {
1038        for(unsigned i=thrs_.size(); i < new_size; i++)
1039           thrs_.push_back(NULL);
1040     }
1041     thrs_[index] = newThread;
1042 }
1043
1044 void rpcMgr::deleteThread(dyn_thread *thr) {
1045    int index = thr->get_index();
1046    delete thrs_[index];
1047    thrs_[index] = NULL;
1048 }
1049
1050 void rpcMgr::addLWP(dyn_lwp *lwp) {
1051     rpcLWP *newLWP = new rpcLWP(this, lwp);
1052     lwps_[lwp->get_lwp_id()] = newLWP;
1053 }
1054
1055 void rpcMgr::deleteLWP(dyn_lwp *lwp) {
1056     rpcLWP *oldLWP = NULL;
1057     lwps_.find(lwp->get_lwp_id(), oldLWP);
1058     if (oldLWP) delete oldLWP;
1059     lwps_.undef(lwp->get_lwp_id());
1060 }
1061
1062 /*
1063  * RPC list manipulation
1064  */
1065
1066 bool rpcMgr::removePostedRPC(inferiorRPCtoDo *rpc) {
1067     bool removed = false;
1068     pdvector<inferiorRPCtoDo *> newPostedRPCs;
1069     for (unsigned i = 0; i < allPostedRPCs_.size(); i++)
1070         if (rpc == allPostedRPCs_[i]) {
1071             removed = true;
1072         }
1073         else {
1074             newPostedRPCs.push_back(allPostedRPCs_[i]);
1075         }
1076     
1077     allPostedRPCs_ = newPostedRPCs;
1078     return removed;
1079 }
1080
1081 bool rpcMgr::removePendingRPC(inferiorRPCinProgress *rpc) {
1082     bool removed = false;
1083     pdvector<inferiorRPCinProgress *> newPendingRPCs;
1084     for (unsigned i = 0; i < allPendingRPCs_.size(); i++)
1085         if (rpc == allPendingRPCs_[i]) {
1086             removed = true;
1087         }
1088         else {
1089             newPendingRPCs.push_back(allPendingRPCs_[i]);
1090         }
1091     
1092     allPendingRPCs_ = newPendingRPCs;
1093     return removed;
1094 }
1095
1096 bool rpcMgr::removeRunningRPC(inferiorRPCinProgress *rpc) {
1097     bool removed = false;
1098     pdvector<inferiorRPCinProgress *> newRunningRPCs;
1099     for (unsigned i = 0; i < allRunningRPCs_.size(); i++)
1100         if (rpc == allRunningRPCs_[i]) {
1101             removed = true;
1102         }
1103         else {
1104             newRunningRPCs.push_back(allRunningRPCs_[i]);
1105         }
1106     
1107     allRunningRPCs_ = newRunningRPCs;
1108     return removed;
1109 }
1110
1111 bool rpcMgr::addPendingRPC(inferiorRPCinProgress *pending) {
1112     allPendingRPCs_.push_back(pending);
1113     return removePostedRPC(pending->rpc);
1114 }
1115
1116 bool rpcMgr::addRunningRPC(inferiorRPCinProgress *running) {
1117     allRunningRPCs_.push_back(running);
1118     inferiorrpc_printf("%s[%d]: Added running RPC to global list; %d total running\n",
1119                        FILE__, __LINE__, allRunningRPCs_.size());
1120     return removePendingRPC(running);
1121 }
1122
1123 bool rpcMgr::deleteProcessRPC(unsigned id) {
1124     bool removed = false;
1125     pdvector<inferiorRPCtoDo *> newRPCs;
1126     for (unsigned i = 0; i < postedProcessRPCs_.size(); i++) {
1127         if (postedProcessRPCs_[i]->id == id)
1128             removed = true;
1129         else
1130             newRPCs.push_back(postedProcessRPCs_[i]);
1131     }
1132     
1133     return removed;
1134     
1135 }
1136
1137 irpcState_t rpcMgr::getRPCState(unsigned id) {
1138     // Check to see if it's posted
1139     for (unsigned i = 0; i < allPostedRPCs_.size(); i++)
1140         if (allPostedRPCs_[i]->id == id)
1141             return irpcNotRunning;
1142     
1143     // Check pending
1144     for (unsigned j = 0; j < allPendingRPCs_.size(); j++) 
1145         if (allPendingRPCs_[j]->rpc->id == id)
1146             return irpcWaitingForSignal;
1147     
1148     // Check running
1149     for (unsigned k = 0; k < allRunningRPCs_.size(); k++)
1150         if (allRunningRPCs_[k]->rpc->id == id)
1151             return irpcRunning;
1152     
1153     return irpcNotValid;
1154 }
1155
1156 const char *irpcStateAsString(irpcState_t state) {
1157     switch(state) {
1158     case irpcNotValid:
1159         return "IRPC Invalid";
1160         break;
1161     case irpcNotRunning:
1162         return "IRPC Posted, not running";
1163         break;
1164     case irpcRunning:
1165         return "IRPC Running";
1166         break;
1167     case irpcWaitingForSignal:
1168         return "IRPC Waiting for Signal";
1169         break;
1170     case irpcNotReadyForIRPC:
1171         return "IRPC Not Ready";
1172         break;
1173     default:
1174         assert(0);
1175         break;
1176     }
1177     return NULL;
1178 }
1179
1180 const char *irpcLaunchStateAsString(irpcLaunchState_t state) {
1181     switch(state) {
1182     case irpcNoIRPC:
1183         return "No IRPC to run";
1184         break;
1185     case irpcStarted:
1186         return "IRPC Started";
1187         break;
1188     case irpcAgain:
1189         return "IRPC not started, try again";
1190         break;
1191     case irpcBreakpointSet:
1192         return "Set breakpoint for syscall exit";
1193         break;
1194     case irpcError:
1195         return "IRPC Error";
1196         break;
1197     default:
1198         assert(0);
1199         break;
1200     }
1201     return NULL;
1202 }
1203
1204     
1205