Update copyright to LGPL on all files
[dyninst.git] / parseThat / src / dyninstCompat.v5.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 #include <iostream>
32 #include <list>
33 #include <vector>
34 #include <string>
35 #include <algorithm>
36 #include <unistd.h>
37
38 #include "BPatch.h"
39 #include "BPatch_Vector.h"
40 #include "BPatch_process.h"
41 #include "BPatch_snippet.h"
42 #include "BPatch_function.h"
43
44 #include "dyninstCompat.h"
45 #include "config.h"
46 #include "ipc.h"
47 #include "log.h"
48
49 using namespace std;
50
51 void printSummary(BPatch_thread *, BPatch_exitType);
52 void reportNewProcess(BPatch_thread *, BPatch_thread *);
53
54 dynHandle *mutatorInit(void)
55 {
56     dynHandle *dh = new dynHandle;
57     if (!dh) {
58         dlog(ERR, "Could not allocate %d bytes of memory in mutatorInit().\n", sizeof(dynHandle));
59         return NULL;
60     }
61
62     sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO);
63     dh->bpatch = new BPatch;
64     if (!dh->bpatch) {
65         sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO, ID_FAIL,
66                 "Failure creating new BPatch object");
67         return NULL;
68     } else
69         sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO, ID_PASS);
70
71     /*
72      * BPatch class level flags.
73      */
74     dh->bpatch->setDelayedParsing(true);
75     if (config.use_merge_tramp) {
76         sendMsg(config.outfd, ID_INIT_MERGE_TRAMP, INFO);
77         dh->bpatch->setMergeTramp(true);
78         sendMsg(config.outfd, ID_INIT_MERGE_TRAMP, INFO, ID_PASS);
79     }
80
81     /*
82      * We should probably have a notion of a default callback
83      * handler to return here instead of NULL to differentiate
84      * between the error case.
85      */
86
87     if (config.use_process)
88       {
89         sendMsg(config.outfd, ID_INIT_REGISTER_EXIT, INFO);
90         dh->bpatch->registerExitCallback(printSummary);
91         sendMsg(config.outfd, ID_INIT_REGISTER_EXIT, INFO, ID_PASS);
92         
93         sendMsg(config.outfd, ID_INIT_REGISTER_FORK, INFO);
94         dh->bpatch->registerPostForkCallback(reportNewProcess);
95         sendMsg(config.outfd, ID_INIT_REGISTER_FORK, INFO, ID_PASS);
96       }
97
98     if (config.use_attach) {
99         sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO);
100         printf("Attach Process\n");
101         dh->addSpace = dh->bpatch->processAttach(config.target, config.attach_pid);
102         dh->proc = dynamic_cast<BPatch_process *>(dh->addSpace);
103         if (!dh->proc) {
104             sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO, ID_FAIL,
105                     "Failure in BPatch::processAttach()");
106             return NULL;
107         } else {
108             config.dynlib = dh;
109             sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO, ID_PASS,
110                     dh->proc->getPid());
111         }
112
113     } else if (config.use_process){
114         sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO);
115         printf("Process Create\n");
116         dh->addSpace = dh->bpatch->processCreate(config.target, (const char **)config.argv);
117         dh->proc = dynamic_cast<BPatch_process *>(dh->addSpace);
118         if (!dh->proc) {
119             sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_FAIL,
120                     "Failure in BPatch::processCreate()");
121             return NULL;
122         } else {
123             config.dynlib = dh;
124             sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_PASS,
125                     dh->proc->getPid());
126         }
127     } else {
128       printf("Created BPatch_binaryEdit\n");
129       //dh->addSpace = new BPatch_binaryEdit(config.target);
130       dh->addSpace = dh->bpatch->openBinary(config.target);
131       if (!dh->addSpace) {
132         sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_FAIL,
133                 "Failure in BPatch:_binaryEdit constructor");
134         return NULL;
135       } else {
136         config.dynlib = dh;
137       }
138       }
139
140     if (config.use_save_world) {
141         sendMsg(config.outfd, ID_INIT_SAVE_WORLD, INFO);
142         dh->proc->enableDumpPatchedImage();
143         sendMsg(config.outfd, ID_INIT_SAVE_WORLD, INFO, ID_PASS);
144     }
145
146     sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO);
147     //dh->image = dh->proc->getImage();
148     dh->image = dh->addSpace->getImage();
149     if (!dh->image) {
150         sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO, ID_FAIL,
151                 "Failure in BPatch_process::getImage()");
152         return NULL;
153     } else
154         sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO, ID_PASS);
155
156     return dh;
157 }
158
159 bool dynStartTransaction(dynHandle *dh)
160 {
161     sendMsg(config.outfd, ID_INST_START_TRANS, INFO);
162     dh->proc->beginInsertionSet();
163     sendMsg(config.outfd, ID_INST_START_TRANS, INFO, ID_PASS);
164     return true;
165 }
166
167 bool dynEndTransaction(dynHandle *dh)
168 {
169     sendMsg(config.outfd, ID_INST_END_TRANS, INFO);
170     if (!dh->proc->finalizeInsertionSet(false)) {
171         sendMsg(config.outfd, ID_INST_END_TRANS, INFO, ID_FAIL,
172                 "Instrumentation transaction failed.  Program left in unknown state.");
173         return false;
174     }
175     sendMsg(config.outfd, ID_INST_END_TRANS, INFO, ID_PASS);
176     return true;
177 }