Move architecture dependent code in PCWidget.C to three separate architecture specifi...
[dyninst.git] / dyninstAPI / src / Relocation / Widgets / PCWidget.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "PCWidget.h"
32 #include "instructionAPI/h/Instruction.h"
33 #include "../dyninstAPI/src/debug.h"
34 #include "../CFG/RelocBlock.h"
35 #include "../CodeBuffer.h"
36 #include "../CodeTracker.h"
37 #include "dyninstAPI/src/function.h"
38
39 #include "dyninstAPI/src/addressSpace.h" // For determining which type of getPC to emit
40 #include "dyninstAPI/src/RegisterConversion.h"
41 #include "dyninstAPI/src/registerSpace.h"
42
43 #include "dyninstAPI/src/emitter.h"
44
45 using namespace Dyninst;
46 using namespace Relocation;
47 using namespace InstructionAPI;
48
49 ////////////////////////
50 PCWidget::Ptr PCWidget::create(Instruction insn,
51                          Address addr,
52                          Absloc a,
53                          Address thunk) {
54   return Ptr(new PCWidget(insn, addr, a, thunk));
55 }
56
57 TrackerElement *PCWidget::tracker(const RelocBlock *t) const {
58   assert(addr_ != 1);
59   EmulatorTracker *e = new EmulatorTracker(addr_, t->block(), t->func());
60   return e;
61 }
62
63 bool PCWidget::generate(const codeGen &templ, const RelocBlock *trace, CodeBuffer &buffer) {
64   // Two options: top of stack (push origAddr) 
65   // or into a register (/w/ a mov)
66
67   switch (a_.type()) {
68   case Absloc::Stack:
69      return PCtoReturnAddr(templ, trace, buffer);
70   case Absloc::Register:
71      return PCtoReg(templ, trace, buffer);
72   default:
73     cerr << "Error: getPC has unknown Absloc type " << a_.format() << endl;
74     return false;
75   }
76 }
77
78 string PCWidget::format() const {
79   stringstream ret;
80   ret << "PCWidget(" 
81       << std::hex << addr_ << std::dec;
82   ret << "" << a_.format();
83   return ret.str();
84 }
85
86
87 unsigned IPPatch::estimate(codeGen &) {
88    // should be the minimum required since we expand
89    // but never contract
90
91    // In the process case we always just generate it 
92    // straight out, because we know the original address.
93
94    // It's gonna be a big one...
95    return 1+4+1+1+1+4 + ((type == Reg) ? 1 : 0);
96 }
97