Working towards getting pc_irpc test working on FreeBSD
[dyninst.git] / proccontrol / src / freebsd.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 "dynutil/h/dyn_regs.h"
33 #include "dynutil/h/dyntypes.h"
34 #include "proccontrol/h/PCErrors.h"
35 #include "proccontrol/h/Generator.h"
36 #include "proccontrol/h/Event.h"
37 #include "proccontrol/h/Handler.h"
38 #include "proccontrol/src/procpool.h"
39 #include "proccontrol/src/irpc.h"
40 #include "proccontrol/src/snippets.h"
41 #include "proccontrol/src/freebsd.h"
42 #include "proccontrol/src/int_handler.h"
43 #include "common/h/freebsdKludges.h"
44
45 // System includes
46 #include <sys/syscall.h>
47 #include <sys/types.h>
48 #include <sys/wait.h>
49 #include <sys/time.h>
50 #include <sys/resource.h>
51 #include <signal.h>
52 #include <sys/ptrace.h>
53 #include <machine/reg.h>
54 #include <sched.h>
55
56 #if defined(arch_x86) || defined(arch_x86_64)
57 #include <machine/psl.h>
58 #endif
59
60 #include <cassert>
61 #include <cerrno>
62
63 #include <map>
64 using std::make_pair;
65
66 using namespace Dyninst;
67 using namespace ProcControlAPI;
68
69 #define NA_FREEBSD "This function is not implemented on FreeBSD"
70
71 Generator *Generator::getDefaultGenerator() {
72     static GeneratorFreeBSD *gen = NULL;
73     if( NULL == gen ) {
74         gen = new GeneratorFreeBSD();
75         assert(gen);
76         gen->launch();
77     }
78     return static_cast<Generator *>(gen);
79 }
80
81 GeneratorFreeBSD::GeneratorFreeBSD() :
82     GeneratorMT(std::string("FreeBSD Generator"))
83 {
84     decoders.insert(new DecoderFreeBSD());
85 }
86
87 GeneratorFreeBSD::~GeneratorFreeBSD()
88 {
89 }
90
91 bool GeneratorFreeBSD::initialize() {
92     return true;
93 }
94
95 bool GeneratorFreeBSD::canFastHandle() {
96     return false;
97 }
98
99 ArchEvent *GeneratorFreeBSD::getEvent(bool block) {
100     int status, options;
101
102     // Block (or not block) in waitpid to receive a OS event
103     options = block ? 0 : WNOHANG;
104     pthrd_printf("%s in waitpid\n", block ? "blocking" : "polling");
105     int pid = waitpid(-1, &status, options);
106     lwpid_t lwp = NULL_LWP;
107
108     ArchEventFreeBSD *newevent = NULL;
109     if (pid == -1) {
110         int errsv = errno;
111         if (errsv == EINTR) {
112             pthrd_printf("waitpid interrupted\n");
113             newevent = new ArchEventFreeBSD(true);
114             return newevent;
115         }
116         perr_printf("Error. waitpid recieved error %s\n", strerror(errsv));
117         newevent = new ArchEventFreeBSD(errsv);
118         return newevent;
119     }
120
121     if (dyninst_debug_proccontrol)
122     {
123         pthrd_printf("Waitpid return status %x for pid %d:\n", status, pid);
124         if (WIFEXITED(status))
125             pthrd_printf("Exited with %d\n", WEXITSTATUS(status));
126         else if (WIFSIGNALED(status))
127             pthrd_printf("Exited with signal %d\n", WTERMSIG(status));
128         else if (WIFSTOPPED(status))
129             pthrd_printf("Stopped with signal %d\n", WSTOPSIG(status));
130 #if defined(WIFCONTINUED)
131         else if (WIFCONTINUED(status))
132             perr_printf("Continued with signal SIGCONT (Unexpected)\n");
133 #endif
134         else
135             pthrd_printf("Unable to interpret waitpid return.\n");
136     }
137
138     // On FreeBSD, we need to get information about the thread that caused the
139     // stop via ptrace -- try for all cases; the ptrace call will fail for some
140     struct ptrace_lwpinfo lwpInfo;
141     if( 0 == ptrace(PT_LWPINFO, pid, (caddr_t)&lwpInfo, sizeof(struct ptrace_lwpinfo)) ) {
142         lwp = lwpInfo.pl_lwpid;
143     }else{
144         int errsv = errno;
145         pthrd_printf("Failed to retrieve lwp for pid %d: %s\n", pid, strerror(errsv));
146
147         // It's an error for a stopped process
148         if( WIFSTOPPED(status) ) {
149             newevent = new ArchEventFreeBSD(errsv);
150             return newevent;
151         }
152     }
153
154     newevent = new ArchEventFreeBSD(pid, lwp, status);
155     return newevent;
156 }
157
158 ArchEventFreeBSD::ArchEventFreeBSD(bool inter_) :
159     status(0),
160     pid(NULL_PID),
161     lwp(NULL_LWP),
162     interrupted(inter_),
163     error(0)
164 {
165 }
166
167 ArchEventFreeBSD::ArchEventFreeBSD(pid_t p, lwpid_t l, int s) :
168     status(s),
169     pid(p),
170     lwp(l),
171     interrupted(false),
172     error(0)
173 {
174 }
175
176 ArchEventFreeBSD::ArchEventFreeBSD(int e) :
177     status(0),
178     pid(NULL_PID),
179     lwp(NULL_LWP),
180     interrupted(false),
181     error(e)
182 {
183 }
184       
185 ArchEventFreeBSD::~ArchEventFreeBSD()
186 {
187 }
188
189 DecoderFreeBSD::DecoderFreeBSD() 
190 {
191 }
192
193 DecoderFreeBSD::~DecoderFreeBSD()
194 {
195 }
196
197 unsigned DecoderFreeBSD::getPriority() const
198 {
199     return Decoder::default_priority;
200 }
201
202 Dyninst::Address DecoderFreeBSD::adjustTrapAddr(Dyninst::Address addr, Dyninst::Architecture arch)
203 {
204     if( arch == Dyninst::Arch_x86 || arch == Dyninst::Arch_x86_64 ) {
205         return addr - 1;
206     }
207
208     return addr;
209 }
210
211 bool DecoderFreeBSD::decode(ArchEvent *ae, std::vector<Event::ptr> &events) {
212     ArchEventFreeBSD *archevent = static_cast<ArchEventFreeBSD *>(ae);
213
214     int_process *proc = NULL;
215     int_thread *thread = NULL;
216     freebsd_process *lproc = NULL;
217     freebsd_thread *lthread = NULL;
218
219     proc = ProcPool()->findProcByPid(archevent->pid);
220
221     /* ignore any events we get for processes we don't know anything about.
222      * This occurs for a double exit event as described below near
223      * WIFEXITED
224      */
225     if( !proc ) {
226         pthrd_printf("Ignoring ArchEvent for unknown process with PID %d\n",
227                 archevent->pid);
228         return true;
229     }
230
231     lproc = static_cast<freebsd_process *>(proc);
232
233     thread = ProcPool()->findThread(archevent->lwp);
234
235     // If the ArchEvent did not set the LWP, assign the event to the initial thread
236     if( !thread ) {
237         thread = proc->threadPool()->initialThread();
238     }
239     lthread = static_cast<freebsd_thread *>(thread);
240
241     Event::ptr event;
242
243     pthrd_printf("Decoding event for %d/%d\n", proc ? proc->getPid() : -1,
244             thread ? thread->getLWP() : -1);
245
246     const int status = archevent->status;
247     bool result = false;
248     bool multipleEvents = false;
249     if( WIFSTOPPED(status) ) {
250         const int stopsig = WSTOPSIG(status);
251
252         pthrd_printf("Decoded to signal %s\n", strsignal(stopsig));
253         switch( stopsig ) {
254             case SIGSTOP: {
255                 if( lthread->hasPendingStop() || lthread->hasBootstrapStop() ) {
256                     pthrd_printf("Received pending stop on %d/%d\n",
257                                  lthread->llproc()->getPid(), lthread->getLWP());
258                     event = Event::ptr(new EventStop());
259                     break;
260                 }
261
262                 if( proc->getState() != int_process::neonatal_intermediate ) {
263                     lthread->setBootstrapStop(true);
264                     event = Event::ptr(new EventStop());
265                     break;
266                 }
267
268                 assert( proc->getState() == int_process::neonatal_intermediate );
269                 // Relying on fall through for bootstrap
270             }
271             case SIGTRAP: {
272                 if( proc->getState() == int_process::neonatal_intermediate) {
273                     pthrd_printf("Decoded event to bootstrap on %d/%d\n",
274                             proc->getPid(), thread->getLWP());
275                     event = Event::ptr(new EventBootstrap());
276                     break;
277                 }
278
279                 Dyninst::MachRegisterVal addr;
280                 result = thread->getRegister(MachRegister::getPC(proc->getTargetArch()), addr);
281                 if( !result ) {
282                     perr_printf("Failed to read PC address upon SIGTRAP\n");
283                     return false;
284                 }
285
286                 Dyninst::Address adjusted_addr = adjustTrapAddr(addr, proc->getTargetArch());
287
288                 // Check if it is a RPC
289                 if (rpcMgr()->isRPCTrap(thread, adjusted_addr)) {
290                    pthrd_printf("Decoded event to rpc completion on %d/%d at %lx\n",
291                                 proc->getPid(), thread->getLWP(), adjusted_addr);
292                    event = Event::ptr(new EventRPC(thread->runningRPC()->getWrapperForDecode()));
293                    break;
294                 }
295
296                 // Check if it is a breakpoint
297                 installed_breakpoint *ibp = proc->getBreakpoint(adjusted_addr);
298                 if( ibp && ibp != thread->isClearingBreakpoint() ) {
299                     pthrd_printf("Decoded breakpoint on %d/%d at %lx\n", proc->getPid(),
300                             thread->getLWP(), adjusted_addr);
301                     event = Event::ptr(new EventBreakpoint(adjusted_addr, ibp));
302
303                     if( adjusted_addr == lproc->getLibBreakpointAddr() ) {
304                         pthrd_printf("Breakpoint is library load/unload\n");
305                         Event::ptr lib_event = Event::ptr(new EventLibrary());
306                         lib_event->setThread(thread->thread());
307                         lib_event->setProcess(proc->proc());
308                         event->addSubservientEvent(lib_event);
309                     }else{
310                         // Check for thread events
311                         vector<Event::ptr> threadEvents;
312                         if( lproc->getEventsAtAddr(adjusted_addr, lthread, threadEvents) ) {
313                             vector<Event::ptr>::iterator threadEventIter;
314                             for(threadEventIter = threadEvents.begin(); threadEventIter != threadEvents.end();
315                                     ++threadEventIter)
316                             {
317                                 // An event is created for the initial thread, but this thread is already
318                                 // created during bootstrap. Ignore any create events for threads that
319                                 // are already created.
320                                 if( (*threadEventIter)->getEventType().code() == EventType::ThreadCreate ) {
321                                     Dyninst::LWP createdLWP = (*threadEventIter)->getEventNewThread()->getLWP();
322                                     int_thread * newThread = ProcPool()->findThread(createdLWP);
323                                     if( NULL != newThread ) {
324                                         freebsd_thread *newlThread = static_cast<freebsd_thread *>(newThread);
325                                         pthrd_printf("Thread already created for LWP %d\n", createdLWP);
326
327                                         if( !newlThread->plat_resume() ) {
328                                             perr_printf("Failed to resume already created LWP %d\n", createdLWP);
329                                             return false;
330                                         }
331
332                                         // Still need to enable events for it -- this can't be done during
333                                         // bootstrap because the thread_db library isn't guaranteed to 
334                                         // be initialized at bootstrap
335                                         newlThread->setEventReporting(true);
336                                         continue;
337                                     }
338                                 }
339
340                                 (*threadEventIter)->setThread(thread->thread());
341                                 (*threadEventIter)->setProcess(proc->proc());
342                                 event->addSubservientEvent(*threadEventIter);
343                             }
344                         }
345                     }
346                     break;
347                 }
348
349                 if( thread->singleStep() ) {
350                     ibp = thread->isClearingBreakpoint();
351                     if( ibp ) {
352                         pthrd_printf("Decoded event to breakpoint cleanup\n");
353                         event = Event::ptr(new EventBreakpointClear(ibp));
354
355                         // For a thread_db_process, post-ThreadDestroy events happen
356                         // after a BreakpointClear
357                         vector<Event::ptr> destroyEvents;
358                         if( lproc->getPostDestroyEvents(destroyEvents) ) {
359                             vector<Event::ptr>::iterator eventIter;
360                             for(eventIter = destroyEvents.begin(); eventIter != destroyEvents.end(); ++eventIter) {
361                                 event->addSubservientEvent(*eventIter);
362                             }
363                         }
364
365                         break;
366                     }else{
367                         pthrd_printf("Decoded event to single step on %d/%d\n",
368                                 proc->getPid(), thread->getLWP());
369                         event = Event::ptr(new EventSingleStep());
370                         break;
371                     }
372                 }else{
373                     // TODO for now, just assume that a call to exec happened
374                     // In the future, if we need to trace syscalls, we will
375                     // need to differentiate between different syscalls
376                     //
377                     // breadcrumb: 
378                     // truss(1) does system call identification after a SIGTRAP
379                     pthrd_printf("Decoded event to exec on %d/%d\n",
380                             proc->getPid(), thread->getLWP());
381                     event = Event::ptr(new EventExec(EventType::Post));
382                     event->setSyncType(Event::sync_process);
383                 }
384                 break;
385             }
386             default:
387                 pthrd_printf("Decoded event to signal %d on %d/%d\n",
388                         stopsig, proc->getPid(), thread->getLWP());
389 #if 1
390                 //Debugging code
391                 if (stopsig == SIGSEGV) {
392                    Dyninst::MachRegisterVal addr;
393                    result = thread->getRegister(MachRegister::getPC(proc->getTargetArch()), addr);
394                    if (!result) {
395                       fprintf(stderr, "Failed to read PC address upon crash\n");
396                    }
397                    fprintf(stderr, "Got crash at %lx\n", addr);
398
399                    fprintf(stderr, "Sending SIGABRT to %d\n", proc->getPid());
400                    ptrace(PT_CONTINUE, proc->getPid(), (caddr_t)1, SIGABRT);
401
402                    while(1) sleep(1);
403                 }
404 #endif
405                 event = Event::ptr(new EventSignal(stopsig));
406                 break;
407         }
408     }
409     else if (WIFEXITED(status) || WIFSIGNALED(status)) {
410         if( WIFEXITED(status) ) {
411             int exitcode = WEXITSTATUS(status);
412             /*
413              * On FreeBSD, an exit of a traced process is reported to both its original
414              * parent and the tracing process. When the traced process is created by a
415              * ProcControlAPI process, ProcControlAPI will receive two copies of the exit
416              * event. The second event should be ignored.
417              */
418             if( int_thread::exited == thread->getGeneratorState() ) {
419                 pthrd_printf("Decoded duplicate exit event of process %d/%d with code %d\n",
420                         proc->getPid(), thread->getLWP(), exitcode);
421                 return true;
422             }
423
424             pthrd_printf("Decoded event to exit of process %d/%d with code %d\n",
425                     proc->getPid(), thread->getLWP(), exitcode);
426             event = Event::ptr(new EventExit(EventType::Post, exitcode));
427         }else{
428             int termsig = WTERMSIG(status);
429             pthrd_printf("Decoded event to crash of %d/%d with signal %d\n",
430                     proc->getPid(), thread->getLWP(), termsig);
431             event = Event::ptr(new EventCrash(termsig));
432         }
433         event->setSyncType(Event::sync_process);
434
435         int_threadPool::iterator i = proc->threadPool()->begin();
436         for(; i != proc->threadPool()->end(); ++i) {
437             (*i)->setGeneratorState(int_thread::exited);
438         }
439     }
440
441     if( !multipleEvents ) {
442         assert(event);
443         assert(proc->proc());
444         assert(thread->thread());
445
446         // All signals stop a process in FreeBSD
447         if( event && event->getSyncType() == Event::unset)
448             event->setSyncType(Event::sync_process);
449
450         event->setThread(thread->thread());
451         event->setProcess(proc->proc());
452         events.push_back(event);
453     }
454
455     delete archevent;
456
457     return true;
458 }
459
460 int_process *int_process::createProcess(Dyninst::PID pid_, std::string exec) {
461     std::vector<std::string> args;
462     freebsd_process *newproc = new freebsd_process(pid_, exec, args);
463     assert(newproc);
464
465     return static_cast<int_process *>(newproc);
466 }
467
468 int_process *int_process::createProcess(std::string exec, std::vector<std::string> args) {
469     freebsd_process *newproc = new freebsd_process(0, exec, args);
470     assert(newproc);
471     return static_cast<int_process *>(newproc);
472 }
473
474 int_process *int_process::createProcess(Dyninst::PID pid_, int_process *parent) {
475     freebsd_process *newproc = new freebsd_process(pid_, parent);
476     assert(newproc);
477     return static_cast<int_process *>(newproc);
478 }
479
480 int_process::ThreadControlMode int_process::getThreadControlMode() {
481     return int_process::HybridLWPControl;
482 }
483
484 int_thread *int_thread::createThreadPlat(int_process *proc, Dyninst::THR_ID thr_id,
485         Dyninst::LWP lwp_id, bool initial_thrd)
486 {
487     if( initial_thrd ) {
488         lwp_id = sysctl_getInitialLWP(proc->getPid());
489         if( lwp_id == -1 ) {
490             perr_printf("Failed to determine initial LWP for PID %d\n",
491                     proc->getPid());
492             assert(!"Failed to determine initial LWP");
493         }
494     }
495     freebsd_thread *lthrd = new freebsd_thread(proc, thr_id, lwp_id);
496     assert(lthrd);
497     return static_cast<int_thread *>(lthrd);
498 }
499
500 HandlerPool *plat_createDefaultHandlerPool(HandlerPool *hpool) {
501     static bool initialized = false;
502     static FreeBSDStopHandler *lstop = NULL;
503     static FreeBSDPostStopHandler *lpoststop = NULL;
504     static FreeBSDBootstrapHandler *lboot = NULL;
505     if( !initialized ) {
506         lstop = new FreeBSDStopHandler();
507         lpoststop = new FreeBSDPostStopHandler();
508         lboot = new FreeBSDBootstrapHandler();
509         initialized = true;
510     }
511     hpool->addHandler(lstop);
512     hpool->addHandler(lpoststop);
513     hpool->addHandler(lboot);
514     thread_db_process::addThreadDBHandlers(hpool);
515     return hpool;
516 }
517
518 bool ProcessPool::LWPIDsAreUnique() {
519     return true;
520 }
521
522 freebsd_process::freebsd_process(Dyninst::PID p, std::string e, std::vector<std::string> a)
523     : thread_db_process(p, e, a)
524 {
525 }
526
527 freebsd_process::freebsd_process(Dyninst::PID pid_, int_process *p) 
528     : thread_db_process(pid_, p)
529 {
530 }
531
532 freebsd_process::~freebsd_process() 
533 {
534     freeThreadDBAgent();
535 }
536
537 bool freebsd_process::plat_create() {
538     pid = fork();
539     if( -1 == pid ) {
540         int errnum = errno;
541         pthrd_printf("Could not fork new process for %s: %s\n",
542                 executable.c_str(), strerror(errnum));
543         setLastError(err_internal, "Unable to fork new process");
544         return false;
545     }
546
547     if( !pid ) {
548         // Child
549         if( 0 != ptrace(PT_TRACE_ME, 0, 0, 0) ) {
550             perr_printf("Faild to execute a PT_TRACE_ME.\n");
551             setLastError(err_internal, "Unable to debug trace new process");
552             exit(-1);
553         }
554
555         plat_execv();
556
557         exit(-1);
558     }
559
560     return true;
561 }
562
563 bool freebsd_process::plat_attach() {
564     pthrd_printf("Attaching to pid %d\n", pid);
565     if( 0 != ptrace(PT_ATTACH, pid, (caddr_t)1, 0) ) {
566         int errnum = errno;
567         pthrd_printf("Unable to attach to process %d: %s\n", pid, strerror(errnum));
568         if( EPERM == errnum ) {
569             setLastError(err_prem, "Do not have correct permissions to attach to pid");
570         }else if( ESRCH == errnum ) {
571             setLastError(err_noproc, "The specified process was not found");
572         }else {
573             setLastError(err_internal, "Unable to attach to the specified process");
574         }
575         return false;
576     }
577     return true;
578 }
579
580 bool freebsd_process::plat_forked() {
581     // TODO
582     assert(!NA_FREEBSD);
583     return false;
584 }
585
586 bool freebsd_process::post_forked() {
587     // TODO
588     assert(!NA_FREEBSD);
589     return false;
590 }
591
592 bool freebsd_process::plat_execed() { 
593     bool result = sysv_process::plat_execed();
594     if( !result ) return false;
595
596     char *pathname = sysctl_getExecPathname(getPid());
597     if( NULL == pathname ) {
598         perr_printf("Failed to retrieve executable pathname");
599         setLastError(err_internal, "Failed to retrieve executable pathname");
600         return false;
601     }
602
603     executable = pathname;
604     free(pathname);
605     return true;
606 }
607
608 bool freebsd_process::plat_detach() {
609     pthrd_printf("PT_DETACH on %d\n", getPid());
610     if( 0 != ptrace(PT_DETACH, getPid(), (caddr_t)1, 0) ) {
611         perr_printf("Failed to PT_DETACH on %d\n", getPid());
612         setLastError(err_internal, "PT_DETACH operation failed\n");
613     }
614     return true;
615 }
616
617 bool freebsd_process::plat_terminate(bool &needs_sync) {
618     pthrd_printf("Terminating process %d\n", getPid());
619     if( 0 != ptrace(PT_KILL, getPid(), (caddr_t)1, 0) ) {
620         perr_printf("Failed to PT_KILL process %d\n", getPid());
621         setLastError(err_internal, "PT_KILL operation failed\n");
622         return false;
623     }
624
625     needs_sync = true;
626     return true;
627 }
628
629 bool freebsd_process::plat_readMem(int_thread *thr, void *local, 
630                          Dyninst::Address remote, size_t size) 
631 {
632     return PtraceBulkRead(remote, size, local, thr->llproc()->getPid());
633 }
634
635 bool freebsd_process::plat_readProcMem(void *local, 
636         Dyninst::Address remote, size_t size)
637 {
638     return PtraceBulkRead(remote, size, local, getPid());
639 }
640
641 bool freebsd_process::plat_writeMem(int_thread *thr, void *local, 
642                           Dyninst::Address remote, size_t size) 
643 {
644     return PtraceBulkWrite(remote, size, local, thr->llproc()->getPid());
645 }
646
647 bool freebsd_process::plat_writeProcMem(void *local, 
648                           Dyninst::Address remote, size_t size) 
649 {
650     return PtraceBulkWrite(remote, size, local, getPid());
651 }
652
653 bool freebsd_process::needIndividualThreadAttach() {
654     // XXX
655     // Actually, no, FreeBSD doesn't need individual thread attach
656     // but the int_process code doesn't create objects for threads
657     // otherwise
658     return true;
659 }
660
661 bool freebsd_process::getThreadLWPs(std::vector<Dyninst::LWP> &lwps) {
662     return sysctl_findProcLWPs(getPid(), lwps);
663 }
664
665 Dyninst::Architecture freebsd_process::getTargetArch() {
666     if( Dyninst::Arch_none != arch ) {
667         return arch;
668     }
669     int addr_width = sysctl_computeAddrWidth(getPid());
670
671 #if defined(arch_x86) || defined(arch_x86_64)
672     assert(addr_width == 4 || addr_width == 8);
673     arch = (addr_width == 4) ? Dyninst::Arch_x86 : Dyninst::Arch_x86_64;
674 #elif defined(arch_power)
675     assert(addr_width == 4 || addr_width == 8);
676     arch = (addr_width == 4) ? Dyninst::Arch_ppc32 : Dyninst::Arch_ppc64;
677 #else
678     assert(!"Unknown architecture");
679 #endif
680     return arch;
681 }
682
683 freebsd_thread::freebsd_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l)
684     : thread_db_thread(p, t, l), bootstrap_stop(false)
685 {
686 }
687
688 freebsd_thread::~freebsd_thread() 
689 {
690 }
691
692 void freebsd_thread::setBootstrapStop(bool b) {
693     bootstrap_stop = b;
694 }
695
696 bool freebsd_thread::hasBootstrapStop() const {
697     return bootstrap_stop;
698 }
699
700 bool freebsd_process::plat_getLWPInfo(lwpid_t lwp, void *lwpInfo) {
701     pthrd_printf("Calling PT_LWPINFO on %d\n", lwp);
702     if( 0 != ptrace(PT_LWPINFO, lwp, (caddr_t)lwpInfo, sizeof(struct ptrace_lwpinfo)) ) {
703         perr_printf("Failed to get thread info for lwp %d: %s\n",
704                 lwp, strerror(errno));
705         setLastError(err_internal, "Failed to get thread info");
706         return false;
707     }
708
709     return true;
710 }
711
712 bool freebsd_process::plat_contThread(lwpid_t lwp) {
713     pthrd_printf("Calling PT_RESUME on %d\n", lwp);
714     if( 0 != ptrace(PT_RESUME, lwp, (caddr_t)1, 0) ) {
715         perr_printf("Failed to resume lwp %d: %s\n",
716                 lwp, strerror(errno));
717         setLastError(err_internal, "Failed to resume lwp");
718         return false;
719     }
720
721     return true;
722 }
723
724 bool freebsd_process::plat_stopThread(lwpid_t lwp) {
725     pthrd_printf("Calling PT_SUSPEND on %d\n", lwp);
726     if( 0 != ptrace(PT_SUSPEND, lwp, (caddr_t)1, 0) ) {
727         perr_printf("Failed to suspend lwp %d: %s\n",
728                 lwp, strerror(errno));
729         setLastError(err_internal, "Failed to suspend lwp");
730         return false;
731     }
732
733     return true;
734 }
735
736 /*
737  * Description of bug_freebsd_mt_suspend
738  *
739  * Here is the scenario:
740  *
741  * 1) The user requests an attach to a multithreaded process
742  * 2) ProcControl issues the attach and waits for the stop
743  * 3) On receiving the stop, ProcControl suspends each thread
744  *    in the process.
745  * 4) User continues a single thread but other threads which
746  *    should remain stopped continue to run
747  *
748  * This is currently an issue on FreeBSD 7.2. However, this
749  * bug has been fixed in FreeBSD 8.0 and higher.
750  *
751  * The workaround for this bug is to issue SIGSTOPs to all the
752  * threads (except the thread that received the SIGSTOP from the
753  * initial attach). Once the stops are handled, the suspend
754  * state will be honored when continuing a whole process; that is,
755  * when all threads are suspended, a continue of one thread will
756  * not continue another thread.
757  *
758  * See the following handlers and the post_attach function for
759  * more detailed comments.
760  */
761
762 FreeBSDStopHandler::FreeBSDStopHandler() 
763     : Handler("FreeBSD Stop Handler")
764 {}
765
766 FreeBSDStopHandler::~FreeBSDStopHandler()
767 {}
768
769 bool FreeBSDStopHandler::handleEvent(Event::ptr ev) {
770     freebsd_process *lproc = static_cast<freebsd_process *>(ev->getProcess()->llproc());
771     freebsd_thread *lthread = static_cast<freebsd_thread *>(ev->getThread()->llthrd());
772
773     // No extra handling is required for single-threaded debuggees
774     if( lproc->threadPool()->size() <= 1 ) return true;
775
776     if( lthread->hasPendingStop() || lthread->hasBootstrapStop() ) {
777         pthrd_printf("Thread %d/%d has a pending stop\n",
778                 lthread->proc()->getPid(), lthread->getLWP());
779         if( !lthread->plat_suspend() ) {
780             perr_printf("Failed to suspend thread %d\n", lthread->getLWP());
781             return false;
782         }
783
784         if( !lthread->plat_setStep() ) {
785             perr_printf("Failed to set single step setting for thread %d\n",
786                     lthread->getLWP());
787             return false;
788         }
789
790         // Since the default thread stop handler is being wrapped, set this flag
791         // here so the default handler doesn't have problems
792         if( lthread->hasBootstrapStop() ) {
793             lthread->setPendingStop(true);
794         }
795     }
796
797     return true;
798 }
799
800 int FreeBSDStopHandler::getPriority() const {
801     return PrePlatformPriority;
802 }
803
804 void FreeBSDStopHandler::getEventTypesHandled(std::vector<EventType> &etypes) {
805     etypes.push_back(EventType(EventType::None, EventType::Stop));
806 }
807
808 FreeBSDPostStopHandler::FreeBSDPostStopHandler() 
809     : Handler("FreeBSD Post Stop Handler")
810 {}
811
812 FreeBSDPostStopHandler::~FreeBSDPostStopHandler()
813 {}
814
815 bool FreeBSDPostStopHandler::handleEvent(Event::ptr ev) {
816     int_process *lproc = ev->getProcess()->llproc();
817
818 #if defined(bug_freebsd_mt_suspend)
819     freebsd_thread *lthread = static_cast<freebsd_thread *>(ev->getThread()->llthrd());
820     
821     if( lthread->hasBootstrapStop() ) {
822         pthrd_printf("Handling bootstrap stop on %d/%d\n",
823                 lproc->getPid(), lthread->getLWP());
824         lthread->setBootstrapStop(false);
825     }
826 #endif
827
828     return true;
829 }
830
831 int FreeBSDPostStopHandler::getPriority() const {
832     return PostPlatformPriority;
833 }
834
835 void FreeBSDPostStopHandler::getEventTypesHandled(std::vector<EventType> &etypes) {
836     etypes.push_back(EventType(EventType::None, EventType::Stop));
837 }
838
839 FreeBSDBootstrapHandler::FreeBSDBootstrapHandler() 
840     : Handler("FreeBSD Bootstrap Handler")
841 {}
842
843 FreeBSDBootstrapHandler::~FreeBSDBootstrapHandler()
844 {}
845
846 bool FreeBSDBootstrapHandler::handleEvent(Event::ptr ev) {
847     int_process *lproc = ev->getProcess()->llproc();
848 #if defined(bug_freebsd_mt_suspend)
849     int_thread *lthread = ev->getThread()->llthrd();
850
851     if( lproc->threadPool()->size() <= 1 ) return true;
852
853     // Issue SIGSTOPs to all threads except the one that received
854     // the initial attach. This acts like a barrier and gets around
855     // the bug the mt suspend bug.
856     for(int_threadPool::iterator i = lproc->threadPool()->begin(); 
857         i != lproc->threadPool()->end(); ++i)
858     {
859         freebsd_thread *bsdThread = static_cast<freebsd_thread *>(*i);
860
861         if( bsdThread->getLWP() != lthread->getLWP() ) {
862             pthrd_printf("Issuing bootstrap stop for %d/%d\n",
863                     lproc->getPid(), bsdThread->getLWP());
864             bsdThread->setBootstrapStop(true);
865
866             if( !bsdThread->plat_stop() ) {
867                 return false;
868             }
869         }
870     }
871 #endif
872
873     return true;
874 }
875
876 int FreeBSDBootstrapHandler::getPriority() const {
877     return PostPlatformPriority;
878 }
879
880 void FreeBSDBootstrapHandler::getEventTypesHandled(std::vector<EventType> &etypes) {
881     etypes.push_back(EventType(EventType::None, EventType::Bootstrap));
882 }
883
884 /*
885  * In the bootstrap handler, SIGSTOPs where issued to all threads. This function
886  * flushes out all those pending "bootstrap stops". Due to some weirdness with
887  * signals, the SIGSTOP signal needs to be resent after the process has been continued.
888  * I haven't been able to figure out why this needs to happen, but it solves the 
889  * problem at hand.
890  */
891 bool freebsd_process::post_attach() {
892     if( !thread_db_process::post_attach() ) return false;
893
894 #if defined(bug_freebsd_mt_suspend)
895     if( threadPool()->size() <= 1 ) return true;
896
897     for(int_threadPool::iterator i = threadPool()->begin(); i != threadPool()->end(); ++i) {
898         freebsd_thread *thrd = static_cast<freebsd_thread *>(*i);
899         if( thrd->hasBootstrapStop() ) {
900             pthrd_printf("attach workaround: resuming %d/%d\n",
901                     getPid(), thrd->getLWP());
902             if( !thrd->intCont() ) {
903                 return false;
904             }
905
906             thrd->setResumed(false);
907
908             pthrd_printf("attach workaround: continuing whole process\n");
909             if( !plat_contProcess() ) {
910                 return false;
911             }
912
913             pthrd_printf("attach workaround: sending stop to %d/%d\n",
914                     getPid(), thrd->getLWP());
915             if( !thrd->plat_stop() ) {
916                 return false;
917             }
918
919             pthrd_printf("attach workaround: handling stop of %d/%d\n",
920                     getPid(), thrd->getLWP());
921             if( !waitfor_startup() ) {
922                 return false;
923             }
924         }
925     }
926 #endif
927
928     return true;
929 }
930
931 bool freebsd_process::plat_contProcess() {
932     /* Single-stepping is enabled/disabled using PT_SETSTEP
933      * and PT_CLEARSTEP instead of continuing the process
934      * with PT_STEP. See plat_setStep.
935      */
936     pthrd_printf("Calling PT_CONTINUE on %d with signal %d\n", 
937                 getPid(), continueSig);
938     if (0 != ptrace(PT_CONTINUE, getPid(), (caddr_t)1, continueSig) ) {
939         perr_printf("low-level continue failed: %s\n", strerror(errno));
940         setLastError(err_internal, "Low-level continue failed");
941         return false;
942     }
943
944     //
945     // XXX
946     //
947     // This attempts to get around the bug documented in FreeBSD problem
948     // report kern/142757 -- if we yield to the scheduler, we may avoid
949     // the race condition described in this bug report.
950     //
951     // Specifically, the race condition results from the following sequence
952     // of events, where P = parent process, C = child process:
953     //
954     // P-SIGSTOP C-STOP P-WAITPID P-CONT P-SIGSTOP C-RUN
955     // 
956     // Because the child doesn't run before the parent sends the second 
957     // stop signal, the child doesn't receive the second SIGSTOP. 
958     //
959     // A workaround for this problem would guarantee that the C-RUN event
960     // always occurs before the second P-SIGSTOP. Here, the sched_yield
961     // attempts to ensure this.
962     //
963     // TODO this doesn't always solve the problem
964     
965     sched_yield();
966
967     return true;
968 }
969
970 static bool t_kill(pid_t pid, long lwp, int sig) {
971     static bool has_tkill = true;
972     int result = 0;
973
974     pthrd_printf("Sending %d to %d/%ld\n", sig, pid, lwp);
975
976     if( has_tkill ) {
977         result = syscall(SYS_thr_kill2, pid, lwp, sig);
978         if( 0 != result && ENOSYS == errno ) {
979             pthrd_printf("Using kill instead of tkill on this system\n");
980             has_tkill = false;
981         }
982     }
983
984     if( !has_tkill ) {
985         result = kill(pid, sig);
986     }
987
988     return (result == 0);
989 }
990
991 bool freebsd_thread::plat_stop() {
992     Dyninst::PID pid = proc_->getPid();
993
994     if( !t_kill(pid, lwp, SIGSTOP) ) {
995         int errnum = errno;
996         if( ESRCH == errnum ) {
997             pthrd_printf("t_kill failed for %d/%d, thread/process doesn't exist\n", lwp, pid);
998             setLastError(err_noproc, "Thread no longer exists");
999             return false;
1000         }
1001         pthrd_printf("t_kill failed on %d/%d: %s\n", lwp, pid, strerror(errnum));
1002         setLastError(err_internal, "Could not send signal to process while stopping");
1003         return false;
1004     }
1005
1006     return true;
1007 }
1008
1009 bool freebsd_thread::plat_cont() {
1010     pthrd_printf("Continuing thread %d\n", lwp);
1011
1012     if( !plat_setStep() ) return false;
1013
1014     // Calling resume only makes sense for processes with multiple threads
1015     if( proc_->threadPool()->size() > 1 ) 
1016         if( !plat_resume() ) return false;
1017
1018     // Because all signals stop the whole process, only one thread should
1019     // have a non-zero continue signal
1020     if( continueSig_ ) {
1021         proc_->setContSignal(continueSig_);
1022     }
1023
1024     return true;
1025 }
1026
1027 bool freebsd_thread::attach() {
1028     // On FreeBSD, an attach is not necessary for threads
1029     return true;
1030 }
1031
1032 bool freebsd_thread::plat_setStep() {
1033     int result;
1034     if( singleStep() ) {
1035         pthrd_printf("Calling PT_SETSTEP on %d\n", lwp);
1036         result = ptrace(PT_SETSTEP, lwp, (caddr_t)1, 0);
1037     }else{
1038         pthrd_printf("Calling PT_CLEARSTEP on %d\n", lwp);
1039         result = ptrace(PT_CLEARSTEP, lwp, (caddr_t)1, 0);
1040     }
1041
1042     if( 0 != result ) {
1043         perr_printf("low-level single step change failed: %s\n", strerror(errno));
1044         setLastError(err_internal, "Low-level single step change failed");
1045         return false;
1046     }
1047
1048     return true;
1049 }
1050
1051 static dynreg_to_user_t dynreg_to_user;
1052 static void init_dynreg_to_user() {
1053     static volatile bool initialized = false;
1054     static Mutex init_lock;
1055     if( initialized ) return;
1056
1057     init_lock.lock();
1058     if( initialized ) {
1059         init_lock.unlock();
1060         return;
1061     }
1062
1063 #if defined(arch_x86_64)
1064     dynreg_to_user[x86_64::r15] =   make_pair(offsetof(reg, r_r15), 8);
1065     dynreg_to_user[x86_64::r14] =   make_pair(offsetof(reg, r_r14), 8);
1066     dynreg_to_user[x86_64::r13] =   make_pair(offsetof(reg, r_r13), 8);
1067     dynreg_to_user[x86_64::r12] =   make_pair(offsetof(reg, r_r12), 8);
1068     dynreg_to_user[x86_64::r11] =   make_pair(offsetof(reg, r_r11), 8);
1069     dynreg_to_user[x86_64::r10] =   make_pair(offsetof(reg, r_r10), 8);
1070     dynreg_to_user[x86_64::r9] =    make_pair(offsetof(reg, r_r9), 8);
1071     dynreg_to_user[x86_64::r8] =    make_pair(offsetof(reg, r_r8), 8);
1072     dynreg_to_user[x86_64::rdi] =   make_pair(offsetof(reg, r_rdi), 8);
1073     dynreg_to_user[x86_64::rsi] =   make_pair(offsetof(reg, r_rsi), 8);
1074     dynreg_to_user[x86_64::rbp] =   make_pair(offsetof(reg, r_rbp), 8);
1075     dynreg_to_user[x86_64::rbx] =   make_pair(offsetof(reg, r_rbx), 8);
1076     dynreg_to_user[x86_64::rdx] =   make_pair(offsetof(reg, r_rdx), 8);
1077     dynreg_to_user[x86_64::rcx] =   make_pair(offsetof(reg, r_rcx), 8);
1078     dynreg_to_user[x86_64::rax] =   make_pair(offsetof(reg, r_rax), 8);
1079     dynreg_to_user[x86_64::rip] =   make_pair(offsetof(reg, r_rip), 8);
1080     dynreg_to_user[x86_64::rsp] =   make_pair(offsetof(reg, r_rsp), 8);
1081     dynreg_to_user[x86_64::flags] = make_pair(offsetof(reg, r_rflags), 8);
1082     dynreg_to_user[x86_64::cs] =    make_pair(offsetof(reg, r_cs), 8);
1083     dynreg_to_user[x86_64::ss] =    make_pair(offsetof(reg, r_ss), 8);
1084
1085     // x86 registers -- it appears that not all the segment registers are available
1086     dynreg_to_user[x86::edi] = make_pair(offsetof(reg, r_rdi), 4);
1087     dynreg_to_user[x86::esi] = make_pair(offsetof(reg, r_rsi), 4);
1088     dynreg_to_user[x86::ebp] = make_pair(offsetof(reg, r_rbp), 4);
1089     dynreg_to_user[x86::ebx] = make_pair(offsetof(reg, r_rbx), 4);
1090     dynreg_to_user[x86::edx] = make_pair(offsetof(reg, r_rdx), 4);
1091     dynreg_to_user[x86::ecx] = make_pair(offsetof(reg, r_rcx), 4);
1092     dynreg_to_user[x86::eax] = make_pair(offsetof(reg, r_rax), 4);
1093     dynreg_to_user[x86::eip] = make_pair(offsetof(reg, r_rip), 4);
1094     dynreg_to_user[x86::flags] = make_pair(offsetof(reg, r_rflags), 4);
1095     dynreg_to_user[x86::esp] = make_pair(offsetof(reg, r_rsp), 4);
1096     dynreg_to_user[x86::ss] = make_pair(offsetof(reg, r_ss), 4);
1097     dynreg_to_user[x86::cs] = make_pair(offsetof(reg, r_cs), 4);
1098     
1099 #elif defined(arch_x86)
1100     dynreg_to_user[x86::fs] = make_pair(offsetof(reg, r_fs), 4);
1101     dynreg_to_user[x86::es] = make_pair(offsetof(reg, r_es), 4);
1102     dynreg_to_user[x86::ds] = make_pair(offsetof(reg, r_ds), 4);
1103     dynreg_to_user[x86::edi] = make_pair(offsetof(reg, r_edi), 4);
1104     dynreg_to_user[x86::esi] = make_pair(offsetof(reg, r_esi), 4);
1105     dynreg_to_user[x86::ebp] = make_pair(offsetof(reg, r_ebp), 4);
1106     dynreg_to_user[x86::ebx] = make_pair(offsetof(reg, r_ebx), 4);
1107     dynreg_to_user[x86::edx] = make_pair(offsetof(reg, r_edx), 4);
1108     dynreg_to_user[x86::ecx] = make_pair(offsetof(reg, r_ecx), 4);
1109     dynreg_to_user[x86::eax] = make_pair(offsetof(reg, r_eax), 4);
1110     dynreg_to_user[x86::eip] = make_pair(offsetof(reg, r_eip), 4);
1111     dynreg_to_user[x86::cs] = make_pair(offsetof(reg, r_cs), 4);
1112     dynreg_to_user[x86::flags] = make_pair(offsetof(reg, r_eflags), 4);
1113     dynreg_to_user[x86::esp] = make_pair(offsetof(reg, r_esp), 4);
1114     dynreg_to_user[x86::ss] = make_pair(offsetof(reg, r_ss), 4);
1115     dynreg_to_user[x86::gs] = make_pair(offsetof(reg, r_gs), 4);
1116 #else
1117     // TODO implement this for other architectures
1118     assert(!"Register conversion is not implemented for this architecture");
1119 #endif
1120
1121     initialized = true;
1122
1123     init_lock.unlock();
1124 }
1125
1126 #if 0 
1127 // Debugging
1128 static void dumpRegisters(struct reg *regs) {
1129 #if defined(arch_x86)
1130     fprintf(stderr, "r_fs = 0x%x\n", regs->r_fs);
1131     fprintf(stderr, "r_es = 0x%x\n", regs->r_es);
1132     fprintf(stderr, "r_ds = 0x%x\n", regs->r_ds);
1133     fprintf(stderr, "r_edi = 0x%x\n", regs->r_edi);
1134     fprintf(stderr, "r_esi = 0x%x\n", regs->r_esi);
1135     fprintf(stderr, "r_ebp = 0x%x\n", regs->r_ebp);
1136     fprintf(stderr, "r_ebx = 0x%x\n", regs->r_ebx);
1137     fprintf(stderr, "r_ecx = 0x%x\n", regs->r_ecx);
1138     fprintf(stderr, "r_eax = 0x%x\n", regs->r_eax);
1139     fprintf(stderr, "r_eip = 0x%x\n", regs->r_eip);
1140     fprintf(stderr, "r_cs = 0x%x\n", regs->r_cs);
1141     fprintf(stderr, "r_eflags = 0x%x\n", regs->r_eflags);
1142     fprintf(stderr, "r_esp = 0x%x\n", regs->r_esp);
1143     fprintf(stderr, "r_ss = 0x%x\n", regs->r_ss);
1144     fprintf(stderr, "r_gs = 0x%x\n", regs->r_gs);
1145     fprintf(stderr, "r_trapno = 0x%x\n", regs->r_trapno);
1146     fprintf(stderr, "r_err = 0x%x\n", regs->r_err);
1147 #endif
1148 }
1149 #endif
1150
1151 bool freebsd_process::plat_individualRegAccess() {
1152     return false;
1153 }
1154
1155 string freebsd_process::getThreadLibName(const char *symName) {
1156     // XXX
1157     // This hack is needed because the FreeBSD implementation doesn't
1158     // set the object name when looking for a symbol -- instead of
1159     // searching every library for the symbol, make some educated 
1160     // guesses
1161     //
1162     // It also assumes that the first symbols thread_db will lookup
1163     // are either _libthr_debug or _libkse_debug
1164     
1165     if( !strcmp(symName, "_libkse_debug") ) {
1166         libThreadName = "libkse.so";
1167     }else if( !strcmp(symName, "_libthr_debug") || 
1168             libThreadName.empty() ) 
1169     {
1170         libThreadName = "libthr.so";
1171     }
1172
1173     return libThreadName;
1174 }
1175
1176 bool freebsd_process::isSupportedThreadLib(const string &libName) {
1177     if( libName.find("libthr") != string::npos ) {
1178         return true;
1179     }else if( libName.find("libkse") != string::npos ) {
1180         return true;
1181     }
1182
1183     return false;
1184 }
1185
1186 bool freebsd_thread::plat_getAllRegisters(int_registerPool &regpool) {
1187     struct reg registers;
1188     unsigned char *regPtr = (unsigned char *)&registers;
1189
1190     if( 0 != ptrace(PT_GETREGS, lwp, (caddr_t)regPtr, 0) ) {
1191         perr_printf("Error reading registers from LWP %d: %s\n", lwp, strerror(errno));
1192         setLastError(err_internal, "Could not read registers from thread");
1193         return false;
1194     }
1195
1196     init_dynreg_to_user();
1197
1198     Dyninst::Architecture curplat = llproc()->getTargetArch();
1199     regpool.regs.clear();
1200
1201     dynreg_to_user_t::iterator i;
1202     for(i = dynreg_to_user.begin(); i != dynreg_to_user.end(); ++i ) {
1203         const MachRegister reg = i->first;
1204         if (reg.getArchitecture() != curplat ) continue;
1205
1206         MachRegisterVal val;
1207         const unsigned int offset = i->second.first;
1208         const unsigned int size = i->second.second;
1209
1210         if( size == sizeof(uint32_t) ) {
1211             val = *((uint32_t *)(&regPtr[offset]));
1212         }else if( size == sizeof(uint64_t) ) {
1213             val = *((uint64_t *)(&regPtr[offset]));
1214         }else{
1215             assert(!"Unknown address width");
1216         }
1217         pthrd_printf("Register %s has value 0x%lx, offset 0x%x\n", reg.name(), (unsigned long)val, offset);
1218         regpool.regs[reg] = val;
1219     }
1220
1221     return true;
1222 }
1223
1224 static bool validateRegisters(struct reg *regs, Dyninst::LWP lwp) {
1225 #if defined(arch_x86)
1226     struct reg old_regs;
1227     if( 0 != ptrace(PT_GETREGS, lwp, (caddr_t)&old_regs, 0) ) {
1228         perr_printf("Error reading registers from LWP %d\n", lwp);
1229         return false;
1230     }
1231
1232     // Sometimes the resume flag is set in the saved version of the
1233     // registers and not set in the current set of registers -- 
1234     // the OS doesn't allow us to change this flag, change it to the
1235     // current value
1236     if( (old_regs.r_eflags & PSL_RF) != (regs->r_eflags & PSL_RF) ) {
1237         if( old_regs.r_eflags & PSL_RF ) regs->r_eflags |= PSL_RF;
1238         else regs->r_eflags &= ~PSL_RF;
1239     }
1240 #endif
1241     return true;
1242 }
1243
1244 bool freebsd_thread::plat_setAllRegisters(int_registerPool &regpool) {
1245     init_dynreg_to_user();
1246
1247     // Populate a struct reg using the registerPool
1248     struct reg registers;
1249     unsigned char *regPtr = (unsigned char *)&registers;
1250
1251     dynreg_to_user_t::iterator i;
1252     unsigned num_found = 0;
1253     Dyninst::Architecture curplat = llproc()->getTargetArch();
1254
1255     for (i = dynreg_to_user.begin(); i != dynreg_to_user.end(); ++i) {
1256         const MachRegister reg = i->first;
1257         MachRegisterVal val;
1258
1259         if (reg.getArchitecture() != curplat) continue;
1260
1261         const unsigned int offset = i->second.first;
1262         const unsigned int size = i->second.second;
1263
1264         assert(offset+size <= sizeof(struct reg));
1265
1266         int_registerPool::reg_map_t::iterator j = regpool.regs.find(reg);
1267
1268         // A register was not set in the registerPool, error report after loop
1269         if( j == regpool.regs.end() ) break;
1270
1271         num_found++;
1272         val = j->second;
1273
1274         if (size == sizeof(uint32_t)) {
1275             *((uint32_t *)&regPtr[offset]) = (uint32_t) val;
1276         } else if (size == sizeof(uint64_t)) {
1277             *((uint64_t *)&regPtr[offset]) = (uint64_t) val;
1278         } else {
1279             assert(!"Unknown address width");
1280         }
1281
1282         pthrd_printf("Register %s gets value 0x%lx, offset 0x%x\n", reg.name(), (unsigned long)val, offset);
1283     }
1284
1285     if (num_found != regpool.regs.size()) {
1286         setLastError(err_badparam, "Invalid register set passed to setAllRegisters");
1287         perr_printf("Couldn't find all registers in the register set %u/%u\n", num_found,
1288                     (unsigned int) regpool.regs.size());
1289         return false;
1290     }
1291
1292     if( 0 != ptrace(PT_SETREGS, lwp, (caddr_t)&registers, 0) ) {
1293         bool success = false;
1294         if( EINVAL == errno ) {
1295             // This usually means that the flag register would change some system status bits
1296             pthrd_printf("Attempting to handle EINVAL caused by PT_SETREGS for LWP %d\n", lwp);
1297
1298             if( validateRegisters(&registers, lwp) ) {
1299                 if( !ptrace(PT_SETREGS, lwp, (caddr_t)&registers, 0) ) {
1300                     pthrd_printf("Successfully handled EINVAL caused by PT_SETREGS\n");
1301                     success = true;
1302                 }else{
1303                     perr_printf("Failed to handle EINVAL caused by PT_SETREGS\n");
1304                 }
1305             }
1306         }
1307
1308         if( !success ) {
1309             perr_printf("Error setting registers for LWP %d: %s\n", lwp, strerror(errno));
1310             setLastError(err_internal, "Could not set registers in thread");
1311             return false;
1312         }
1313     }
1314
1315     pthrd_printf("Successfully set the values of all registers for LWP %d\n", lwp);
1316
1317     return true;
1318 }
1319
1320 bool freebsd_thread::plat_getRegister(Dyninst::MachRegister, Dyninst::MachRegisterVal &) {
1321     assert(!"This platform does not have individual register access");
1322     return false;
1323 }
1324
1325 bool freebsd_thread::plat_setRegister(Dyninst::MachRegister, Dyninst::MachRegisterVal) {
1326     assert(!"This platform does not have individual register access");
1327     return false;
1328 }
1329
1330 // iRPC snippets
1331 const unsigned int x86_64_mmap_flags_position = 17;
1332 const unsigned int x86_64_mmap_size_position = 30;
1333 const unsigned int x86_64_mmap_addr_position = 40;
1334 const unsigned int x86_64_mmap_start_position = 0;
1335 const unsigned char x86_64_call_mmap[] = {
1336 0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0,%r9 (offset)
1337 0x49, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff,       //mov    $0xffffffffffffffff,%r8 (fd)
1338 0x49, 0xc7, 0xc2, 0x12, 0x10, 0x00, 0x00,       //mov    $0x1012,%r10 (flags)
1339 0x48, 0xc7, 0xc2, 0x07, 0x00, 0x00, 0x00,       //mov    $0x7,%rdx (perms)
1340 0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi (size)
1341 0x00, 0x00, 0x00,                               //
1342 0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi (addr)
1343 0x00, 0x00, 0x00,                               //
1344 0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
1345 0x0f, 0x05,                                     //syscall
1346 0xcc,                                           //trap
1347 0x90                                            //nop
1348 };
1349 const unsigned int x86_64_call_mmap_size = sizeof(x86_64_call_mmap);
1350
1351 const unsigned int x86_64_munmap_size_position = 2;
1352 const unsigned int x86_64_munmap_addr_position = 12;
1353 const unsigned int x86_64_munmap_start_position = 0;
1354 const unsigned char x86_64_call_munmap[] = {
1355 0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi
1356 0x00, 0x00, 0x00,                               //
1357 0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi
1358 0x00, 0x00, 0x00,                               //
1359 0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax
1360 0x0f, 0x05,                                     //syscall
1361 0xcc,                                           //trap
1362 0x90                                            //nop
1363 };
1364 const unsigned int x86_64_call_munmap_size = sizeof(x86_64_call_munmap);
1365
1366 const unsigned int x86_mmap_flags_position = 5;
1367 const unsigned int x86_mmap_size_position = 12;
1368 const unsigned int x86_mmap_addr_position = 17;
1369 const unsigned int x86_mmap_start_position = 0;
1370 const unsigned char x86_call_mmap[] = {
1371 0x6a, 0x00,                                     //push   $0x0 (offset)
1372 0x6a, 0xff,                                     //push   $0xffffffff (fd)
1373 0x68, 0x12, 0x10, 0x00, 0x00,                   //push   $0x1012 (flags)
1374 0x6a, 0x07,                                     //push   $0x7 (perms)
1375 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)
1376 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
1377 0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
1378 0x50,                                           //push   %eax (required by calling convention)
1379 0xcd, 0x80,                                     //int    $0x80
1380 0x8d, 0x64, 0x24, 0x1c,                         //lea    0x1c(%esp),%esp
1381 0xcc,                                           //trap
1382 0x90                                            //nop
1383 };
1384 const unsigned int x86_call_mmap_size = sizeof(x86_call_mmap);
1385
1386 const unsigned int x86_munmap_size_position = 1;
1387 const unsigned int x86_munmap_addr_position = 6;
1388 const unsigned int x86_munmap_start_position = 0;
1389 const unsigned char x86_call_munmap[] = {
1390 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)    
1391 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
1392 0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax (SYS_munmap)
1393 0x50,                                           //push   %eax (required by calling convention)
1394 0xcd, 0x80,                                     //int    $0x80
1395 0x8d, 0x64, 0x24, 0x0c,                         //lea    0xc(%esp),%esp 
1396 0xcc,                                           //trap
1397 0x90                                            //nop
1398 };
1399 const unsigned int x86_call_munmap_size = sizeof(x86_call_munmap);