GCC 4.8 build fixes: ensure all extern template declarations are in fact extern'ed...
[dyninst.git] / stackwalk / src / bluegene-swk.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  *
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  *
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  *
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30 #include "stackwalk/src/bluegene-swk.h"
31 using namespace DebuggerInterface;
32
33 #include "stackwalk/src/bluegenel-swk.h"
34 #include "stackwalk/src/bluegenep-swk.h"
35 #include "stackwalk/src/sw.h"
36
37 #include "stackwalk/h/swk_errors.h"
38 #include "stackwalk/h/symlookup.h"
39 #include "stackwalk/h/walker.h"
40 #include "stackwalk/h/framestepper.h"
41 #include "stackwalk/h/procstate.h"
42 #include "stackwalk/src/symtab-swk.h"
43
44 using namespace Dyninst;
45 using namespace Dyninst::Stackwalker;
46
47 #include "common/src/SymLite-elf.h"
48
49
50 #include <string>
51 #include <memory>
52 #include <string.h>
53 #include <sys/syscall.h>
54 #include <unistd.h>
55 #include <errno.h>
56 #include <signal.h>
57 #include <sys/poll.h>
58 #include <assert.h>
59 using namespace std;
60
61
62 namespace Dyninst {
63   namespace Stackwalker {
64
65     bool bg_fdHasData(int fd) {
66       int result;
67       struct pollfd fds;
68       fds.fd = fd;
69       fds.events = POLLIN;
70       fds.revents = 0;
71       result = poll(&fds, 1, 0);
72       if (result == -1) {
73         int errnum = errno;
74         sw_printf("[%s:%u] - Unable to poll fd %d: %s\n", FILE__, __LINE__,
75                   fd, strerror(errnum));
76         return false;
77       }
78       return (bool) (fds.revents & POLLIN);
79     }
80
81
82     // ============================================================ //
83     // Walker
84     // ============================================================ //
85     bool Walker::createDefaultSteppers() {
86       FrameStepper *stepper = new FrameFuncStepper(this);
87       bool result = addStepper(stepper);
88       if (!result) {
89         sw_printf("[%s:%u] - Error adding stepper %p\n", FILE__, __LINE__, stepper);
90       }
91       return result;
92     }
93
94
95     // ============================================================ //
96     // ProcSelf -- all stubs; this is 3rd-party only
97     // ============================================================ //
98     static bool proc_self_unsupported(const char *file, size_t line) {
99       const char *msg = "ProcSelf not supported for 3rd party BG stackwalkers!";
100       sw_printf("[%s:%u] - %s\n", file, line, msg);
101       setLastError(err_procread, msg);
102       return false;
103     }
104
105     bool ProcSelf::getThreadIds(std::vector<THR_ID> &) {
106       return proc_self_unsupported(FILE__, __LINE__);
107     }
108
109
110     ProcSelf::ProcSelf(std::string exe_path) : ProcessState(getpid(), exe_path) {
111       proc_self_unsupported(FILE__, __LINE__);
112     }
113
114
115     void ProcSelf::initialize() {
116       proc_self_unsupported(FILE__, __LINE__);
117     }
118
119
120     bool ProcSelf::getDefaultThread(THR_ID &) {
121       return proc_self_unsupported(FILE__, __LINE__);
122     }
123
124
125     bool ProcSelf::readMem(void *, Address, size_t) {
126       return proc_self_unsupported(FILE__, __LINE__);
127     }
128
129
130     // ============================================================ //
131     // ProcDebug
132     // ============================================================ //
133     ProcDebug *ProcDebug::newProcDebug(PID pid, string executable) {
134       auto_ptr<ProcDebug> pd(ProcDebugBG::createProcDebugBG(pid, executable));
135       if (!pd.get()) {
136         const char *msg = "Error creating new ProcDebug object";
137         sw_printf("[%s:%u] - %s\n", FILE__, __LINE__, msg);
138         setLastError(err_internal, msg);
139         return NULL;
140       }
141
142       bool result = pd->attach();
143       if (!result || (pd->state() != ps_running && pd->state() != ps_attached))
144       {
145         pd->setState(ps_errorstate);
146         proc_map.erase(pid);
147         const char *msg = "Error attaching to process";
148         sw_printf("[%s:%u] - %s %d\n", FILE__, __LINE__, msg, pid);
149         setLastError(err_noproc, msg);
150         return NULL;
151       }
152
153       return pd.release();
154     }
155
156
157     bool ProcDebug::newProcDebugSet(const vector<Dyninst::PID>&, vector<ProcDebug*>&) {
158       setLastError(err_unsupported, "ERROR: newProcDebugSet not implemented for BlueGene Stackwalker!");
159       return false;
160     }
161
162
163     ProcDebug *ProcDebug::newProcDebug(std::string, const std::vector<std::string> &) {
164       setLastError(err_unsupported, "Executable launch not supported on BlueGene");
165       return NULL;
166     }
167
168
169     bool ProcDebugBG::isLibraryTrap(Dyninst::THR_ID) {
170       // Base ProcDebugBG doesn't support dynamic libs.
171       return false;
172     }
173
174
175     DebugEvent ProcDebug::debug_get_event(bool block) {
176       DebugEvent ev;
177       BG_Debugger_Msg msg;
178
179       if (!block && !bg_fdHasData(BG_DEBUGGER_READ_PIPE)) {
180         ev.dbg = dbg_noevent;
181         return ev;
182       }
183
184       // Read an event from the debug filehandle.
185       sw_printf("[%s:%u] - Waiting for debug event\n", FILE__, __LINE__);
186       bool result = BG_Debugger_Msg::readFromFd(BG_DEBUGGER_READ_PIPE, msg);
187       if (!result) {
188         sw_printf("[%s:%u] - Unable to wait for debug event on process\n",
189                   FILE__, __LINE__);
190         ev.dbg = dbg_err;
191         return ev;
192       }
193
194       // extract process and thread id from the BG message.
195       pid_t pid = msg.header.nodeNumber;
196       THR_ID tid = msg.header.thread;
197       int returnCode = msg.header.returnCode;
198       sw_printf("[%s:%u] - Received debug event %s from pid %d, tid %d, rc %d\n", FILE__, __LINE__,
199                 BG_Debugger_Msg::getMessageName(msg.header.messageType), pid, tid, returnCode);
200
201       if (returnCode > 0) {
202         // Print out a message if we get a return code we don't expect.  Consult the debugger header
203         // for the meanings of these.
204         sw_printf("[%s:%u] - WARNING: return code for %s on pid %d, tid %d was non-zero: %d\n",
205                   FILE__, __LINE__,
206                   BG_Debugger_Msg::getMessageName(msg.header.messageType), pid, tid,
207                   msg.header.returnCode);
208       }
209
210       // Look up the ProcDebugBG from which the event originated.
211       std::map<PID, ProcessState *>::iterator i = proc_map.find(pid);
212       if (i == proc_map.end()) {
213         sw_printf("[%s:%u] - Error, received unknown pid %d\n", FILE__, __LINE__, pid);
214         setLastError(err_internal, "Error waiting for debug event");
215         ev.dbg = dbg_err;
216         return ev;
217       }
218       ProcDebugBG *procbg = dynamic_cast<ProcDebugBG*>(i->second);
219       assert(procbg);
220       ev.proc = procbg;
221
222       // below is some (somewhat nasty) magic to allow stackwalker to discover the
223       // initial thread's id after it attaches.
224       thread_map_t::iterator t = procbg->threads.find(tid);
225       if (t == procbg->threads.end()) {
226         BGThreadState *initial_thread = dynamic_cast<BGThreadState*>(procbg->initial_thread);
227
228         if (tid != 0) {
229           // Check to see if the initial thread is valid.  If its id is zero, it's a stub
230           // from creation time and we got a signal from the real initial thread.  If it's
231           // not zero, then we're seeing a strange thread id.
232           if (initial_thread->getTid() != 0) {
233             const char *msg = "Saw unknown thread id in ProcDebug::debug_get_evet()!";
234             sw_printf("[%s:%u] - %s on pid %d\n", FILE__, __LINE__, msg, pid);
235             setLastError(err_internal, msg);
236             ev.dbg = dbg_err;
237             return ev;
238           }
239
240           // if we see a threadid we don't know about, it's because we got a SIGNAL_ENCOUNTERED
241           // from the main thread.  We default the initial thread id to zero, but this is only because
242           // we need to start somewhere to attach.  This sets the main thread id to the real thread id
243           // for the process.  This should happen relatively early when we stop the thread during attach.
244           procbg->threads.erase(initial_thread->getTid());
245           initial_thread->setTid(tid);
246           procbg->threads[tid] = initial_thread;
247           t = procbg->threads.find(tid);
248
249         } else {
250           // if the thread id we don't know about is zero, we got an ack for something we
251           // did before we discovered what the initial thread id was.  So just point the event
252           // at the initial thread
253           t = procbg->threads.find(initial_thread->getTid());
254         }
255       }
256
257       ThreadState *ts = t->second;
258       assert(ts);
259       ev.thr = ts;
260
261       procbg->translate_event(msg, ev);
262       return ev;
263     }
264
265
266    int ProcDebug::getNotificationFD() {
267       return BG_DEBUGGER_READ_PIPE;
268     }
269
270
271     // ============================================================ //
272     // ProcDebugBG
273     // ============================================================ /
274     void ProcDebugBG::translate_event(const BG_Debugger_Msg& msg, DebugEvent& ev) {
275       switch (msg.header.messageType) {
276       case PROGRAM_EXITED:
277         {
278           ev.data.idata = msg.dataArea.PROGRAM_EXITED.rc;
279           int exit_type = msg.dataArea.PROGRAM_EXITED.type;
280
281           if (exit_type == 0) {
282             ev.dbg = dbg_exited;
283             sw_printf("[%s:%u] - Process %d exited with %d\n", FILE__, __LINE__, pid, ev.data.idata);
284           } else if (exit_type == 1) {
285             ev.dbg = dbg_crashed;
286             sw_printf("[%s:%u] - Process %d crashed with %d\n", FILE__, __LINE__, pid, ev.data.idata);
287           } else {
288             ev.dbg = dbg_err;
289             sw_printf("[%s:%u] - WARNING: Unknown exit type (%d) on process %d. "
290                       "May be using outdated BG Debugger Interface!\n", FILE__, __LINE__,
291                       msg.dataArea.PROGRAM_EXITED.type, pid);
292           }
293         }
294         break;
295
296       case SIGNAL_ENCOUNTERED:
297         ev.dbg = dbg_stopped;
298         ev.data.idata = msg.dataArea.SIGNAL_ENCOUNTERED.signal;
299         sw_printf("[%s:%u] - Process %d stopped with %d\n",
300                   FILE__, __LINE__, pid, msg.dataArea.SIGNAL_ENCOUNTERED.signal);
301         break;
302
303       case ATTACH_ACK:
304         ev.dbg = dbg_attached;
305         sw_printf("[%s:%u] - Process %d acknowledged attach\n", FILE__, __LINE__, pid);
306         break;
307       case DETACH_ACK:
308          ev.dbg = dbg_detached;
309          sw_printf("[%s:%u] - Process %d acknowledged detach\n", FILE__, __LINE__, pid);
310          break;
311       case CONTINUE_ACK:
312         ev.dbg = dbg_continued;
313         sw_printf("[%s:%u] - Process %d acknowledged continue\n", FILE__, __LINE__, pid);
314         break;
315
316       case KILL_ACK:
317         ev.dbg = dbg_other;
318         sw_printf("[%s:%u] - Process %d acknowledged kill\n", FILE__, __LINE__, pid);
319         break;
320
321       case GET_ALL_REGS_ACK:
322         {
323           ev.dbg = dbg_allregs_ack;
324           ev.size = msg.header.dataLength;
325           BG_GPRSet_t *data = new BG_GPRSet_t();
326           *data = msg.dataArea.GET_ALL_REGS_ACK.gprs;
327           ev.data.pdata = data;
328           sw_printf("[%s:%u] - RegisterAll ACK on pid %d\n", FILE__, __LINE__, pid);
329         }
330         break;
331       case SET_REG_ACK:
332         {
333           ev.dbg = dbg_setreg_ack;
334           sw_printf("[%s:%u] - SET_REG ACK on pid %d\n", FILE__, __LINE__, pid);
335           break;
336         }
337
338       case GET_MEM_ACK:
339         ev.dbg = dbg_mem_ack;
340         ev.size = msg.header.dataLength;
341         ev.data.pdata = new unsigned char[msg.header.dataLength];
342         if (!ev.data.pdata) {
343           ev.dbg = dbg_err;
344           sw_printf("[%s:%u] - FATAL: Couldn't allocate enough space for memory read on pid %d\n",
345                     FILE__, __LINE__, pid);
346         } else {
347           memcpy(ev.data.pdata, &msg.dataArea, msg.header.dataLength);
348           sw_printf("[%s:%u] - Memory read ACK on pid %d\n", FILE__, __LINE__, pid);
349         }
350         break;
351
352     case SET_MEM_ACK:
353         ev.dbg = dbg_setmem_ack;
354         ev.size = msg.dataArea.SET_MEM_ACK.len;
355         sw_printf("[%s:%u] - Memory write ACK on pid %d ($d bytes at %x).  \n", FILE__, __LINE__,
356                   msg.dataArea.SET_MEM_ACK.len, msg.dataArea.SET_MEM_ACK.addr);
357         break;
358
359       case SINGLE_STEP_ACK:
360         // single step ack is just an ack (like KILL_ACK). We ignore this event and
361         // handle SINGLE_STEP_SIG specially in debug_handle_signal().
362         ev.dbg = dbg_other;
363         sw_printf("[%s:%u] - Process %d received SINGLE_STEP\n", FILE__, __LINE__, pid, ev.data);
364         break;
365
366       default:
367         sw_printf("[%s:%u] - Unknown debug message: %s (%d)\n",
368                   FILE__, __LINE__,
369                   BG_Debugger_Msg::getMessageName(msg.header.messageType),
370                   msg.header.messageType);
371         ev.dbg = dbg_noevent;
372         break;
373      }
374   }
375
376
377     void copy_thread_state(ThreadState *source, ThreadState *dest) {
378       dest->setState(source->state());
379       dest->setStopped(source->isStopped());
380       dest->setShouldResume(source->shouldResume());
381       dest->setUserStopped(source->userIsStopped());
382     }
383
384     bool ProcDebugBG::pollForNewThreads() {
385       return true;  // by default, we don't find anything.
386     }
387
388
389     // This basic implementation assumes *only* the initial thread.
390     bool ProcDebugBG::getThreadIds(std::vector<THR_ID> &threads) {
391       threads.clear();
392       threads.push_back(initial_thread->getTid());
393       return true;
394     }
395
396
397     bool ProcDebugBG::getDefaultThread(THR_ID &default_tid) {
398       default_tid = initial_thread->getTid();
399       return true;
400     }
401
402
403     unsigned ProcDebugBG::getAddressWidth() {
404       return sizeof(DebuggerInterface::BG_Addr_t);
405     }
406
407
408     bool ProcDebugBG::debug_continue(ThreadState *ts) {
409       return debug_continue_with(ts, 0);
410     }
411
412
413     ProcDebugBG::~ProcDebugBG() {
414       if (read_cache) delete [] read_cache;
415     }
416
417
418     ProcDebugBG::ProcDebugBG(PID pid, string exe)
419       : ProcDebug(pid, exe),
420         mem_data(NULL),
421         read_cache(NULL),
422         read_cache_start(0x0),
423         read_cache_size(0x0),
424         detached(false),
425         write_ack(false),
426         wrote_trap(false)
427     {
428     }
429
430
431     bool ProcDebugBG::debug_create(std::string, const std::vector<std::string> &)
432     {
433       setLastError(err_unsupported, "Create mode not supported on BlueGene");
434       return false;
435     }
436
437
438     struct set_gprs {
439       bool val;
440       set_gprs(bool v) : val(v) { }
441       void operator()(ThreadState *ts) {
442         dynamic_cast<BGThreadState*>(ts)->gprs_set = val;
443       }
444     };
445
446
447     void ProcDebugBG::clear_cache() {
448       for_all_threads(set_gprs(false));
449       read_cache_start = 0x0;
450       read_cache_size = 0x0;
451       mem_data = NULL;
452     }
453
454
455     bool ProcDebugBG::version_msg()
456     {
457       bool result = debug_version_msg();
458       if (!result) {
459         sw_printf("[%s:%u] - Could not version msg debugee %d\n", FILE__, __LINE__, pid);
460         return false;
461       }
462
463       result = debug_waitfor_version_msg();
464       if (state() == ps_exited) {
465         setLastError(err_procexit, "Process exited unexpectedly during version_msg");
466         return false;
467       }
468       if (!result) {
469         sw_printf("[%s:%u] - Error during process version_msg for %d\n",
470                   FILE__, __LINE__, pid);
471         return false;
472       }
473       return true;
474     }
475
476
477     bool ProcDebugBG::debug_waitfor_version_msg() {
478       sw_printf("[%s:%u] - At debug_waitfor_Version_msg.\n", FILE__, __LINE__);
479       bool handled, result;
480
481       result = debug_wait_and_handle(true, false, handled);
482       if (!result || state() == ps_errorstate) {
483         sw_printf("[%s:%u] - Error,  Process %d errored during version_msg\n",
484                   FILE__, __LINE__, pid);
485         return false;
486       }
487       if (state() == ps_exited) {
488         sw_printf("[%s:%u] - Error.  Process %d exited during version_msg\n",
489                   FILE__, __LINE__, pid);
490         return false;
491       }
492       sw_printf("[%s:%u] - Successfully version_msg %d\n",
493                 FILE__, __LINE__, pid);
494       return true;
495     }
496
497
498
499     bool ProcDebugBG::debug_handle_event(DebugEvent ev)
500     {
501       BGThreadState *thr = dynamic_cast<BGThreadState*>(ev.thr);
502
503       switch (ev.dbg) {
504       case dbg_stopped:
505         // we got a signal from the process.  Stop all the threads and let
506         // debug_handle_signal() take care of things.
507         for_all_threads(set_stopped(true));
508         return debug_handle_signal(&ev);
509
510       case dbg_crashed:
511         sw_printf("[%s:%u] - Process %d crashed!\n", FILE__, __LINE__, pid);
512         // fallthru
513
514       case dbg_exited:
515         sw_printf("[%s:%u] - Handling process exit on %d\n", FILE__, __LINE__, pid);
516         for_all_threads(set_stopped(true));
517         for_all_threads(set_state(ps_exited));
518         break;
519
520       case dbg_continued:
521         sw_printf("[%s:%u] - Process %d continued\n", FILE__, __LINE__, pid);
522         clear_cache();
523         assert(thr->isStopped());
524         for_all_threads(set_stopped(false));
525         break;
526
527       case dbg_attached:
528         sw_printf("[%s:%u] - Process %d attached\n", FILE__, __LINE__, pid);
529         assert(state() == ps_neonatal);
530         for_all_threads(set_state(ps_attached_intermediate));
531         debug_pause(NULL); //immediately after debug_attach, pause the process.
532         break;
533       case dbg_detached:
534         sw_printf("[%s:%u] - Process %d detached\n", FILE__, __LINE__, pid);
535         detached = true;
536         break;
537
538       case dbg_mem_ack:
539         sw_printf("[%s:%u] - Process %d returned a memory chunk of size %u\n",
540                   FILE__, __LINE__, pid, ev.size);
541         assert(!mem_data);
542         mem_data = static_cast<BG_Debugger_Msg::DataArea*>(ev.data.pdata);
543         break;
544
545       case dbg_setmem_ack:
546         sw_printf("[%s:%u] - Process %d set a chunk of memory of size %u\n",
547                   FILE__, __LINE__, pid, ev.size);
548         write_ack = true;
549         break;
550
551       case dbg_allregs_ack:
552         {
553           sw_printf("[%s:%u] - Process %d returned a register chunk of size %u\n",
554                     FILE__, __LINE__, pid, ev.size);
555           BG_GPRSet_t *data = static_cast<BG_GPRSet_t*>(ev.data.pdata);
556           thr->gprs = *data;
557           thr->gprs_set = true;
558           ev.data.pdata = NULL;
559           delete data;
560         }
561         break;
562       case dbg_setreg_ack:
563         {
564           sw_printf("[%s:%u] - Handling set reg ack on process %d\n",
565                     FILE__, __LINE__, pid);
566           thr->write_ack = true;
567           break;
568         }
569       case dbg_other:
570         sw_printf("[%s:%u] - Skipping unimportant event\n", FILE__, __LINE__);
571         break;
572
573       case dbg_err:
574       case dbg_noevent:
575       default:
576         sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d\n",
577                   FILE__, __LINE__, ev.dbg, pid);
578         setLastError(err_internal, "Told to handle an unexpected event.");
579         return false;
580       }
581
582       return true;
583     }
584
585
586     bool ProcDebugBG::debug_handle_signal(DebugEvent *ev) {
587       assert(ev->dbg == dbg_stopped);
588       // PRE: we got a signal event, and things are stopped.
589
590       sw_printf("[%s:%u] - Handling signal for pid %d\n", FILE__, __LINE__, pid);
591       BGThreadState *thr = dynamic_cast<BGThreadState*>(ev->thr);
592
593       switch (ev->data.idata) {
594       case SIGSTOP:
595         // if we're attaching, SIGSTOP tells us we've completed.
596         if (state() == ps_attached_intermediate) {
597           setState(ps_attached);
598           sw_printf("[%s:%u] - Moving %d to state ps_attached\n", FILE__, __LINE__, pid);
599         }
600         // if we're not attaching, do nothing.  leave the thread stopped.
601         break;
602
603       case SINGLE_STEP_SIG:
604         // BG uses this special signal to indicate completion of a single step.
605         // Ignore the event and continue if the user didn't stop. TODO: why?
606         // Otherwise, if *we* stopped, just stay stopped.
607         clear_cache();  // took a step, need to clear cache.
608         return thr->userIsStopped() ? true : debug_continue_with(thr, 0);
609         break;
610
611       default:
612         // by default, pass the signal back to the process being debugged.
613         if (sigfunc) {
614            bool user_stopped = ev->thr->userIsStopped();
615            ev->thr->setUserStopped(true);
616            sigfunc(ev->data.idata, ev->thr);
617            ev->thr->setUserStopped(user_stopped);
618         }
619         return debug_continue_with(thr, ev->data.idata);
620       }
621
622       return true;
623     }
624
625
626     bool ProcDebugBG::debug_attach(ThreadState *ts)
627     {
628       THR_ID tid = ts->getTid();
629       BG_Debugger_Msg msg(ATTACH, pid, tid, 0, 0);
630       msg.header.dataLength = sizeof(msg.dataArea.ATTACH);
631
632       // send attach message
633       sw_printf("[%s:%u] - Attaching to pid %d, thread %d\n", FILE__, __LINE__, pid, tid);
634       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
635       if (!result) {
636         sw_printf("[%s:%u] - Error sending attach to process %d, thread %d\n",
637                   FILE__, __LINE__, pid, tid);
638       }
639
640       return result;
641     }
642
643     bool ProcDebugBG::cleanOnDetach() {
644       //Overridden on BG/P
645       return true;
646     }
647
648     bool ProcDebugBG::detach(bool /*leave_stopped*/) {
649       // TODO: send detach message
650       sw_printf("[%s:%u] - Detaching from process %d\n", FILE__, __LINE__,
651                 pid);
652       bool result = cleanOnDetach();
653       if (!result) {
654         sw_printf("[%s:%u] - Failed to clean process %d\n",
655                   FILE__, __LINE__, pid);
656         return false;
657       }
658
659       result = resume();
660       if (!result) {
661         sw_printf("[%s:%u] - Error resuming process before detach\n");
662       }
663
664       BG_Debugger_Msg msg(DETACH, pid, 0, 0, 0);
665       msg.header.dataLength = sizeof(msg.dataArea.DETACH);
666       result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
667       if (!result) {
668         sw_printf("[%s:%u] - Failed to write detach to process %d\n",
669                   FILE__, __LINE__, pid);
670         setLastError(err_internal, "Could not write to debug pipe\n");
671         return false;
672       }
673       while (!detached) {
674         bool handled;
675         bool result = debug_wait_and_handle(true, false, handled);
676         if (!result) {
677           sw_printf("[%s:%u] - Error while waiting for detach\n",
678                     FILE__, __LINE__);
679             return false;
680         }
681       }
682       return true;
683     }
684
685
686     bool ProcDebugBG::debug_pause(ThreadState *ts)
687     {
688       THR_ID tid = initial_thread->getTid();  // default to initial thread.
689       if (ts) tid = ts->getTid();
690
691       BG_Debugger_Msg msg(KILL, pid, tid, 0, 0);
692       msg.dataArea.KILL.signal = SIGSTOP;
693       msg.header.dataLength = sizeof(msg.dataArea.KILL);
694
695       sw_printf("[%s:%u] - Sending SIGSTOP to pid %d, thread %d\n", FILE__, __LINE__, pid, tid);
696       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
697       if (!result) {
698         sw_printf("[%s:%u] - Unable to send SIGSTOP to process %d, thread\n", FILE__, __LINE__, pid, tid);
699       }
700       return result;
701     }
702
703
704     bool ProcDebugBG::debug_continue_with(ThreadState *ts, long sig)
705     {
706       THR_ID tid = ts->getTid();
707       if (!ts->isStopped()) {
708         sw_printf("[%s:%u] - Error in debug_continue_with(): pid %d, thread %d not stopped.\n",
709                   FILE__, __LINE__, pid, tid);
710         return false;
711       }
712
713       BG_Debugger_Msg msg(CONTINUE, pid, tid, 0, 0);
714       msg.dataArea.CONTINUE.signal = sig;
715       msg.header.dataLength = sizeof(msg.dataArea.CONTINUE);
716
717       sw_printf("[%s:%u] - Sending signal %d to pid %d, thread %d\n", FILE__, __LINE__, sig, pid, tid);
718       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
719       if (!result) {
720         sw_printf("[%s:%u] - Unable to send %d to process %d, thread %d\n", FILE__, __LINE__, sig, pid, tid);
721       }
722       return result;
723     }
724
725
726     bool ProcDebugBG::getRegValue(MachRegister reg, THR_ID tid, MachRegisterVal &val) {
727       assert(threads.count(tid));
728       BGThreadState *thr = dynamic_cast<BGThreadState*>(threads[tid]);
729
730       if (!thr->gprs_set) {
731         BG_Debugger_Msg msg(GET_ALL_REGS, pid, tid, 0, 0);
732         msg.header.dataLength = sizeof(msg.dataArea.GET_ALL_REGS);
733
734         bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
735         if (!result) {
736           sw_printf("[%s:%u] - Unable to write to process %d, thread %d\n",
737                     FILE__, __LINE__, pid, tid);
738           return true;
739         }
740
741         //Wait for the read to return
742         sw_printf("[%s:%u] - Waiting for read to return on pid %d, tid %d\n",
743                   FILE__, __LINE__, pid, tid);
744
745         do {
746           bool handled, result;
747           result = debug_wait_and_handle(true, false, handled);
748           if (!result)
749           {
750             sw_printf("[%s:%u] - Error while waiting for read to return\n",
751                       FILE__, __LINE__);
752             return false;
753           }
754         } while (!thr->gprs_set);
755       }
756
757       switch(reg.val())
758       {
759          case Dyninst::iReturnAddr:
760          case Dyninst::ppc32::ipc:
761             val = thr->gprs.iar;
762             break;
763          case Dyninst::iFrameBase:
764          case Dyninst::ppc32::ir1:
765             val = thr->gprs.gpr[BG_GPR1];
766             break;
767          case Dyninst::iStackTop:
768             val = 0x0;
769             break;
770          default:
771             sw_printf("[%s:%u] - Request for unsupported register %d\n", FILE__, __LINE__, reg.name().c_str());
772             setLastError(err_badparam, "Unknown register passed in reg field");
773             return false;
774       }
775       return true;
776     }
777
778
779
780     bool ProcDebugBG::setRegValue(MachRegister reg, THR_ID tid, MachRegisterVal val) {
781       assert(threads.count(tid));
782       BGThreadState *thr = dynamic_cast<BGThreadState*>(threads[tid]);
783
784       BG_Debugger_Msg msg(SET_REG, pid, tid, 0, 0);
785       msg.header.dataLength = sizeof(msg.dataArea.SET_REG);
786       msg.dataArea.SET_REG.value = val;
787       switch(reg.val())
788       {
789          case Dyninst::iFrameBase:
790          case Dyninst::ppc32::ir1:
791             msg.dataArea.SET_REG.registerNumber = BG_GPR1;
792             break;
793          case Dyninst::iReturnAddr:
794          case Dyninst::ppc32::ipc:
795             msg.dataArea.SET_REG.registerNumber = BG_IAR;
796             break;
797          default:
798             sw_printf("[%s:%u] - Request for unsupported register %s\n", FILE__, __LINE__, reg.name().c_str());
799             setLastError(err_badparam, "Unknown register passed in reg field");
800             return false;
801       }
802       thr->write_ack = false;
803       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
804       if (!result) {
805         sw_printf("[%s:%u] - Unable to set reg to process %d, thread %d\n",
806                   FILE__, __LINE__, pid, tid);
807         return true;
808       }
809
810       //Wait for the read to return
811       sw_printf("[%s:%u] - Waiting for set reg to return on pid %d, tid %d\n",
812                 FILE__, __LINE__, pid, tid);
813
814       do {
815         bool handled, result;
816         result = debug_wait_and_handle(true, false, handled);
817         if (!result)
818           {
819             sw_printf("[%s:%u] - Error while waiting for read to return\n",
820                       FILE__, __LINE__);
821             return false;
822           }
823       } while (!thr->write_ack);
824
825       return true;
826     }
827
828     bool ProcDebugBG::readMem(void *dest, Address source, size_t size)
829     {
830       unsigned char *ucdest = (unsigned char *) dest;
831       bool result;
832
833       for (;;)
834       {
835         if (size == 0)
836           return true;
837
838         sw_printf("[%s:%u] - Reading memory from 0x%lx to 0x%lx (into %p)\n",
839                   FILE__, __LINE__, source, source+size, ucdest);
840         if (source >= read_cache_start &&
841             source+size < read_cache_start + read_cache_size)
842         {
843           //Lucky us, we have everything cached.
844           memcpy(ucdest, read_cache + (source - read_cache_start), size);
845           return true;
846         }
847         if (source >= read_cache_start &&
848             source < read_cache_start + read_cache_size)
849         {
850           //The beginning is in the cache, read those bytes
851           long cached_bytes = read_cache_start + read_cache_size - source;
852           memcpy(ucdest, read_cache + (source - read_cache_start), cached_bytes);
853           //Change the parameters and continue the read (this is a kind of
854           // optimized tail call).
855           ucdest += cached_bytes;
856           source = read_cache_start + read_cache_size;
857           size -= cached_bytes;
858           continue;
859         }
860         if (source+size > read_cache_start &&
861             source+size <= read_cache_start + read_cache_size)
862         {
863           //The end is in the cache, read those bytes
864           long cached_bytes = (source+size) - read_cache_start;
865           memcpy(ucdest + read_cache_start - source, read_cache, cached_bytes);
866           //Change the parameters and continue the read (this is a kind of
867           // optimized tail call).
868           size -= cached_bytes;
869           continue;
870         }
871         if (source < read_cache_start &&
872             source+size >= read_cache_start+read_cache_size)
873         {
874           //The middle is in the cache
875           unsigned char *dest_start = ucdest + read_cache_start - source;
876           Address old_read_cache_start = read_cache_start;
877           memcpy(dest_start, read_cache, read_cache_size);
878           //Use actual recursion here, as we need to queue up two reads
879           // First read out of the high memory with recursion
880           result = readMem(dest_start + read_cache_size,
881                            read_cache_start+read_cache_size,
882                            source+size - read_cache_start+read_cache_size);
883           if (!result) {
884             return false;
885           }
886           // Now read out of the low memory
887           size = old_read_cache_start - source;
888           continue;
889         }
890         //The memory isn't cached, read a new cache'd page.
891         assert(source < read_cache_start ||
892                source >= read_cache_start+read_cache_size);
893
894         if (!read_cache) {
895           read_cache = new unsigned char[BG_READCACHE_SIZE];
896           assert(read_cache);
897         }
898
899         read_cache_size = BG_READCACHE_SIZE;
900         read_cache_start = source - (source % read_cache_size);
901         sw_printf("[%s:%u] - Caching memory from 0x%lx to 0x%lx\n",
902                   FILE__, __LINE__, read_cache_start,
903                   read_cache_start+read_cache_size);
904
905         //Read read_cache_start to read_cache_start+read_cache_size into our
906         // cache.
907         assert(!mem_data);
908         assert(read_cache_size < BG_Debugger_Msg_MAX_MEM_SIZE);
909
910         BG_Debugger_Msg msg(GET_MEM, pid, 0, 0, 0);
911         msg.header.dataLength = sizeof(msg.dataArea.GET_MEM);
912         msg.dataArea.GET_MEM.addr = read_cache_start;
913         msg.dataArea.GET_MEM.len = read_cache_size;
914         bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
915         if (!result) {
916           sw_printf("[%s:%u] - Unable to write to process %d\n", FILE__, __LINE__, pid);
917           return true;
918         }
919
920         //Wait for the read to return
921         sw_printf("[%s:%u] - Waiting for read to return on pid %d\n", FILE__, __LINE__);
922
923         if (!debug_waitfor(dbg_mem_ack)) {
924           sw_printf("[%s:%u] - Error while waiting for read to return\n", FILE__, __LINE__);
925           return false;
926         }
927
928         sw_printf("[%s:%u] - Asserting mem_data post-read.\n", FILE__, __LINE__);
929         assert(mem_data->GET_MEM_ACK.addr == read_cache_start);
930         assert(mem_data->GET_MEM_ACK.len == read_cache_size);
931         memcpy(read_cache, mem_data->GET_MEM_ACK.data, read_cache_size);
932
933         //Free up the memory data
934         delete mem_data;
935         mem_data = NULL;
936       }
937     }
938
939
940     bool ProcDebugBG::debug_version_msg()
941     {
942       BG_Debugger_Msg msg(VERSION_MSG, pid, 0, 0, 0);
943       msg.header.dataLength = sizeof(msg.dataArea.VERSION_MSG);
944
945       sw_printf("[%s:%u] - Sending VERSION_MSG to pid %d\n", FILE__, __LINE__, pid);
946       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
947
948       if (!result) {
949         sw_printf("[%s:%u] - Unable to send VERSION_MSG to process %d\n",
950                   FILE__, __LINE__, pid);
951         return false;
952       }
953       return true;
954     }
955
956     // ============================================================ //
957     // SymtabLibState -- need to differentiate for P
958     // ============================================================ //
959      bool LibraryState::updateLibsArch(vector<pair<LibAddrPair, unsigned int> > &)
960      {
961         return true;
962      }
963
964
965     // ============================================================ //
966     // ThreadState
967     // ============================================================ //
968     ThreadState* ThreadState::createThreadState(ProcDebug *parent, Dyninst::THR_ID tid, bool) {
969       THR_ID thread_id = tid;
970       if (thread_id == NULL_THR_ID) {
971         thread_id = 0;
972       }
973       BGThreadState *ts = new BGThreadState(parent, thread_id);
974       return ts;
975     }
976
977     void BottomOfStackStepperImpl::initialize()
978     {
979     }
980
981      Dyninst::Architecture ProcDebug::getArchitecture()
982      {
983         return Dyninst::Arch_ppc32;
984      }
985
986      void BottomOfStackStepperImpl::newLibraryNotification(LibAddrPair *, lib_change_t change)
987      {
988         if (change == library_unload)
989            return;
990         if (!libthread_init || !aout_init) {
991            initialize();
992         }
993      }
994
995      SymbolReaderFactory *getDefaultSymbolReader()
996      {
997         static SymElfFactory symelffact;
998         if (!Walker::symrfact)
999            Walker::symrfact = (SymbolReaderFactory *) &symelffact;
1000         return Walker::symrfact;
1001      }
1002   } // namespace Stackwalker
1003 } // namespace Dyninst
1004