extended parseThat to use new addressSpace abstraction
[dyninst.git] / parseThat / src / dyninstCompat.v5.C
1 #include <iostream>
2 #include <list>
3 #include <vector>
4 #include <string>
5 #include <algorithm>
6 #include <unistd.h>
7
8 #include "BPatch.h"
9 #include "BPatch_Vector.h"
10 #include "BPatch_process.h"
11 #include "BPatch_snippet.h"
12 #include "BPatch_function.h"
13
14 #include "dyninstCompat.h"
15 #include "config.h"
16 #include "ipc.h"
17 #include "log.h"
18
19 using namespace std;
20
21 void printSummary(BPatch_thread *, BPatch_exitType);
22 void reportNewProcess(BPatch_thread *, BPatch_thread *);
23
24 dynHandle *mutatorInit(void)
25 {
26     dynHandle *dh = new dynHandle;
27     if (!dh) {
28         dlog(ERR, "Could not allocate %d bytes of memory in mutatorInit().\n", sizeof(dynHandle));
29         return NULL;
30     }
31
32     sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO);
33     dh->bpatch = new BPatch;
34     if (!dh->bpatch) {
35         sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO, ID_FAIL,
36                 "Failure creating new BPatch object");
37         return NULL;
38     } else
39         sendMsg(config.outfd, ID_INIT_CREATE_BPATCH, INFO, ID_PASS);
40
41     /*
42      * BPatch class level flags.
43      */
44     dh->bpatch->setDelayedParsing(true);
45     if (config.use_merge_tramp) {
46         sendMsg(config.outfd, ID_INIT_MERGE_TRAMP, INFO);
47         dh->bpatch->setMergeTramp(true);
48         sendMsg(config.outfd, ID_INIT_MERGE_TRAMP, INFO, ID_PASS);
49     }
50
51     /*
52      * We should probably have a notion of a default callback
53      * handler to return here instead of NULL to differentiate
54      * between the error case.
55      */
56
57     if (config.use_process)
58       {
59         sendMsg(config.outfd, ID_INIT_REGISTER_EXIT, INFO);
60         dh->bpatch->registerExitCallback(printSummary);
61         sendMsg(config.outfd, ID_INIT_REGISTER_EXIT, INFO, ID_PASS);
62         
63         sendMsg(config.outfd, ID_INIT_REGISTER_FORK, INFO);
64         dh->bpatch->registerPostForkCallback(reportNewProcess);
65         sendMsg(config.outfd, ID_INIT_REGISTER_FORK, INFO, ID_PASS);
66       }
67
68     if (config.use_attach) {
69         sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO);
70         printf("Attach Process\n");
71         dh->addSpace = dh->bpatch->processAttach(config.target, config.attach_pid);
72         dh->proc = dynamic_cast<BPatch_process *>(dh->addSpace);
73         if (!dh->proc) {
74             sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO, ID_FAIL,
75                     "Failure in BPatch::processAttach()");
76             return NULL;
77         } else {
78             config.dynlib = dh;
79             sendMsg(config.outfd, ID_INIT_ATTACH_PROCESS, INFO, ID_PASS,
80                     dh->proc->getPid());
81         }
82
83     } else if (config.use_process){
84         sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO);
85         printf("Process Create\n");
86         dh->addSpace = dh->bpatch->processCreate(config.target, (const char **)config.argv);
87         dh->proc = dynamic_cast<BPatch_process *>(dh->addSpace);
88         if (!dh->proc) {
89             sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_FAIL,
90                     "Failure in BPatch::processCreate()");
91             return NULL;
92         } else {
93             config.dynlib = dh;
94             sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_PASS,
95                     dh->proc->getPid());
96         }
97     } else {
98       printf("Created BPatch_binaryEdit\n");
99       dh->addSpace = new BPatch_binaryEdit(config.target);
100       if (!dh->addSpace) {
101         sendMsg(config.outfd, ID_INIT_CREATE_PROCESS, INFO, ID_FAIL,
102                 "Failure in BPatch:_binaryEdit constructor");
103         return NULL;
104       } else {
105         config.dynlib = dh;
106       }
107       }
108
109     if (config.use_save_world) {
110         sendMsg(config.outfd, ID_INIT_SAVE_WORLD, INFO);
111         dh->proc->enableDumpPatchedImage();
112         sendMsg(config.outfd, ID_INIT_SAVE_WORLD, INFO, ID_PASS);
113     }
114
115     sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO);
116     //dh->image = dh->proc->getImage();
117     dh->image = dh->addSpace->getImage();
118     if (!dh->image) {
119         sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO, ID_FAIL,
120                 "Failure in BPatch_process::getImage()");
121         return NULL;
122     } else
123         sendMsg(config.outfd, ID_INIT_GET_IMAGE, INFO, ID_PASS);
124
125     return dh;
126 }
127
128 bool dynStartTransaction(dynHandle *dh)
129 {
130     sendMsg(config.outfd, ID_INST_START_TRANS, INFO);
131     dh->proc->beginInsertionSet();
132     sendMsg(config.outfd, ID_INST_START_TRANS, INFO, ID_PASS);
133     return true;
134 }
135
136 bool dynEndTransaction(dynHandle *dh)
137 {
138     sendMsg(config.outfd, ID_INST_END_TRANS, INFO);
139     if (!dh->proc->finalizeInsertionSet(false)) {
140         sendMsg(config.outfd, ID_INST_END_TRANS, INFO, ID_FAIL,
141                 "Instrumentation transaction failed.  Program left in unknown state.");
142         return false;
143     }
144     sendMsg(config.outfd, ID_INST_END_TRANS, INFO, ID_PASS);
145     return true;
146 }