A first pass at implementing thread stop and continue 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
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 when 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     if( WIFSTOPPED(status) ) {
249         const int stopsig = WSTOPSIG(status);
250
251         pthrd_printf("Decoded to signal %s\n", strsignal(stopsig));
252         switch( stopsig ) {
253             case SIGSTOP: {
254                 if( lthread->hasPendingStop() ) {
255                     pthrd_printf("Received pending stop on %d/%d\n",
256                             lthread->llproc()->getPid(), lthread->getLWP());
257                     event = Event::ptr(new EventStop());
258                     break;
259                 }
260
261                 bool foundPendingContinue = false;
262                 int_threadPool::iterator i;
263                 for(i = lproc->threadPool()->begin(); i != lproc->threadPool()->end(); ++i) {
264                     freebsd_thread *contThread = static_cast<freebsd_thread *>(*i);
265                     if( contThread->hasPendingContinue() ) {
266                         pthrd_printf("Received pending continue on %d/%d\n",
267                                 contThread->llproc()->getPid(), contThread->getLWP());
268                         event = Event::ptr(new EventContinue(contThread->getContSignal()));
269                         foundPendingContinue = true;
270                         break;
271                     }
272                 }
273
274                 if( foundPendingContinue )
275                     break;
276
277                 // Relying on fall through for bootstrap
278                 assert( proc->getState() == int_process::neonatal_intermediate );
279             }
280             case SIGTRAP: {
281                 if( proc->getState() == int_process::neonatal_intermediate) {
282                     pthrd_printf("Decoded event to bootstrap on %d/%d\n",
283                             proc->getPid(), thread->getLWP());
284                     event = Event::ptr(new EventBootstrap());
285                     break;
286                 }
287
288                 Dyninst::MachRegisterVal addr;
289                 result = thread->getRegister(MachRegister::getPC(proc->getTargetArch()), addr);
290                 if( !result ) {
291                     perr_printf("Failed to read PC address upon SIGTRAP\n");
292                     return false;
293                 }
294
295                 Dyninst::Address adjusted_addr = adjustTrapAddr(addr, proc->getTargetArch());
296
297                 // Check if it is a RPC
298                 if (rpcMgr()->isRPCTrap(thread, adjusted_addr)) {
299                    pthrd_printf("Decoded event to rpc completion on %d/%d at %lx\n",
300                                 proc->getPid(), thread->getLWP(), adjusted_addr);
301                    event = Event::ptr(new EventRPC(thread->runningRPC()->getWrapperForDecode()));
302                    break;
303                 }
304
305                 // Check if it is a breakpoint
306                 installed_breakpoint *ibp = proc->getBreakpoint(adjusted_addr);
307                 if( ibp && ibp != thread->isClearingBreakpoint() ) {
308                     pthrd_printf("Decoded breakpoint on %d/%d at %lx\n", proc->getPid(),
309                             thread->getLWP(), adjusted_addr);
310                     event = Event::ptr(new EventBreakpoint(adjusted_addr, ibp));
311
312                     if( adjusted_addr == lproc->getLibBreakpointAddr() ) {
313                         pthrd_printf("Breakpoint is library load/unload\n");
314                         Event::ptr lib_event = Event::ptr(new EventLibrary());
315                         lib_event->setThread(thread->thread());
316                         lib_event->setProcess(proc->proc());
317                         event->addSubservientEvent(lib_event);
318                     }else{
319                         // Check for thread events
320                         vector<Event::ptr> threadEvents;
321                         if( lproc->getEventsAtAddr(adjusted_addr, lthread, threadEvents) ) {
322                             vector<Event::ptr>::iterator threadEventIter;
323                             for(threadEventIter = threadEvents.begin(); threadEventIter != threadEvents.end();
324                                     ++threadEventIter)
325                             {
326                                 // An event is created for the initial thread, but this thread is already
327                                 // created during bootstrap. Ignore any create events for threads that
328                                 // are already created.
329                                 if( (*threadEventIter)->getEventType().code() == EventType::ThreadCreate ) {
330                                     Dyninst::LWP createdLWP = (*threadEventIter)->getEventNewThread()->getLWP();
331                                     int_thread * newThread = ProcPool()->findThread(createdLWP);
332                                     if( NULL != newThread ) {
333                                         freebsd_thread *newlThread = static_cast<freebsd_thread *>(newThread);
334                                         pthrd_printf("Thread already created for LWP %d\n", createdLWP);
335
336                                         if( !newlThread->resume() ) {
337                                             perr_printf("Failed to resume already created LWP %d\n", createdLWP);
338                                             return false;
339                                         }
340
341                                         // Still need to enable events for it -- this can't be done during
342                                         // bootstrap because the thread_db library isn't guaranteed to 
343                                         // be initialized at bootstrap
344                                         newlThread->setEventReporting(true);
345                                         continue;
346                                     }
347                                 }
348
349                                 (*threadEventIter)->setThread(thread->thread());
350                                 (*threadEventIter)->setProcess(proc->proc());
351                                 event->addSubservientEvent(*threadEventIter);
352                             }
353                         }
354                     }
355                     break;
356                 }
357
358                 if( thread->singleStep() ) {
359                     ibp = thread->isClearingBreakpoint();
360                     if( ibp ) {
361                         pthrd_printf("Decoded event to breakpoint cleanup\n");
362                         event = Event::ptr(new EventBreakpointClear(ibp));
363
364                         // For a thread_db_process, post-ThreadDestroy events happen
365                         // after a BreakpointClear
366                         vector<Event::ptr> destroyEvents;
367                         if( lproc->getPostDestroyEvents(destroyEvents) ) {
368                             vector<Event::ptr>::iterator eventIter;
369                             for(eventIter = destroyEvents.begin(); eventIter != destroyEvents.end(); ++eventIter) {
370                                 event->addSubservientEvent(*eventIter);
371                             }
372                         }
373
374                         break;
375                     }else{
376                         pthrd_printf("Decoded event to single step on %d/%d\n",
377                                 proc->getPid(), thread->getLWP());
378                         event = Event::ptr(new EventSingleStep());
379                         break;
380                     }
381                 }else{
382                     // TODO for now, just assume that a call to exec happened
383                     // In the future, if we need to trace syscalls, we will
384                     // need to differentiate between different syscalls
385                     //
386                     // breadcrumb: 
387                     // truss(1) does system call identification after a SIGTRAP
388                     pthrd_printf("Decoded event to exec on %d/%d\n",
389                             proc->getPid(), thread->getLWP());
390                     event = Event::ptr(new EventExec(EventType::Post));
391                     event->setSyncType(Event::sync_process);
392                 }
393                 break;
394             }
395             default:
396                 pthrd_printf("Decoded event to signal %d on %d/%d\n",
397                         stopsig, proc->getPid(), thread->getLWP());
398 #if 0
399                 //Debugging code
400                 if (stopsig == SIGSEGV) {
401                    Dyninst::MachRegisterVal addr;
402                    result = thread->getRegister(MachRegister::getPC(proc->getTargetArch()), addr);
403                    if (!result) {
404                       fprintf(stderr, "Failed to read PC address upon crash\n");
405                    }
406                    fprintf(stderr, "Got crash at %lx\n", addr);
407
408                    size_t readSize = 10;
409                    void *local = malloc(readSize);
410                    if( !PtraceBulkRead(addr, readSize, local, proc->getPid()) ) {
411                        fprintf(stderr, "Failed to read memory at %lx\n", addr);
412                    }else{
413                        unsigned char *localBytes = (unsigned char *)local;
414                        fprintf(stderr, "%lx: ", addr);
415                        for(unsigned i = 0; i < readSize; ++i) {
416                            fprintf(stderr, "%x ", localBytes[i]);
417                        }
418                        fprintf(stderr, "\n");
419                    }
420
421                    assert(!"Received crash");
422                 }
423 #endif
424                 event = Event::ptr(new EventSignal(stopsig));
425                 break;
426         }
427     }
428     else if (WIFEXITED(status) || WIFSIGNALED(status)) {
429         if( WIFEXITED(status) ) {
430             int exitcode = WEXITSTATUS(status);
431             /*
432              * On FreeBSD, an exit of a traced process is reported to both its original
433              * parent and the tracing process. When the traced process is created by a
434              * ProcControlAPI process, ProcControlAPI will receive two copies of the exit
435              * event. The second event should be ignored.
436              */
437             if( int_thread::exited == thread->getGeneratorState() ) {
438                 pthrd_printf("Decoded duplicate exit event of process %d/%d with code %d\n",
439                         proc->getPid(), thread->getLWP(), exitcode);
440                 return true;
441             }
442
443             pthrd_printf("Decoded event to exit of process %d/%d with code %d\n",
444                     proc->getPid(), thread->getLWP(), exitcode);
445             event = Event::ptr(new EventExit(EventType::Post, exitcode));
446         }else{
447             int termsig = WTERMSIG(status);
448             pthrd_printf("Decoded event to crash of %d/%d with signal %d\n",
449                     proc->getPid(), thread->getLWP(), termsig);
450             event = Event::ptr(new EventCrash(termsig));
451         }
452         event->setSyncType(Event::sync_process);
453
454         int_threadPool::iterator i = proc->threadPool()->begin();
455         for(; i != proc->threadPool()->end(); ++i) {
456             (*i)->setGeneratorState(int_thread::exited);
457         }
458     }
459
460     assert(event);
461     assert(proc->proc());
462     assert(thread->thread());
463
464     // All signals stop a process in FreeBSD
465     if( event && event->getSyncType() == Event::unset)
466         event->setSyncType(Event::sync_process);
467
468     event->setThread(thread->thread());
469     event->setProcess(proc->proc());
470     events.push_back(event);
471
472     delete archevent;
473
474     return true;
475 }
476
477 int_process *int_process::createProcess(Dyninst::PID pid_, std::string exec) {
478     std::vector<std::string> args;
479     freebsd_process *newproc = new freebsd_process(pid_, exec, args);
480     assert(newproc);
481
482     return static_cast<int_process *>(newproc);
483 }
484
485 int_process *int_process::createProcess(std::string exec, std::vector<std::string> args) {
486     freebsd_process *newproc = new freebsd_process(0, exec, args);
487     assert(newproc);
488     return static_cast<int_process *>(newproc);
489 }
490
491 int_process *int_process::createProcess(Dyninst::PID pid_, int_process *parent) {
492     freebsd_process *newproc = new freebsd_process(pid_, parent);
493     assert(newproc);
494     return static_cast<int_process *>(newproc);
495 }
496
497 int_process::ThreadControlMode int_process::getThreadControlMode() {
498     return int_process::HybridLWPControl;
499 }
500
501 int_thread *int_thread::createThreadPlat(int_process *proc, Dyninst::THR_ID thr_id,
502         Dyninst::LWP lwp_id, bool initial_thrd)
503 {
504     if( initial_thrd ) {
505         freebsd_process *tmpProc = static_cast<freebsd_process *>(proc);
506         
507         vector<Dyninst::LWP> lwps;
508         tmpProc->getThreadLWPs(lwps);
509         assert( lwps.size() == 1 );
510
511         lwp_id = lwps.back();
512     }
513     freebsd_thread *lthrd = new freebsd_thread(proc, thr_id, lwp_id);
514     assert(lthrd);
515     return static_cast<int_thread *>(lthrd);
516 }
517
518 HandlerPool *plat_createDefaultHandlerPool(HandlerPool *hpool) {
519     static bool initialized = false;
520     static FreeBSDSyncHandler *lstop = NULL;
521     if( !initialized ) {
522         lstop = new FreeBSDSyncHandler();
523         initialized = true;
524     }
525     hpool->addHandler(lstop);
526     thread_db_process::addThreadDBHandlers(hpool);
527     return hpool;
528 }
529
530 bool ProcessPool::LWPIDsAreUnique() {
531     return true;
532 }
533
534 freebsd_process::freebsd_process(Dyninst::PID p, std::string e, std::vector<std::string> a)
535     : thread_db_process(p, e, a)
536 {
537 }
538
539 freebsd_process::freebsd_process(Dyninst::PID pid_, int_process *p) 
540     : thread_db_process(pid_, p)
541 {
542 }
543
544 freebsd_process::~freebsd_process() 
545 {
546     freeThreadDBAgent();
547 }
548
549 bool freebsd_process::plat_create() {
550     pid = fork();
551     if( -1 == pid ) {
552         int errnum = errno;
553         pthrd_printf("Could not fork new process for %s: %s\n",
554                 executable.c_str(), strerror(errnum));
555         setLastError(err_internal, "Unable to fork new process");
556         return false;
557     }
558
559     if( !pid ) {
560         // Child
561         if( 0 != ptrace(PT_TRACE_ME, 0, 0, 0) ) {
562             perr_printf("Faild to execute a PT_TRACE_ME.\n");
563             setLastError(err_internal, "Unable to debug trace new process");
564             exit(-1);
565         }
566
567         plat_execv(); // Never returns
568
569         exit(-1);
570     }
571
572     return true;
573 }
574
575 bool freebsd_process::plat_attach() {
576     pthrd_printf("Attaching to pid %d\n", pid);
577     if( 0 != ptrace(PT_ATTACH, pid, (caddr_t)1, 0) ) {
578         int errnum = errno;
579         pthrd_printf("Unable to attach to process %d: %s\n", pid, strerror(errnum));
580         if( EPERM == errnum ) {
581             setLastError(err_prem, "Do not have correct permissions to attach to pid");
582         }else if( ESRCH == errnum ) {
583             setLastError(err_noproc, "The specified process was not found");
584         }else {
585             setLastError(err_internal, "Unable to attach to the specified process");
586         }
587         return false;
588     }
589     return true;
590 }
591
592 bool freebsd_process::plat_forked() {
593     // TODO
594     assert(!NA_FREEBSD);
595     return false;
596 }
597
598 bool freebsd_process::post_forked() {
599     // TODO
600     assert(!NA_FREEBSD);
601     return false;
602 }
603
604 bool freebsd_process::plat_execed() { 
605     bool result = sysv_process::plat_execed();
606     if( !result ) return false;
607
608     char *pathname = sysctl_getExecPathname(getPid());
609     if( NULL == pathname ) {
610         perr_printf("Failed to retrieve executable pathname");
611         setLastError(err_internal, "Failed to retrieve executable pathname");
612         return false;
613     }
614
615     executable = pathname;
616     free(pathname);
617     return true;
618 }
619
620 bool freebsd_process::plat_detach() {
621     pthrd_printf("PT_DETACH on %d\n", getPid());
622     if( 0 != ptrace(PT_DETACH, getPid(), (caddr_t)1, 0) ) {
623         perr_printf("Failed to PT_DETACH on %d\n", getPid());
624         setLastError(err_internal, "PT_DETACH operation failed\n");
625     }
626     return true;
627 }
628
629 bool freebsd_process::plat_terminate(bool &needs_sync) {
630     pthrd_printf("Terminating process %d\n", getPid());
631     if( 0 != ptrace(PT_KILL, getPid(), (caddr_t)1, 0) ) {
632         perr_printf("Failed to PT_KILL process %d\n", getPid());
633         setLastError(err_internal, "PT_KILL operation failed\n");
634         return false;
635     }
636
637     needs_sync = true;
638     return true;
639 }
640
641 bool freebsd_process::plat_readMem(int_thread *thr, void *local, 
642                          Dyninst::Address remote, size_t size) 
643 {
644     return PtraceBulkRead(remote, size, local, thr->llproc()->getPid());
645 }
646
647 bool freebsd_process::plat_readProcMem(void *local, 
648         Dyninst::Address remote, size_t size)
649 {
650     return PtraceBulkRead(remote, size, local, getPid());
651 }
652
653 bool freebsd_process::plat_writeMem(int_thread *thr, void *local, 
654                           Dyninst::Address remote, size_t size) 
655 {
656     return PtraceBulkWrite(remote, size, local, thr->llproc()->getPid());
657 }
658
659 bool freebsd_process::plat_writeProcMem(void *local, 
660                           Dyninst::Address remote, size_t size) 
661 {
662     return PtraceBulkWrite(remote, size, local, getPid());
663 }
664
665 bool freebsd_process::needIndividualThreadAttach() {
666     return false;
667 }
668
669 bool freebsd_process::getThreadLWPs(std::vector<Dyninst::LWP> &lwps) {
670     return sysctl_findProcLWPs(getPid(), lwps);
671 }
672
673 Dyninst::Architecture freebsd_process::getTargetArch() {
674     if( Dyninst::Arch_none != arch ) {
675         return arch;
676     }
677     int addr_width = sysctl_computeAddrWidth(getPid());
678
679 #if defined(arch_x86) || defined(arch_x86_64)
680     assert(addr_width == 4 || addr_width == 8);
681     arch = (addr_width == 4) ? Dyninst::Arch_x86 : Dyninst::Arch_x86_64;
682 #elif defined(arch_power)
683     assert(addr_width == 4 || addr_width == 8);
684     arch = (addr_width == 4) ? Dyninst::Arch_ppc32 : Dyninst::Arch_ppc64;
685 #else
686     assert(!"Unknown architecture");
687 #endif
688     return arch;
689 }
690
691 freebsd_thread::freebsd_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l)
692     : thread_db_thread(p, t, l)
693 {
694 }
695
696 freebsd_thread::~freebsd_thread() 
697 {
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 FreeBSDSyncHandler::FreeBSDSyncHandler() 
737     : Handler("FreeBSD Sync Handler")
738 {}
739
740 FreeBSDSyncHandler::~FreeBSDSyncHandler()
741 {}
742
743 static
744 bool syncThreadState(freebsd_thread *lthread) {
745     if( dyninst_debug_proccontrol ) {
746         pthrd_printf("synchronize: Thread %d/%d is in handler state %s internal state %s\n",
747                      lthread->proc()->getPid(), lthread->getLWP(),
748                      int_thread::stateStr(lthread->getHandlerState()),
749                      int_thread::stateStr(lthread->getInternalState()));
750     }
751
752     if( lthread->hasPendingContinue() ) {
753         pthrd_printf("Thread %d/%d has a pending continue\n",
754                 lthread->proc()->getPid(), lthread->getLWP());
755         if( !lthread->resume() ) {
756             perr_printf("Failed to resume thread %d\n", lthread->getLWP());
757             return false;
758         }
759
760         pthrd_printf("Unsetting pending continue for thread %d\n", lthread->getLWP());
761         lthread->setPendingContinue(false);
762         if( lthread->hasPendingUserContinue() ) {
763             lthread->setPendingUserContinue(false);
764             lthread->setInternalState(int_thread::running);
765             lthread->setHandlerState(int_thread::running);
766             lthread->setGeneratorState(int_thread::running);
767         }
768     }else if( lthread->hasPendingStop() ) {
769         pthrd_printf("Thread %d/%d has a pending stop\n",
770                 lthread->proc()->getPid(), lthread->getLWP());
771         if( !lthread->suspend() ) {
772             perr_printf("Failed to suspend thread %d\n", lthread->getLWP());
773             return false;
774         }
775     }else if( lthread->getHandlerState() == int_thread::running ) {
776         if( !lthread->resume() ) {
777             perr_printf("Failed to resume thread %d\n", lthread->getLWP());
778             return false;
779         }
780     }else if( lthread->getHandlerState() == int_thread::stopped ) {
781         if( !lthread->suspend() ) {
782             perr_printf("Failed to suspend thread %d\n", lthread->getLWP());
783             return false;
784         }
785     }
786
787     if( !lthread->plat_setStep() ) {
788         perr_printf("Failed to set single step setting for thread %d\n",
789                 lthread->getLWP());
790         return false;
791     }
792
793     return true;
794 }
795
796 bool FreeBSDSyncHandler::handleEvent(Event::ptr ev) {
797     freebsd_process *lproc = static_cast<freebsd_process *>(ev->getProcess()->llproc());
798     freebsd_thread *lthread = static_cast<freebsd_thread *>(ev->getThread()->llthrd());
799
800     // No extra handling is required for single-threaded debuggees
801     if( lproc->threadPool()->size() <= 1 ) return true;
802
803     EventContinue::const_ptr evContinue = ev->getEventContinue();
804     if( evContinue ) {
805         lproc->setContSignal(evContinue->getContinueSignal());
806
807         int_threadPool::iterator i;
808         for(i = lproc->threadPool()->begin(); i != lproc->threadPool()->end(); ++i) {
809             if( !syncThreadState(static_cast<freebsd_thread *>(*i)) )
810                 return false;
811         }
812     }else{
813         if( !syncThreadState(lthread) ) {
814             return false;
815         }
816     }
817
818     return true;
819 }
820
821 int FreeBSDSyncHandler::getPriority() const {
822     return PrePlatformPriority;
823 }
824
825 void FreeBSDSyncHandler::getEventTypesHandled(std::vector<EventType> &etypes) {
826     etypes.push_back(EventType(EventType::None, EventType::Stop));
827     etypes.push_back(EventType(EventType::None, EventType::Continue));
828 }
829
830 bool freebsd_process::plat_contProcess() {
831     /* Single-stepping is enabled/disabled using PT_SETSTEP
832      * and PT_CLEARSTEP instead of continuing the process
833      * with PT_STEP. See plat_setStep.
834      */
835     pthrd_printf("Calling PT_CONTINUE on %d with signal %d\n", 
836                 getPid(), continueSig);
837     if (0 != ptrace(PT_CONTINUE, getPid(), (caddr_t)1, continueSig) ) {
838         perr_printf("low-level continue failed: %s\n", strerror(errno));
839         setLastError(err_internal, "Low-level continue failed");
840         return false;
841     }
842
843     //
844     // XXX
845     //
846     // This attempts to get around the bug documented in FreeBSD problem
847     // report kern/142757 -- if we yield to the scheduler, we may avoid
848     // the race condition described in this bug report.
849     //
850     // Specifically, the race condition results from the following sequence
851     // of events, where P = parent process, C = child process:
852     //
853     // P-SIGSTOP C-STOP P-WAITPID P-CONT P-SIGSTOP C-RUN
854     // 
855     // Because the child doesn't run before the parent sends the second 
856     // stop signal, the child doesn't receive the second SIGSTOP. 
857     //
858     // A workaround for this problem would guarantee that the C-RUN event
859     // always occurs before the second P-SIGSTOP. Here, the sched_yield
860     // attempts to ensure this.
861     //
862     // TODO this doesn't always solve the problem
863     
864     sched_yield();
865
866     return true;
867 }
868
869 static bool t_kill(pid_t pid, long lwp, int sig) {
870     static bool has_tkill = true;
871     int result = 0;
872
873     pthrd_printf("Sending %d to %d/%ld\n", sig, pid, lwp);
874
875     if( has_tkill ) {
876         result = syscall(SYS_thr_kill2, pid, lwp, sig);
877         if( 0 != result && ENOSYS == errno ) {
878             pthrd_printf("Using kill instead of tkill on this system\n");
879             has_tkill = false;
880         }
881     }
882
883     if( !has_tkill ) {
884         result = kill(pid, sig);
885     }
886
887     return (result == 0);
888 }
889
890 bool freebsd_thread::plat_stop() {
891     Dyninst::PID pid = proc_->getPid();
892     if( !t_kill(pid, lwp, SIGSTOP) ) {
893         int errnum = errno;
894         if( ESRCH == errnum ) {
895             pthrd_printf("t_kill failed for %d/%d, thread/process doesn't exist\n", lwp, pid);
896             setLastError(err_noproc, "Thread no longer exists");
897             return false;
898         }
899         pthrd_printf("t_kill failed on %d/%d: %s\n", lwp, pid, strerror(errnum));
900         setLastError(err_internal, "Could not send signal to process while stopping");
901         return false;
902     }
903
904     return true;
905 }
906
907 bool freebsd_thread::plat_cont(bool user_cont) {
908     pthrd_printf("Continuing thread %d\n", lwp);
909
910     // Internal continues must happen when process is stopped and all internal
911     // continues need to eventually be followed by a call to plat_contProcess
912     // elsewhere
913     if (!user_cont) {
914         pthrd_printf("Performing internal contine for LWP %d\n", lwp);
915         if( !plat_setStep() ) return false;
916
917         if( proc_->threadPool()->size() > 1 ) 
918             if( !resume() ) return false;
919
920         // Because all signals stop the whole process, only one thread should
921         // have a non-zero continue signal
922         if( continueSig_ ) {
923             proc_->setContSignal(continueSig_);
924         }
925
926         setPendingContinue(true);
927         setPendingUserContinue(false);
928         return true;
929     }
930
931     if( hasPendingContinue() ) {
932         pthrd_printf("Thread %d already has a pending continue\n", lwp);
933         return true;
934     }
935
936     // There are two cases that need to be handled:
937     //
938     // 1) All threads are stopped
939     //    -> the thread needs to be resumed and the whole process continued
940     //
941     // 2) This thread is stopped, but other threads are running
942     //    -> send a SIGSTOP to the process and have the stop handler take care of
943     //       resuming the thread
944     
945     bool hasRunningThread = false;
946     int_thread *runningThread = NULL;
947     int_threadPool::iterator i;
948     for(i = proc_->threadPool()->begin(); i != proc_->threadPool()->end(); ++i) {
949         if( (*i)->getInternalState() == int_thread::running ) {
950             hasRunningThread = true;
951             runningThread = *i;
952             break;
953         }
954     }
955
956     if( !hasRunningThread ) {
957         pthrd_printf("No running thread found, doing simple continue for LWP %d\n", lwp);
958         if( !plat_setStep() ) return false;
959         if( proc_->threadPool()->size() > 1 )
960             if( !resume() ) return false;
961
962         proc_->setContSignal(continueSig_);
963         return proc_->plat_contProcess();
964     }else{
965         pthrd_printf("Running thread found, doing SIGSTOP continue for LWP %d\n", lwp);
966
967         setPendingContinue(true);
968         setPendingUserContinue(true);
969
970         // We cannot send the SIGSTOP to this thread because it is already suspended
971         // Instead send the SIGSTOP to any running thread, the whole process will
972         // be stopped and then this thread can be resumed
973         if( !runningThread->plat_stop() ) {
974             setPendingContinue(false);
975             setPendingUserContinue(false);
976             return false;
977         }
978     }
979
980     return true;
981 }
982
983 bool freebsd_thread::attach() {
984     // On FreeBSD, an attach is not necessary for threads
985     return true;
986 }
987
988 bool freebsd_thread::plat_setStep() {
989     int result;
990     if( singleStep() ) {
991         pthrd_printf("Calling PT_SETSTEP on %d\n", lwp);
992         result = ptrace(PT_SETSTEP, lwp, (caddr_t)1, 0);
993     }else{
994         pthrd_printf("Calling PT_CLEARSTEP on %d\n", lwp);
995         result = ptrace(PT_CLEARSTEP, lwp, (caddr_t)1, 0);
996     }
997
998     if( 0 != result ) {
999         perr_printf("low-level single step change failed: %s\n", strerror(errno));
1000         setLastError(err_internal, "Low-level single step change failed");
1001         return false;
1002     }
1003
1004     return true;
1005 }
1006
1007 static dynreg_to_user_t dynreg_to_user;
1008 static void init_dynreg_to_user() {
1009     static volatile bool initialized = false;
1010     static Mutex init_lock;
1011     if( initialized ) return;
1012
1013     init_lock.lock();
1014     if( initialized ) {
1015         init_lock.unlock();
1016         return;
1017     }
1018
1019 #if defined(arch_x86_64)
1020     dynreg_to_user[x86_64::r15] =   make_pair(offsetof(reg, r_r15), 8);
1021     dynreg_to_user[x86_64::r14] =   make_pair(offsetof(reg, r_r14), 8);
1022     dynreg_to_user[x86_64::r13] =   make_pair(offsetof(reg, r_r13), 8);
1023     dynreg_to_user[x86_64::r12] =   make_pair(offsetof(reg, r_r12), 8);
1024     dynreg_to_user[x86_64::r11] =   make_pair(offsetof(reg, r_r11), 8);
1025     dynreg_to_user[x86_64::r10] =   make_pair(offsetof(reg, r_r10), 8);
1026     dynreg_to_user[x86_64::r9] =    make_pair(offsetof(reg, r_r9), 8);
1027     dynreg_to_user[x86_64::r8] =    make_pair(offsetof(reg, r_r8), 8);
1028     dynreg_to_user[x86_64::rdi] =   make_pair(offsetof(reg, r_rdi), 8);
1029     dynreg_to_user[x86_64::rsi] =   make_pair(offsetof(reg, r_rsi), 8);
1030     dynreg_to_user[x86_64::rbp] =   make_pair(offsetof(reg, r_rbp), 8);
1031     dynreg_to_user[x86_64::rbx] =   make_pair(offsetof(reg, r_rbx), 8);
1032     dynreg_to_user[x86_64::rdx] =   make_pair(offsetof(reg, r_rdx), 8);
1033     dynreg_to_user[x86_64::rcx] =   make_pair(offsetof(reg, r_rcx), 8);
1034     dynreg_to_user[x86_64::rax] =   make_pair(offsetof(reg, r_rax), 8);
1035     dynreg_to_user[x86_64::rip] =   make_pair(offsetof(reg, r_rip), 8);
1036     dynreg_to_user[x86_64::rsp] =   make_pair(offsetof(reg, r_rsp), 8);
1037     dynreg_to_user[x86_64::flags] = make_pair(offsetof(reg, r_rflags), 8);
1038     dynreg_to_user[x86_64::cs] =    make_pair(offsetof(reg, r_cs), 8);
1039     dynreg_to_user[x86_64::ss] =    make_pair(offsetof(reg, r_ss), 8);
1040
1041     // x86 registers -- it appears that not all the segment registers are available
1042     dynreg_to_user[x86::edi] = make_pair(offsetof(reg, r_rdi), 4);
1043     dynreg_to_user[x86::esi] = make_pair(offsetof(reg, r_rsi), 4);
1044     dynreg_to_user[x86::ebp] = make_pair(offsetof(reg, r_rbp), 4);
1045     dynreg_to_user[x86::ebx] = make_pair(offsetof(reg, r_rbx), 4);
1046     dynreg_to_user[x86::edx] = make_pair(offsetof(reg, r_rdx), 4);
1047     dynreg_to_user[x86::ecx] = make_pair(offsetof(reg, r_rcx), 4);
1048     dynreg_to_user[x86::eax] = make_pair(offsetof(reg, r_rax), 4);
1049     dynreg_to_user[x86::eip] = make_pair(offsetof(reg, r_rip), 4);
1050     dynreg_to_user[x86::flags] = make_pair(offsetof(reg, r_rflags), 4);
1051     dynreg_to_user[x86::esp] = make_pair(offsetof(reg, r_rsp), 4);
1052     dynreg_to_user[x86::ss] = make_pair(offsetof(reg, r_ss), 4);
1053     dynreg_to_user[x86::cs] = make_pair(offsetof(reg, r_cs), 4);
1054     
1055 #elif defined(arch_x86)
1056     dynreg_to_user[x86::fs] = make_pair(offsetof(reg, r_fs), 4);
1057     dynreg_to_user[x86::es] = make_pair(offsetof(reg, r_es), 4);
1058     dynreg_to_user[x86::ds] = make_pair(offsetof(reg, r_ds), 4);
1059     dynreg_to_user[x86::edi] = make_pair(offsetof(reg, r_edi), 4);
1060     dynreg_to_user[x86::esi] = make_pair(offsetof(reg, r_esi), 4);
1061     dynreg_to_user[x86::ebp] = make_pair(offsetof(reg, r_ebp), 4);
1062     dynreg_to_user[x86::ebx] = make_pair(offsetof(reg, r_ebx), 4);
1063     dynreg_to_user[x86::edx] = make_pair(offsetof(reg, r_edx), 4);
1064     dynreg_to_user[x86::ecx] = make_pair(offsetof(reg, r_ecx), 4);
1065     dynreg_to_user[x86::eax] = make_pair(offsetof(reg, r_eax), 4);
1066     dynreg_to_user[x86::eip] = make_pair(offsetof(reg, r_eip), 4);
1067     dynreg_to_user[x86::cs] = make_pair(offsetof(reg, r_cs), 4);
1068     dynreg_to_user[x86::flags] = make_pair(offsetof(reg, r_eflags), 4);
1069     dynreg_to_user[x86::esp] = make_pair(offsetof(reg, r_esp), 4);
1070     dynreg_to_user[x86::ss] = make_pair(offsetof(reg, r_ss), 4);
1071     dynreg_to_user[x86::gs] = make_pair(offsetof(reg, r_gs), 4);
1072 #else
1073     // TODO implement this for other architectures
1074     assert(!"Register conversion is not implemented for this architecture");
1075 #endif
1076
1077     initialized = true;
1078
1079     init_lock.unlock();
1080 }
1081
1082 #if 0 
1083 // Debugging
1084 static void dumpRegisters(struct reg *regs) {
1085 #if defined(arch_x86)
1086     fprintf(stderr, "r_fs = 0x%x\n", regs->r_fs);
1087     fprintf(stderr, "r_es = 0x%x\n", regs->r_es);
1088     fprintf(stderr, "r_ds = 0x%x\n", regs->r_ds);
1089     fprintf(stderr, "r_edi = 0x%x\n", regs->r_edi);
1090     fprintf(stderr, "r_esi = 0x%x\n", regs->r_esi);
1091     fprintf(stderr, "r_ebp = 0x%x\n", regs->r_ebp);
1092     fprintf(stderr, "r_ebx = 0x%x\n", regs->r_ebx);
1093     fprintf(stderr, "r_ecx = 0x%x\n", regs->r_ecx);
1094     fprintf(stderr, "r_eax = 0x%x\n", regs->r_eax);
1095     fprintf(stderr, "r_eip = 0x%x\n", regs->r_eip);
1096     fprintf(stderr, "r_cs = 0x%x\n", regs->r_cs);
1097     fprintf(stderr, "r_eflags = 0x%x\n", regs->r_eflags);
1098     fprintf(stderr, "r_esp = 0x%x\n", regs->r_esp);
1099     fprintf(stderr, "r_ss = 0x%x\n", regs->r_ss);
1100     fprintf(stderr, "r_gs = 0x%x\n", regs->r_gs);
1101     fprintf(stderr, "r_trapno = 0x%x\n", regs->r_trapno);
1102     fprintf(stderr, "r_err = 0x%x\n", regs->r_err);
1103 #endif
1104 }
1105 #endif
1106
1107 bool freebsd_process::plat_individualRegAccess() {
1108     return false;
1109 }
1110
1111 string freebsd_process::getThreadLibName(const char *symName) {
1112     // XXX
1113     // This hack is needed because the FreeBSD implementation doesn't
1114     // set the object name when looking for a symbol -- instead of
1115     // searching every library for the symbol, make some educated 
1116     // guesses
1117     //
1118     // It also assumes that the first symbols thread_db will lookup
1119     // are either _libthr_debug or _libkse_debug
1120     
1121     if( !strcmp(symName, "_libkse_debug") ) {
1122         libThreadName = "libkse.so";
1123     }else if( !strcmp(symName, "_libthr_debug") || 
1124             libThreadName.empty() ) 
1125     {
1126         libThreadName = "libthr.so";
1127     }
1128
1129     return libThreadName;
1130 }
1131
1132 bool freebsd_process::isSupportedThreadLib(const string &libName) {
1133     if( libName.find("libthr") != string::npos ) {
1134         return true;
1135     }else if( libName.find("libkse") != string::npos ) {
1136         return true;
1137     }
1138
1139     return false;
1140 }
1141
1142 bool freebsd_thread::plat_getAllRegisters(int_registerPool &regpool) {
1143     struct reg registers;
1144     unsigned char *regPtr = (unsigned char *)&registers;
1145
1146     if( 0 != ptrace(PT_GETREGS, lwp, (caddr_t)regPtr, 0) ) {
1147         perr_printf("Error reading registers from LWP %d\n", lwp);
1148         setLastError(err_internal, "Could not read registers from thread");
1149         return false;
1150     }
1151
1152     init_dynreg_to_user();
1153
1154     Dyninst::Architecture curplat = llproc()->getTargetArch();
1155     regpool.regs.clear();
1156
1157     dynreg_to_user_t::iterator i;
1158     for(i = dynreg_to_user.begin(); i != dynreg_to_user.end(); ++i ) {
1159         const MachRegister reg = i->first;
1160         if (reg.getArchitecture() != curplat ) continue;
1161
1162         MachRegisterVal val;
1163         const unsigned int offset = i->second.first;
1164         const unsigned int size = i->second.second;
1165
1166         if( size == sizeof(uint32_t) ) {
1167             val = *((uint32_t *)(&regPtr[offset]));
1168         }else if( size == sizeof(uint64_t) ) {
1169             val = *((uint64_t *)(&regPtr[offset]));
1170         }else{
1171             assert(!"Unknown address width");
1172         }
1173         pthrd_printf("Register %s has value 0x%lx, offset 0x%x\n", reg.name(), (unsigned long)val, offset);
1174         regpool.regs[reg] = val;
1175     }
1176
1177     return true;
1178 }
1179
1180 static bool validateRegisters(struct reg *regs, Dyninst::LWP lwp) {
1181 #if defined(arch_x86)
1182     struct reg old_regs;
1183     if( 0 != ptrace(PT_GETREGS, lwp, (caddr_t)&old_regs, 0) ) {
1184         perr_printf("Error reading registers from LWP %d\n", lwp);
1185         return false;
1186     }
1187
1188     // Sometimes the resume flag is set in the saved version of the
1189     // registers and not set in the current set of registers -- 
1190     // the OS doesn't allow us to change this flag, change it to the
1191     // current value
1192     if( (old_regs.r_eflags & PSL_RF) != (regs->r_eflags & PSL_RF) ) {
1193         if( old_regs.r_eflags & PSL_RF ) regs->r_eflags |= PSL_RF;
1194         else regs->r_eflags &= ~PSL_RF;
1195     }
1196 #endif
1197     return true;
1198 }
1199
1200 bool freebsd_thread::plat_setAllRegisters(int_registerPool &regpool) {
1201     init_dynreg_to_user();
1202
1203     // Populate a struct reg using the registerPool
1204     struct reg registers;
1205     unsigned char *regPtr = (unsigned char *)&registers;
1206
1207     dynreg_to_user_t::iterator i;
1208     unsigned num_found = 0;
1209     Dyninst::Architecture curplat = llproc()->getTargetArch();
1210
1211     for (i = dynreg_to_user.begin(); i != dynreg_to_user.end(); ++i) {
1212         const MachRegister reg = i->first;
1213         MachRegisterVal val;
1214
1215         if (reg.getArchitecture() != curplat) continue;
1216
1217         const unsigned int offset = i->second.first;
1218         const unsigned int size = i->second.second;
1219
1220         assert(offset+size <= sizeof(struct reg));
1221
1222         int_registerPool::reg_map_t::iterator j = regpool.regs.find(reg);
1223
1224         // A register was not set in the registerPool, error report after loop
1225         if( j == regpool.regs.end() ) break;
1226
1227         num_found++;
1228         val = j->second;
1229
1230         if (size == sizeof(uint32_t)) {
1231             *((uint32_t *)&regPtr[offset]) = (uint32_t) val;
1232         } else if (size == sizeof(uint64_t)) {
1233             *((uint64_t *)&regPtr[offset]) = (uint64_t) val;
1234         } else {
1235             assert(!"Unknown address width");
1236         }
1237
1238         pthrd_printf("Register %s gets value 0x%lx, offset 0x%x\n", reg.name(), (unsigned long)val, offset);
1239     }
1240
1241     if (num_found != regpool.regs.size()) {
1242         setLastError(err_badparam, "Invalid register set passed to setAllRegisters");
1243         perr_printf("Couldn't find all registers in the register set %u/%u\n", num_found,
1244                     (unsigned int) regpool.regs.size());
1245         return false;
1246     }
1247
1248     if( 0 != ptrace(PT_SETREGS, lwp, (caddr_t)&registers, 0) ) {
1249         bool success = false;
1250         if( EINVAL == errno ) {
1251             // This usually means that the flag register would change some system status bits
1252             pthrd_printf("Attempting to handle EINVAL caused by PT_SETREGS for LWP %d\n", lwp);
1253
1254             if( validateRegisters(&registers, lwp) ) {
1255                 if( !ptrace(PT_SETREGS, lwp, (caddr_t)&registers, 0) ) {
1256                     pthrd_printf("Successfully handled EINVAL caused by PT_SETREGS\n");
1257                     success = true;
1258                 }else{
1259                     perr_printf("Failed to handle EINVAL caused by PT_SETREGS\n");
1260                 }
1261             }
1262         }
1263
1264         if( !success ) {
1265             perr_printf("Error setting registers for LWP %d: %s\n", lwp, strerror(errno));
1266             setLastError(err_internal, "Could not set registers in thread");
1267             return false;
1268         }
1269     }
1270
1271     pthrd_printf("Successfully set the values of all registers for LWP %d\n", lwp);
1272
1273     return true;
1274 }
1275
1276 bool freebsd_thread::plat_getRegister(Dyninst::MachRegister, Dyninst::MachRegisterVal &) {
1277     assert(!"This platform does not have individual register access");
1278     return false;
1279 }
1280
1281 bool freebsd_thread::plat_setRegister(Dyninst::MachRegister, Dyninst::MachRegisterVal) {
1282     assert(!"This platform does not have individual register access");
1283     return false;
1284 }
1285
1286 // iRPC snippets
1287 const unsigned int x86_64_mmap_flags_position = 17;
1288 const unsigned int x86_64_mmap_size_position = 30;
1289 const unsigned int x86_64_mmap_addr_position = 40;
1290 const unsigned int x86_64_mmap_start_position = 0;
1291 const unsigned char x86_64_call_mmap[] = {
1292 0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0,%r9 (offset)
1293 0x49, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff,       //mov    $0xffffffffffffffff,%r8 (fd)
1294 0x49, 0xc7, 0xc2, 0x12, 0x10, 0x00, 0x00,       //mov    $0x1012,%r10 (flags)
1295 0x48, 0xc7, 0xc2, 0x07, 0x00, 0x00, 0x00,       //mov    $0x7,%rdx (perms)
1296 0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi (size)
1297 0x00, 0x00, 0x00,                               //
1298 0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi (addr)
1299 0x00, 0x00, 0x00,                               //
1300 0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
1301 0x0f, 0x05,                                     //syscall
1302 0xcc,                                           //trap
1303 0x90                                            //nop
1304 };
1305 const unsigned int x86_64_call_mmap_size = sizeof(x86_64_call_mmap);
1306
1307 const unsigned int x86_64_munmap_size_position = 2;
1308 const unsigned int x86_64_munmap_addr_position = 12;
1309 const unsigned int x86_64_munmap_start_position = 0;
1310 const unsigned char x86_64_call_munmap[] = {
1311 0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi
1312 0x00, 0x00, 0x00,                               //
1313 0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi
1314 0x00, 0x00, 0x00,                               //
1315 0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax
1316 0x0f, 0x05,                                     //syscall
1317 0xcc,                                           //trap
1318 0x90                                            //nop
1319 };
1320 const unsigned int x86_64_call_munmap_size = sizeof(x86_64_call_munmap);
1321
1322 const unsigned int x86_mmap_flags_position = 5;
1323 const unsigned int x86_mmap_size_position = 12;
1324 const unsigned int x86_mmap_addr_position = 17;
1325 const unsigned int x86_mmap_start_position = 0;
1326 const unsigned char x86_call_mmap[] = {
1327 0x6a, 0x00,                                     //push   $0x0 (offset)
1328 0x6a, 0xff,                                     //push   $0xffffffff (fd)
1329 0x68, 0x12, 0x10, 0x00, 0x00,                   //push   $0x1012 (flags)
1330 0x6a, 0x07,                                     //push   $0x7 (perms)
1331 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)
1332 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
1333 0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
1334 0x50,                                           //push   %eax (required by calling convention)
1335 0xcd, 0x80,                                     //int    $0x80
1336 0x8d, 0x64, 0x24, 0x1c,                         //lea    0x1c(%esp),%esp
1337 0xcc,                                           //trap
1338 0x90                                            //nop
1339 };
1340 const unsigned int x86_call_mmap_size = sizeof(x86_call_mmap);
1341
1342 const unsigned int x86_munmap_size_position = 1;
1343 const unsigned int x86_munmap_addr_position = 6;
1344 const unsigned int x86_munmap_start_position = 0;
1345 const unsigned char x86_call_munmap[] = {
1346 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)    
1347 0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
1348 0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax (SYS_munmap)
1349 0x50,                                           //push   %eax (required by calling convention)
1350 0xcd, 0x80,                                     //int    $0x80
1351 0x8d, 0x64, 0x24, 0x0c,                         //lea    0xc(%esp),%esp 
1352 0xcc,                                           //trap
1353 0x90                                            //nop
1354 };
1355 const unsigned int x86_call_munmap_size = sizeof(x86_call_munmap);