Fix ARM stack walking (#559)
[dyninst.git] / dyninstAPI / src / inst-aarch64.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 //#warning "This file is not implemented yet!"
32
33 #include "common/src/headers.h"
34 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
35 #include "dyninstAPI/src/image.h"
36 #include "dyninstAPI/src/dynProcess.h"
37 #include "dyninstAPI/src/inst.h"
38 #include "dyninstAPI/src/instP.h"
39 #include "dyninstAPI/src/inst-aarch64.h"
40 #include "common/src/arch.h"
41 #include "dyninstAPI/src/codegen.h"
42 #include "dyninstAPI/src/ast.h"
43 #include "dyninstAPI/src/util.h"
44 #include "common/src/stats.h"
45 #include "dyninstAPI/src/os.h"
46 #include "dyninstAPI/src/instPoint.h" // class instPoint
47 #include "dyninstAPI/src/debug.h"
48 #include "common/src/debugOstream.h"
49 #include "dyninstAPI/src/baseTramp.h"
50 #include "dyninstAPI/h/BPatch.h"
51 #include "dyninstAPI/src/BPatch_collections.h"
52 #include "dyninstAPI/src/registerSpace.h"
53 #include "dyninstAPI/src/binaryEdit.h"
54 #include "dyninstAPI/src/function.h"
55 #include "dyninstAPI/src/mapped_object.h"
56
57 #include "parseAPI/h/CFG.h"
58
59 #include "emitter.h"
60 #include "emit-aarch64.h"
61
62 #include <boost/assign/list_of.hpp>
63 using namespace boost::assign;
64 #include <sstream>
65
66 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
67
68 extern bool isPowerOf2(int value, int &result);
69
70 #define DISTANCE(x, y)   ((x<y) ? (y-x) : (x-y))
71
72 Address getMaxBranch() {
73     return MAX_BRANCH_OFFSET;
74 }
75
76 std::unordered_map<std::string, unsigned> funcFrequencyTable;
77
78 void initDefaultPointFrequencyTable() {
79     assert(0); //Not implemented
80 }
81
82 /************************************* Register Space **************************************/
83
84 void registerSpace::initialize32() {
85     assert(!"No 32-bit implementation for the ARM architecture!");
86 }
87
88 void registerSpace::initialize64() {
89     static bool done = false;
90     if (done)
91         return;
92
93     std::vector < registerSlot * > registers;
94
95     //GPRs
96     for (unsigned idx = r0; idx <= r28; idx++) {
97         char name[32];
98         if (idx < 10)
99             sprintf(name, "r%1d", idx - r0);
100         else
101             sprintf(name, "r%2d", idx - r0);
102         registers.push_back(new registerSlot(idx,
103                                              name,
104                                              false,
105                                              registerSlot::liveAlways,
106                                              registerSlot::GPR));
107     }
108     //Mark r29 (frame pointer) and r30 (link register) as off-limits
109     registers.push_back(new registerSlot(r29, "r29", true, registerSlot::liveAlways, registerSlot::GPR));
110     registers.push_back(new registerSlot(r30, "r30", true, registerSlot::liveAlways, registerSlot::GPR));
111
112     //SPRs
113     registers.push_back(new registerSlot(lr, "lr", true, registerSlot::liveAlways, registerSlot::SPR));
114     registers.push_back(new registerSlot(sp, "sp", true, registerSlot::liveAlways, registerSlot::SPR));
115     registers.push_back(new registerSlot(pstate, "nzcv", true, registerSlot::liveAlways, registerSlot::SPR));
116     registers.push_back(new registerSlot(fpcr, "fpcr", true, registerSlot::liveAlways, registerSlot::SPR));
117     registers.push_back(new registerSlot(fpsr, "fpsr", true, registerSlot::liveAlways, registerSlot::SPR));
118
119     //FPRs
120     for (unsigned idx = fpr0; idx <= fpr31; idx++) {
121         char name[32];
122         sprintf(name, "fpr%d", idx - fpr0);
123         registers.push_back(new registerSlot(idx,
124                                              name,//TODO mov SP to FP
125                                              false,
126                                              registerSlot::liveAlways,
127                                              registerSlot::FPR));
128     }
129
130     registerSpace::createRegisterSpace64(registers);
131     done = true;
132 }
133
134 void registerSpace::initialize() {
135     initialize64();
136 }
137
138 /************************************************************************************************/
139 /************************************************************************************************/
140
141 /********************************* EmitterAARCH64SaveRegs ***************************************/
142
143 /********************************* Private methods *********************************************/
144
145 void EmitterAARCH64SaveRegs::saveSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
146 {
147     assert(scratchReg!=REG_NULL);
148
149     //TODO move map to common location
150     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
151     if(!sysRegCodeMap.count(sprnum))
152         assert(!"Invalid/unknown system register passed to saveSPR()!");
153
154     instruction insn;
155     insn.clear();
156
157     //Set opcode for MRS instruction
158     INSN_SET(insn, 20, 31, MRSOp);
159     //Set destination register
160     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
161     //Set bits representing source system register
162     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
163     insnCodeGen::generate(gen, insn);
164
165     insnCodeGen::generateMemAccess(gen, insnCodeGen::Store, scratchReg,
166             REG_SP, stkOffset, 4, insnCodeGen::Pre);
167 }
168
169
170 void EmitterAARCH64SaveRegs::saveFPRegister(codeGen &gen, Register reg, int save_off) {
171     //Always performing save of the full FP register
172     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Store, reg, REG_SP, save_off, 0, true);
173
174 }
175
176 /********************************* Public methods *********************************************/
177
178 unsigned EmitterAARCH64SaveRegs::saveGPRegisters(
179         codeGen &gen, registerSpace *theRegSpace, int offset, int numReqGPRs)
180 {
181     int ret = 0;
182     if(numReqGPRs == -1) numReqGPRs = theRegSpace->numGPRs();
183
184     for(unsigned int idx = 0; idx < numReqGPRs; idx++) {
185         registerSlot *reg = theRegSpace->GPRs()[idx];
186         // We always save FP and LR for stack walking out of instrumentation
187         if (reg->liveState == registerSlot::live || reg->number == REG_FP || reg->number == REG_LR) {
188             int offset_from_sp = offset + (reg->encoding() * gen.width());
189             insnCodeGen::saveRegister(gen, reg->number, offset_from_sp);
190             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
191             ret++;
192         }
193     }
194
195     return ret;
196 }
197
198 unsigned EmitterAARCH64SaveRegs::saveFPRegisters(
199         codeGen &gen, registerSpace *theRegSpace, int offset)
200 {
201     unsigned ret = 0;
202
203     for(int idx = 0; idx < theRegSpace->numFPRs(); idx++) {
204         registerSlot *reg = theRegSpace->FPRs()[idx];
205
206         //if(reg->liveState == registerSlot::live) {
207             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
208             saveFPRegister(gen, reg->number, offset_from_sp);
209             //reg->liveState = registerSlot::spilled;
210             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
211             ret++;
212         //}
213     }
214
215     return ret;
216 }
217
218 unsigned EmitterAARCH64SaveRegs::saveSPRegisters(
219         codeGen &gen, registerSpace *theRegSpace, int offset, bool force_save)
220 {
221     int ret = 0;
222
223     std::vector<registerSlot *> spRegs;
224     map<registerSlot *, int> regMap;
225
226     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
227     assert(regNzcv);
228     regMap[regNzcv] = SPR_NZCV;
229     if(force_save || regNzcv->liveState == registerSlot::live)
230         spRegs.push_back(regNzcv);
231
232     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
233     assert(regFpcr);
234     regMap[regFpcr] = SPR_FPCR;
235     if(force_save || regFpcr->liveState == registerSlot::live)
236         spRegs.push_back(regFpcr);
237
238     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
239     assert(regFpsr);
240     regMap[regFpsr] = SPR_FPSR;
241     if(force_save || regFpsr->liveState == registerSlot::live)
242         spRegs.push_back(regFpsr);
243
244     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
245         registerSlot *cur = *itr;
246         saveSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], -4*GPRSIZE_32);
247         theRegSpace->markSavedRegister(cur->number, offset);
248
249         offset += 4*GPRSIZE_32;
250         ret++;
251     }
252
253     return ret;
254 }
255
256 void EmitterAARCH64SaveRegs::createFrame(codeGen &gen) {
257     //Save link register
258     Register linkRegister = gen.rs()->getRegByName("r30");
259     insnCodeGen::saveRegister(gen, linkRegister, -2*GPRSIZE_64);
260
261     //Save frame pointer
262     Register framePointer = gen.rs()->getRegByName("r29");
263     insnCodeGen::saveRegister(gen, framePointer, -2*GPRSIZE_64);
264
265     //Move stack pointer to frame pointer
266     Register stackPointer = gen.rs()->getRegByName("sp");
267     insnCodeGen::generateMoveSP(gen, stackPointer, framePointer, true);
268 }
269
270 /***********************************************************************************************/
271 /***********************************************************************************************/
272
273 /********************************* EmitterAARCH64RestoreRegs ************************************/
274
275 /********************************* Public methods *********************************************/
276
277 unsigned EmitterAARCH64RestoreRegs::restoreGPRegisters(
278         codeGen &gen, registerSpace *theRegSpace, int offset)
279 {
280     unsigned ret = 0;
281
282     for(int idx = theRegSpace->numGPRs()-1; idx >=0; idx--) {
283         registerSlot *reg = theRegSpace->GPRs()[idx];
284
285         if(reg->liveState == registerSlot::spilled) {
286             //#sasha this should be GPRSIZE_64 and not gen.width
287             int offset_from_sp = offset + (reg->encoding() * gen.width());
288             insnCodeGen::restoreRegister(gen, reg->number, offset_from_sp);
289             ret++;
290         }
291     }
292
293     return ret;
294 }
295
296 unsigned EmitterAARCH64RestoreRegs::restoreFPRegisters(
297         codeGen &gen, registerSpace *theRegSpace, int offset)
298 {
299     unsigned ret = 0;
300
301     for(int idx = theRegSpace->numFPRs() - 1; idx >= 0; idx--) {
302         registerSlot *reg = theRegSpace->FPRs()[idx];
303
304         //if(reg->liveState == registerSlot::spilled) {
305             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
306             restoreFPRegister(gen, reg->number, offset_from_sp);
307             ret++;
308         //}
309     }
310
311     return ret;
312 }
313
314 unsigned EmitterAARCH64RestoreRegs::restoreSPRegisters(
315         codeGen &gen, registerSpace *theRegSpace, int offset, int force_save)
316 {
317     int ret = 0;
318
319     std::vector<registerSlot *> spRegs;
320     map<registerSlot *, int> regMap;
321
322     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
323     assert(regNzcv);
324     regMap[regNzcv] = SPR_NZCV;
325     if(force_save || regNzcv->liveState == registerSlot::spilled)
326         spRegs.push_back(regNzcv);
327
328     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
329     assert(regFpcr);
330     regMap[regFpcr] = SPR_FPCR;
331     if(force_save || regFpcr->liveState == registerSlot::spilled)
332         spRegs.push_back(regFpcr);
333
334     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
335     assert(regFpsr);
336     regMap[regFpsr] = SPR_FPSR;
337     if(force_save || regFpsr->liveState == registerSlot::spilled)
338         spRegs.push_back(regFpsr);
339
340     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
341         registerSlot *cur = *itr;
342         restoreSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], 4*GPRSIZE_32);
343         ret++;
344     }
345
346     return ret;
347 }
348
349 void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen) {
350     //Restore frame pointer
351     Register framePointer = gen.rs()->getRegByName("r29");
352     insnCodeGen::restoreRegister(gen, framePointer, 2*GPRSIZE_64);
353
354     //Restore link register
355     Register linkRegister = gen.rs()->getRegByName("r30");
356     insnCodeGen::restoreRegister(gen, linkRegister, 2*GPRSIZE_64);
357 }
358
359
360 /********************************* Private methods *********************************************/
361
362 void EmitterAARCH64RestoreRegs::restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
363 {
364     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, 4);
365
366     //TODO move map to common location
367     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
368     if (!sysRegCodeMap.count(sprnum))
369         assert(!"Invalid/unknown system register passed to restoreSPR()!");
370
371     instruction insn;
372     insn.clear();
373
374     //Set opcode for MSR (register) instruction
375     INSN_SET(insn, 20, 31, MSROp);
376     //Set source register
377     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
378     //Set bits representing destination system register
379     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
380     insnCodeGen::generate(gen, insn);
381 }
382
383 void EmitterAARCH64RestoreRegs::restoreFPRegister(codeGen &gen, Register reg, int save_off) {
384     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Load, reg, REG_SP, save_off, 0, true);
385 }
386
387 /***********************************************************************************************/
388 /***********************************************************************************************/
389
390 /*
391  * Emit code to push down the stack
392  */
393 void pushStack(codeGen &gen)
394 {
395     if (gen.width() == 8)
396         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Sub, 0,
397                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
398     else
399         assert(0); // 32 bit not implemented
400 }
401
402 void popStack(codeGen &gen)
403 {
404     if (gen.width() == 8)
405         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0,
406                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
407     else
408         assert(0); // 32 bit not implemented
409 }
410
411 /*********************************** Base Tramp ***********************************************/
412 bool baseTramp::generateSaves(codeGen &gen, registerSpace *)
413 {
414     regalloc_printf("========== baseTramp::generateSaves\n");
415
416     // Make a stack frame.
417     pushStack(gen);
418
419     EmitterAARCH64SaveRegs saveRegs;
420     unsigned int width = gen.width();
421
422     saveRegs.saveGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
423     // After saving GPR, we move SP to FP to create the instrumentation frame.
424     // Note that Dyninst instrumentation frame has a different structure
425     // compared to stack frame created by the compiler.
426     //
427     // Dyninst instrumentation frame makes sure that FP and SP are the same.
428     // So, during stack walk, the FP retrived from the previous frame is 
429     // the SP of the current instrumentation frame.
430     //
431     // Note: If the implementation of the instrumentation frame layout
432     // needs to be changed, DyninstDynamicStepperImpl::getCallerFrameArch
433     // in stackwalk/src/aarch64-swk.C also likely needs to be changed accordingly
434     insnCodeGen::generateMoveSP(gen, REG_SP, REG_FP, true);
435     gen.markRegDefined(REG_FP);
436
437     bool saveFPRs = BPatch::bpatch->isForceSaveFPROn() ||
438                    (BPatch::bpatch->isSaveFPROn()      &&
439                     gen.rs()->anyLiveFPRsAtEntry()     &&
440                     this->saveFPRs());
441
442     if(saveFPRs) saveRegs.saveFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
443     this->savedFPRs = saveFPRs;
444
445     saveRegs.saveSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
446     //gen.rs()->debugPrint();
447
448     return true;
449 }
450
451 bool baseTramp::generateRestores(codeGen &gen, registerSpace *)
452 {
453     EmitterAARCH64RestoreRegs restoreRegs;
454     unsigned int width = gen.width();
455
456     restoreRegs.restoreSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
457
458     if(this->savedFPRs)
459         restoreRegs.restoreFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
460
461     restoreRegs.restoreGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
462
463     // Tear down the stack frame.
464     popStack(gen);
465
466     return true;
467 }
468
469 /***********************************************************************************************/
470 /***********************************************************************************************/
471
472 //TODO: 32-/64-bit regs?
473 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
474         codeGen &gen, bool /*noCost*/, registerSpace * /* rs */, bool s)
475 {
476     switch(op) {
477         case plusOp:
478         case minusOp:
479             {
480                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
481                 insnCodeGen::generateAddSubShifted(gen,
482                         op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub,
483                         0, 0, rm, src1, dest, true);
484             }
485             break;
486         case timesOp:
487             {
488                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
489                 insnCodeGen::generateMul(gen, rm, src1, dest, true);
490             }
491             break;
492         case divOp:
493             {
494                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
495                 insnCodeGen::generateDiv(gen, rm, src1, dest, true, s);
496             }
497             break;
498         case xorOp:
499             {
500                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
501                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Eor, 0, rm, 0, src1, dest, true);
502             }
503             break;
504         case orOp:
505             {
506                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
507                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Or, 0, rm, 0, src1, dest, true);
508             }
509             break;
510         case andOp:
511             {
512                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
513                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::And, 0, rm, 0, src1, dest, true);
514             }
515             break;
516         case eqOp:
517             {
518                 Register scratch = gen.rs()->getScratchRegister(gen);
519                 emitVload(loadConstOp, src2imm, NULL, scratch, gen, true);
520                 emitV(op, src1, scratch, dest, gen, true);
521             }
522             break;
523         case neOp:
524         case lessOp:
525         case leOp:
526         case greaterOp:
527         case geOp:
528             // note that eqOp could be grouped here too.
529             // There's two ways to implement this.
530             gen.codeEmitter()->emitRelOpImm(op, dest, src1, src2imm, gen, s);
531             return;
532         default:
533             assert(0); // not implemented or not valid
534             break;
535     }
536 }
537
538 void cleanUpAndExit(int status);
539
540 /* Recursive function that goes to where our instrumentation is calling
541 to figure out what registers are clobbered there, and in any function
542 that it calls, to a certain depth ... at which point we clobber everything
543
544 Update-12/06, njr, since we're going to a cached system we are just going to
545 look at the first level and not do recursive, since we would have to also
546 store and reexamine every call out instead of doing it on the fly like before*/
547 bool EmitterAARCH64::clobberAllFuncCall(registerSpace *rs,
548                                         func_instance *callee) {
549     if(!callee)
550         return true;
551
552     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
553
554     if(callee->ifunc()->isLeafFunc()) {
555         std::set<Register> *gpRegs = callee->ifunc()->usedGPRs();
556         for(std::set<Register>::iterator itr = gpRegs->begin(); itr != gpRegs->end(); itr++)
557             rs->GPRs()[*itr]->beenUsed = true;
558
559         std::set<Register> *fpRegs = callee->ifunc()->usedFPRs();
560         for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++)
561             rs->FPRs()[*itr]->beenUsed = true;
562     } else {
563         for(int idx = 0; idx < rs->numGPRs(); idx++)
564             rs->GPRs()[idx]->beenUsed = true;
565         for(int idx = 0; idx < rs->numFPRs(); idx++)
566             rs->FPRs()[idx]->beenUsed = true;
567     }
568
569     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
570
571     return false;
572 }
573
574 Register emitFuncCall(opCode, codeGen &, std::vector <AstNodePtr> &, bool, Address) {
575     assert(0);
576     return 0;
577 }
578
579 Register emitFuncCall(opCode op,
580                       codeGen &gen,
581                       std::vector <AstNodePtr> &operands, bool noCost,
582                       func_instance *callee) {
583     return gen.emitter()->emitCall(op, gen, operands, noCost, callee);
584 }
585
586 Register EmitterAARCH64::emitCallReplacement(opCode ocode,
587                                              codeGen &gen,
588                                              bool /* noCost */,
589                                              func_instance *callee) {
590     assert(0); //Not implemented
591     return 0;
592 }
593
594 // There are four "axes" going on here:
595 // 32 bit vs 64 bit
596 // Instrumentation vs function call replacement
597 // Static vs. dynamic
598
599 Register EmitterAARCH64::emitCall(opCode op,
600                                   codeGen &gen,
601                                   const std::vector<AstNodePtr> &operands,
602                                   bool noCost,
603                                   func_instance *callee) 
604 {
605     //#sasha This function implementation is experimental.
606
607     if (op != callOp) {
608         cerr << "ERROR: emitCall with op == " << op << endl;
609     }
610     assert(op == callOp);
611
612     std::vector<Register> srcs;
613     std::vector<Register> saves;
614
615     //  Sanity check for NULL address arg
616     if (!callee) 
617     {
618         char msg[256];
619         sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
620                 "callee argument", __FILE__, __LINE__);
621         showErrorCallback(80, msg);
622         assert(0);
623     }
624
625     vector<int> savedRegs;
626
627     // save r0-r7
628     for(size_t id = 0; id < gen.rs()->numGPRs(); id++)
629     {
630         registerSlot *reg = gen.rs()->GPRs()[id];
631
632         // We must save if:
633         // refCount > 0 (and not a source register)
634         // keptValue == true (keep over the call)
635         // liveState == live (technically, only if not saved by the callee)
636
637         if ((reg->refCount > 0) || reg->keptValue || (reg->liveState == registerSlot::live))
638         {
639             insnCodeGen::saveRegister(gen, registerSpace::r0 + id,
640                     -2*GPRSIZE_64, insnCodeGen::Post);
641             savedRegs.push_back(reg->number);
642         }
643     }
644
645     // Passing operands to registers
646     for(size_t id = 0; id < operands.size(); id++)
647     {
648         Register reg = REG_NULL;
649         if (gen.rs()->allocateSpecificRegister(gen, registerSpace::r0 + id, true))
650             reg = registerSpace::r0 + id;
651
652         Address unnecessary = ADDR_NULL;
653         if (!operands[id]->generateCode_phase2(gen, false, unnecessary, reg))
654             assert(0);
655         assert(reg!=REG_NULL);
656     }
657
658     //instPoint *point = gen.point();
659     //assert(point);
660     assert(gen.rs());
661
662     //Address of function to call in scratch register
663     Register scratch = gen.rs()->getScratchRegister(gen);
664     assert(scratch!=REG_NULL);
665     gen.markRegDefined(scratch);
666     insnCodeGen::loadImmIntoReg<Address>(gen, scratch, callee->addr());
667
668     instruction branchInsn;
669     branchInsn.clear();
670
671     //Set bits which are 0 for both BR and BLR
672     INSN_SET(branchInsn, 0, 4, 0);
673     INSN_SET(branchInsn, 10, 15, 0);
674
675     //Set register
676     INSN_SET(branchInsn, 5, 9, scratch);
677
678     //Set other bits. Basically, these are the opcode bits.
679     //The only difference between BR and BLR is that bit 21 is 1 for BLR.
680     INSN_SET(branchInsn, 16, 31, BRegOp);
681     INSN_SET(branchInsn, 21, 21, 1);
682     insnCodeGen::generate(gen, branchInsn);
683
684     /*
685      * Restoring registers
686      */
687
688     // r7-r0
689     for (signed int ui = savedRegs.size()-1; ui >= 0; ui--) {
690         insnCodeGen::restoreRegister(gen, registerSpace::r0 + savedRegs[ui],
691                 2*GPRSIZE_64, insnCodeGen::Post);
692     }
693
694     return 0;
695 }
696
697
698 codeBufIndex_t emitA(opCode op, Register src1, Register src2, long dest,
699         codeGen &gen, RegControl rc, bool noCost)
700 {
701     codeBufIndex_t retval = 0;
702
703     switch (op) {
704         case ifOp: 
705             {
706                 // if src1 == 0 jump to dest
707                 // src1 is a temporary
708                 // dest is a target address
709                 retval = gen.codeEmitter()->emitIf(src1, dest, rc, gen);
710                 break;
711             }
712         case branchOp:
713             {
714                 insnCodeGen::generateBranch(gen, dest);
715                 retval = gen.getIndex();
716                 break;
717             }
718         default:
719             assert(0);        // op not implemented or not expected for this emit!
720     }
721
722     return retval;
723 }
724
725 Register emitR(opCode op, Register src1, Register src2, Register dest,
726                codeGen &gen, bool /*noCost*/,
727                const instPoint * location, bool /*for_MT*/)
728 {
729     registerSlot *regSlot = NULL;
730     unsigned addrWidth = gen.width();
731
732     switch(op){
733         case getRetValOp:
734             regSlot = (*(gen.rs()))[registerSpace::r0];
735             break;
736         case getParamOp:
737             // src1 is the number of the argument
738             // dest is a register where we can store the value
739             //gen.codeEmitter()->emitGetParam(dest, src1, location->type(), op,
740             //        false, gen);
741
742             if(src1 <= 7) {
743                 // src1 is 0..7 - it's a parameter order number, not a register
744                 regSlot = (*(gen.rs()))[registerSpace::r0 + src1];
745                 break;
746
747             } else {
748                 int stkOffset = TRAMP_FRAME_SIZE_64 + (src1 - 8) * sizeof(long);
749                 // printf("TRAMP_FRAME_SIZE_64: %d\n", TRAMP_FRAME_SIZE_64);
750                 // printf("stdOffset = TRAMP_xxx_64 + (argc - 8) * 8 = { %d }\n", stkOffset);
751                 // TODO: PARAM_OFFSET(addrWidth) is currently not used
752                 // should delete that macro if it's useless
753
754                 if (src2 != REG_NULL) insnCodeGen::saveRegister(gen, src2, stkOffset);
755                 insnCodeGen::restoreRegister(gen, dest, stkOffset);
756
757                 return dest;
758             }
759             break;
760         default:
761             assert(0);
762     }
763
764     assert(regSlot);
765     Register reg = regSlot->number;
766
767     switch(regSlot->liveState) {
768         case registerSlot::spilled:
769             {
770                 int offset = TRAMP_GPR_OFFSET(addrWidth);
771                 // its on the stack so load it.
772                 //if (src2 != REG_NULL) saveRegister(gen, src2, reg, offset);
773                 insnCodeGen::restoreRegister(gen, dest, offset + (reg * gen.width()));
774                 return(dest);
775             }
776         case registerSlot::live:
777             {
778                 // its still in a register so return the register it is in.
779                 cerr << "emitR state:" << reg << " live" << endl;
780                 assert(0);
781                 return(reg);
782             }
783         case registerSlot::dead:
784             {
785                 cerr << "emitR state" << reg << ": dead" << endl;
786                 // Uhhh... wha?
787                 assert(0);
788             }
789     }
790     return reg;
791 }
792
793 void emitJmpMC(int /*condition*/, int /*offset*/, codeGen &) {
794     assert(0); //Not implemented
795     // Not needed for memory instrumentation, otherwise TBD
796 }
797
798
799 // VG(11/16/01): Say if we have to restore a register to get its original value
800 // VG(03/15/02): Sync'd with the new AIX tramp
801 // Yuhan(02/05/19): Needs to implement, refering to what registers are saved during the trap
802
803 static inline bool needsRestore(Register x) {
804         if(x>=0 && x<=2 || x>=19 && x <= 31) 
805                 return true;
806         else
807                 return false;
808 }
809
810 // VG(03/15/02): Restore mutatee value of GPR reg to dest GPR
811 static inline void restoreGPRtoGPR(codeGen &gen,
812                                    Register reg, Register dest) {
813     int frame_size, gpr_size, gpr_off;
814         if(!needsRestore(reg)){
815                 assert("No need of restoring this GPR");
816                 return;
817         }
818         
819         //printf("restoring: %d\n", reg);
820
821         frame_size = TRAMP_FRAME_SIZE_64;
822     gpr_size   = GPRSIZE_64;
823     gpr_off    = TRAMP_GPR_OFFSET_64;
824         
825         
826         //Stack Point Register
827         if(reg == 31) {
828             insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0, frame_size, REG_SP, dest, true);     
829         }
830         else {
831                 //cout << "offset " << gpr_off << endl;
832                 insnCodeGen::restoreRegister(gen, dest, gpr_off + reg*gpr_size);
833         }
834         
835         return;
836 }
837
838 // VG(03/15/02): Restore mutatee value of XER to dest GPR
839 static inline void restoreXERtoGPR(codeGen &gen, Register dest) {
840     assert(0); //Not implemented
841 }
842
843 // VG(03/15/02): Move bits 25:31 of GPR reg to GPR dest
844 static inline void moveGPR2531toGPR(codeGen &gen,
845                                     Register reg, Register dest) {
846     assert(0); //Not implemented
847 }
848
849 // VG(11/16/01): Emit code to add the original value of a register to
850 // another. The original value may need to be restored from stack...
851 // VG(03/15/02): Made functionality more obvious by adding the above functions
852 static inline void emitAddOriginal(Register src, Register acc,
853                                    codeGen &gen, bool noCost) {
854         /*
855         bool nr = needsRestore(src);    
856     Register temp;
857     
858     if(nr) {
859         // this needs gen because it uses emitV...
860         temp = gen.rs()->allocateRegister(gen, noCost);
861         
862         // Emit code to restore the original ra register value in temp.
863         // The offset compensates for the gap 0, 3, 4, ...
864         // This writes at insn, and updates insn and base.
865                 
866         restoreGPRtoGPR(gen, src, temp);
867     }
868     else
869         temp = src;
870     */
871     // add temp to dest;
872     // writes at gen+base and updates base, we must update insn...
873     emitV(plusOp, src, acc, acc, gen, noCost, 0);
874     
875         /*
876     if(nr){
877         gen.rs()->freeRegister(temp);
878         }*/
879 }
880
881 // Yuhan(02/04/19): Load in destination the effective address given
882 // by the address descriptor. Used for memory access stuff.
883 void emitASload(const BPatch_addrSpec_NP *as, Register dest, int stackShift,
884                 codeGen &gen,
885                 bool noCost) {
886
887     // Haven't implemented non-zero shifts yet
888     assert(stackShift == 0);
889     int imm = as->getImm();
890     int ra  = as->getReg(0);
891     int rb  = as->getReg(1);
892     int sc  = as->getScale();
893
894         bool restored_ra = false, restored_rb = false;
895         Register original_ra, original_rb, temp;
896     if(ra > -1) {
897                 if(needsRestore(ra)) {
898                 temp = gen.rs()->allocateRegister(gen, noCost);
899                 original_ra = gen.rs()->allocateRegister(gen, noCost);
900                         restoreGPRtoGPR(gen, ra, original_ra);
901                         restored_ra = true;
902                 }
903                 else {
904                         restored_ra = ra;
905                 }
906                 emitAddOriginal(original_ra, dest, gen, noCost);
907         }       
908
909
910     if(rb > -1) {
911             if(needsRestore(rb)) {
912                 temp = gen.rs()->allocateRegister(gen, noCost); 
913                 original_rb = gen.rs()->allocateRegister(gen, noCost);
914                         restoreGPRtoGPR(gen, rb, original_rb);
915                         restored_rb = true;
916                 }
917         // call adds, save 2^scale * rb to dest
918                 insnCodeGen::generateAddSubShifted(gen, insnCodeGen::Add, 0, sc, original_rb, dest, dest, 1);
919         }
920         
921     // emit code to load the immediate (constant offset) into dest; this
922     // writes at gen+base and updates base, we must update insn...
923         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0, imm, dest, dest, true);  
924         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Sub, 0, 0x10, dest, dest, true); 
925         
926         if(restored_ra || restored_rb)
927                 gen.rs()->freeRegister(temp);
928         if(restored_ra)
929         gen.rs()->freeRegister(original_ra);
930         if(restored_rb)
931         gen.rs()->freeRegister(original_rb);
932 }
933
934 void emitCSload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,
935                 bool noCost) {
936     assert(0); //Not implemented
937 }
938
939 void emitVload(opCode op, Address src1, Register src2, Register dest,
940                codeGen &gen, bool /*noCost*/,
941                registerSpace * /*rs*/, int size,
942                const instPoint * /* location */, AddressSpace *proc)
943 {
944     switch(op)
945     {
946         case loadConstOp:
947             // dest is a temporary
948             // src1 is an immediate value
949             // dest = src1:imm32
950             gen.codeEmitter()->emitLoadConst(dest, src1, gen);
951             break;
952         case loadOp:
953             // dest is a temporary
954             // src1 is the address of the operand
955             // dest = [src1]
956             gen.codeEmitter()->emitLoad(dest, src1, size, gen);
957             break;
958         case loadRegRelativeAddr:
959             // (readReg(src2) + src1)
960             // dest is a temporary
961             // src2 is the register
962             // src1 is the offset from the address in src2
963             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, false);
964             break;
965         case loadRegRelativeOp:
966             // *(readReg(src2) + src1)
967             // dest is a temporary
968             // src2 is the register
969             // src1 is the offset from the address in src2
970             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, true);
971             break;
972         default:
973             assert(0); //Not implemented
974             break;
975     }
976 }
977
978 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
979         codeGen &gen, bool noCost,
980         registerSpace * /* rs */, int size,
981         const instPoint * /* location */, AddressSpace *proc)
982 {
983     if (op ==  storeOp) {
984         // [dest] = src1
985         // dest has the address where src1 is to be stored
986         // src1 is a temporary
987         // src2 is a "scratch" register, we don't need it in this architecture
988         gen.codeEmitter()->emitStore(dest, src1, size, gen);
989     }else{
990         assert(0); //Not implemented
991     }
992     return;
993 }
994
995 void emitV(opCode op, Register src1, Register src2, Register dest,
996         codeGen &gen, bool /*noCost*/,
997            registerSpace * /*rs*/, int size,
998            const instPoint * /* location */, AddressSpace *proc, bool s) 
999 {
1000     switch(op){
1001         case plusOp:
1002         case minusOp:
1003         case timesOp:
1004         case orOp:
1005         case andOp:
1006         case xorOp:
1007             gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
1008             break;
1009         case divOp:
1010             insnCodeGen::generateDiv(gen, src2, src1, dest, true, s);
1011             break;
1012         case lessOp:
1013         case leOp:
1014         case greaterOp:
1015         case geOp:
1016         case eqOp:
1017         case neOp:
1018             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen, s);
1019             break;
1020         case loadIndirOp:
1021             size = !size ? proc->getAddressWidth() : size;
1022             // same as loadOp, but the value to load is already in a register
1023             gen.codeEmitter()->emitLoadIndir(dest, src1, size, gen);
1024             break;
1025         case storeIndirOp:
1026             size = !size ? proc->getAddressWidth() : size;
1027             gen.codeEmitter()->emitStoreIndir(dest, src1, size, gen);
1028             break;
1029         default:
1030             //std::cout << "operation not implemented= " << op << endl;
1031             assert(0); // Not implemented
1032             break;
1033     }
1034     return;
1035 }
1036
1037 //
1038 // I don't know how to compute cycles for AARCH64 instructions due to
1039 //   multiple functional units.  However, we can compute the number of
1040 //   instructions and hope that is fairly close. - jkh 1/30/96
1041 //
1042 int getInsnCost(opCode op) {
1043     assert(0); //Not implemented
1044     return NULL;
1045 }
1046
1047 #if 0
1048 // What does this do???
1049 void registerSpace::saveClobberInfo(const instPoint *location)
1050 {
1051   registerSlot *regSlot = NULL;
1052   registerSlot *regFPSlot = NULL;
1053   if (location == NULL)
1054     return;
1055   if (location->actualGPRLiveSet_ != NULL && location->actualFPRLiveSet_ != NULL)
1056     {
1057
1058       // REG guard registers, if live, must be saved
1059       if (location->actualGPRLiveSet_[ REG_GUARD_ADDR ] == LIVE_REG)
1060     location->actualGPRLiveSet_[ REG_GUARD_ADDR ] = LIVE_CLOBBERED_REG;
1061
1062       if (location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] == LIVE_REG)
1063     location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] = LIVE_CLOBBERED_REG;
1064
1065       // GPR and FPR scratch registers, if live, must be saved
1066       if (location->actualGPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
1067     location->actualGPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
1068
1069       if (location->actualFPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
1070     location->actualFPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
1071
1072       // Return func call register, since we make a call because
1073       // of multithreading (regardless if it's threaded) from BT
1074       // we must save return register
1075       if (location->actualGPRLiveSet_[ 3 ] == LIVE_REG)
1076     location->actualGPRLiveSet_[ 3 ] = LIVE_CLOBBERED_REG;
1077
1078
1079       for (u_int i = 0; i < getRegisterCount(); i++)
1080     {
1081       regSlot = getRegSlot(i);
1082
1083       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_REG )
1084         {
1085           if (!registers[i].beenClobbered)
1086         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_UNCLOBBERED_REG;
1087           else
1088         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
1089         }
1090
1091
1092       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_UNCLOBBERED_REG )
1093         {
1094           if (registers[i].beenClobbered)
1095         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
1096         }
1097     }
1098
1099       for (u_int i = 0; i < getFPRegisterCount(); i++)
1100     {
1101       regFPSlot = getFPRegSlot(i);
1102
1103       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_REG )
1104         {
1105           if (!fpRegisters[i].beenClobbered)
1106         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_UNCLOBBERED_REG;
1107           else
1108         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
1109         }
1110
1111       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_UNCLOBBERED_REG )
1112         {
1113           if (fpRegisters[i].beenClobbered)
1114         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
1115         }
1116     }
1117     }
1118 }
1119 #endif
1120
1121 // This is used for checking wether immediate value should be encoded
1122 // into a instruction. In fact, only being used for loading constant
1123 // value into a register, and in ARMv8 there are 16 bits for immediate
1124 // values in the instruction MOV.
1125 // value here is never a negative value since constant values are saved
1126 // as void* in the AST operand.
1127 bool doNotOverflow(int64_t value)
1128 {
1129     if ((value >= 0) && (value <= 0xFFFF)) return true;
1130     else return false;
1131 }
1132
1133
1134 #if !defined(os_vxworks)
1135
1136 // hasBeenBound: returns true if the runtime linker has bound the
1137 // function symbol corresponding to the relocation entry in at the address
1138 // specified by entry and base_addr.  If it has been bound, then the callee
1139 // function is returned in "target_pdf", else it returns false.
1140 bool PCProcess::hasBeenBound(const SymtabAPI::relocationEntry &entry,
1141                              func_instance *&target_pdf, Address base_addr)
1142 {
1143         if (isTerminated()) return false;
1144
1145         // if the relocationEntry has not been bound yet, then the value
1146         // at rel_addr is the address of the instruction immediately following
1147         // the first instruction in the PLT entry (which is at the target_addr)
1148         // The PLT entries are never modified, instead they use an indirrect
1149         // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the
1150         // function symbol is bound by the runtime linker, it changes the address
1151         // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
1152
1153         Address got_entry = entry.rel_addr() + base_addr;
1154         Address bound_addr = 0;
1155         if (!readDataSpace((const void*)got_entry, sizeof(Address),
1156                                 &bound_addr, true)){
1157                 sprintf(errorLine, "read error in PCProcess::hasBeenBound addr 0x%x, pid=%d\n (readDataSpace returns 0)",(unsigned)got_entry,getPid());
1158                 logLine(errorLine);
1159                 //print_read_error_info(entry, target_pdf, base_addr);
1160                 fprintf(stderr, "%s[%d]: %s\n", FILE__, __LINE__, errorLine);
1161                 return false;
1162         }
1163
1164    //fprintf(stderr, "%s[%d]:  hasBeenBound:  %p ?= %p ?\n", FILE__, __LINE__, bound_addr, entry.target_addr() + 6 + base_addr);
1165         if ( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
1166           // the callee function has been bound by the runtime linker
1167           // find the function and return it
1168           target_pdf = findFuncByEntry(bound_addr);
1169           if(!target_pdf){
1170             return false;
1171           }
1172           return true;
1173         }
1174         return false;
1175 }
1176
1177 #endif
1178
1179 bool PCProcess::bindPLTEntry(const SymtabAPI::relocationEntry &, Address,
1180                              func_instance *, Address) {
1181     assert(0); //Not implemented
1182     assert(0 && "TODO!");
1183     return false;
1184 }
1185
1186 void emitLoadPreviousStackFrameRegister(Address register_num,
1187                                         Register dest,
1188                                         codeGen &gen,
1189                                         int /*size*/,
1190                                         bool noCost)
1191 {
1192     gen.codeEmitter()->emitLoadOrigRegister(register_num, dest, gen);
1193 }
1194
1195 void emitStorePreviousStackFrameRegister(Address,
1196                                          Register,
1197                                          codeGen &,
1198                                          int,
1199                                          bool) {
1200     assert(0);
1201 }
1202
1203 // First AST node: target of the call
1204 // Second AST node: source of the call
1205 // This can handle indirect control transfers as well
1206 bool AddressSpace::getDynamicCallSiteArgs(InstructionAPI::Instruction i,
1207                                           Address addr,
1208                                           pdvector<AstNodePtr> &args)
1209 {
1210     using namespace Dyninst::InstructionAPI;
1211     Register branch_target = registerSpace::ignored;
1212
1213     for(Instruction::cftConstIter curCFT = i.cft_begin();
1214             curCFT != i.cft_end(); ++curCFT)
1215     {
1216         auto target_reg = dynamic_cast<RegisterAST *>(curCFT->target.get());
1217         if(!target_reg) return false;
1218         branch_target = target_reg->getID() & 0x1f;
1219         break;
1220     }
1221
1222     if(branch_target == registerSpace::ignored) return false;
1223
1224     //jumping to Xn (BLR Xn)
1225     args.push_back(AstNode::operandNode(AstNode::origRegister,(void *) branch_target));
1226     args.push_back(AstNode::operandNode(AstNode::Constant, (void *) addr));
1227
1228     //inst_printf("%s[%d]:  Inserting dynamic call site instrumentation for %s\n",
1229     //        FILE__, __LINE__, cft->format(insn.getArch()).c_str());
1230     return true;
1231 }
1232
1233 bool writeFunctionPtr(AddressSpace *p, Address addr, func_instance *f) {
1234     Address val_to_write = f->addr();
1235     return p->writeDataSpace((void *) addr, sizeof(Address), &val_to_write);
1236     return false;
1237 }
1238
1239 Emitter *AddressSpace::getEmitter() {
1240     static EmitterAARCH64Stat emitter64Stat;
1241     static EmitterAARCH64Dyn emitter64Dyn;
1242
1243     if (proc())
1244         return &emitter64Dyn;
1245
1246     return &emitter64Stat;
1247 }
1248
1249 #define GET_IP      0x429f0005
1250 #define MFLR_30     0x7fc802a6
1251 #define ADDIS_30_30 0x3fde0000
1252 #define ADDI_30_30  0x3bde0000
1253 #define LWZ_11_30   0x817e0000
1254 #define ADDIS_11_30 0x3d7e0000
1255
1256 /*
1257  * If the target stub_addr is a glink stub, try to determine the actual
1258  * function called (through the GOT) and fill in that information.
1259  *
1260  * The function at stub_addr may not have been created when this method
1261  * is called.
1262  *
1263  * XXX Is this a candidate to move into general parsing code, or is
1264  *     this properly a Dyninst-only technique?
1265  */
1266
1267 /*
1268 bool image::updatePltFunc(parse_func *caller_func, Address stub_addr)
1269 {
1270         assert(0); //Not implemented
1271     return true;
1272 }
1273 */
1274
1275 bool EmitterAARCH64::emitCallRelative(Register dest, Address offset, Register base, codeGen &gen) {
1276     assert(0); //Not implemented
1277     return true;
1278 }
1279
1280 bool EmitterAARCH64::emitLoadRelative(Register dest, Address offset, Register base, int size, codeGen &gen) {
1281     assert(0); //Not implemented
1282     return true;
1283 }
1284
1285
1286 void EmitterAARCH64::emitStoreRelative(Register source, Address offset, Register base, int size, codeGen &gen) {
1287     //return true;
1288     assert(0); //Not implemented
1289 }
1290
1291 bool EmitterAARCH64::emitMoveRegToReg(registerSlot *src,
1292                                       registerSlot *dest,
1293                                       codeGen &gen) {
1294     assert(0); //Not implemented
1295     return true;
1296 }
1297
1298 /*
1299 bool EmitterAARCH6432Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1300
1301       Register scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1302       std::vector<Register> excludeReg;
1303       excludeReg.push_back(scratchPCReg);
1304       Register scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1305       bool newStackFrame = false;
1306       int stack_size = 0;
1307       int gpr_off, fpr_off, ctr_off;
1308       //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx Registers PC %d scratch %d \n", origAddr, relocAddr, scratchPCReg, scratchReg);
1309       if ((scratchPCReg == REG_NULL) || (scratchReg == REG_NULL)) {
1310                 //fprintf(stderr, " Creating new stack frame for 0x%lx to 0x%lx \n", origAddr, relocAddr);
1311
1312                 newStackFrame = true;
1313                 //create new stack frame
1314                 gpr_off = TRAMP_GPR_OFFSET_32;
1315                 fpr_off = TRAMP_FPR_OFFSET_32;
1316                 ctr_off = STK_CTR_32;
1317
1318                 // Make a stack frame.
1319                 pushStack(gen);
1320
1321                 // Save GPRs
1322               stack_size = saveGPRegisters(gen, gen.rs(), gpr_off, 2);
1323
1324               scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1325               assert(scratchPCReg != REG_NULL);
1326               excludeReg.clear();
1327               excludeReg.push_back(scratchPCReg);
1328               scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1329               assert(scratchReg != REG_NULL);
1330               // relocaAddr has moved since we added instructions to setup a new stack frame
1331               relocAddr = relocAddr + ((stack_size + 1)*(gen.width()));
1332               //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx stack size %d Registers PC %d scratch %d \n", origAddr, relocAddr, stack_size, scratchPCReg, scratchReg);
1333
1334         }
1335         emitMovePCToReg(scratchPCReg, gen);
1336         Address varOffset = origAddr - relocAddr;
1337         emitCallRelative(scratchReg, varOffset, scratchPCReg, gen);
1338         insnCodeGen::generateMoveToLR(gen, scratchReg);
1339         if(newStackFrame) {
1340               // GPRs
1341               restoreGPRegisters(gen, gen.rs(), gpr_off);
1342               popStack(gen);
1343         }
1344
1345       return 0;
1346 }
1347
1348 bool EmitterAARCH64Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1349         assert(0);
1350         return false;
1351 }
1352 bool EmitterAARCH64Dyn::emitPIC(codeGen &gen, Address origAddr, Address relocAddr) {
1353
1354         Address origRet = origAddr + 4;
1355         Register scratch = gen.rs()->getScratchRegister(gen, true);
1356         assert(scratch != REG_NULL);
1357         instruction::loadImmIntoReg(gen, scratch, origRet);
1358         insnCodeGen::generateMoveToLR(gen, scratch);
1359         return true;
1360
1361 }
1362 */
1363
1364 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1365     assert(0); //Not implemented
1366     return true;
1367 }
1368
1369 #if 0
1370 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1371   // In PPC64 Linux, function descriptors are used in place of direct
1372   // function pointers.  The descriptors have the following layout:
1373   //
1374   // Function Descriptor --> + 0: <Function Text Address>
1375   //                         + 8: <TOC Pointer Value>
1376   //                         +16: <Environment Pointer [Optional]>
1377   //
1378   // Additionally, this should be able to stomp on the link register (LR)
1379   // and TOC register (r2), as they were saved by Emitter::emitCall() if
1380   // necessary.
1381   //
1382   // So here's a brief sketch of the code this function generates:
1383   //
1384   //   Set up new branch target in LR from function descriptor
1385   //   Set up new TOC in R2 from function descriptor + 8
1386   //   Call
1387   bool isStaticBinary = false;
1388
1389   if(gen.addrSpace()->edit()->getMappedObject()->parse_img()->getObject()->isStaticBinary()) {
1390     isStaticBinary = true;
1391   }
1392
1393   const unsigned TOCreg = 2;
1394   const unsigned wordsize = gen.width();
1395   assert(wordsize == 8);
1396   Address dest = getInterModuleFuncAddr(callee, gen);
1397   Address caller_toc = 0;
1398   Address toc_anchor = gen.addrSpace()->getTOCoffsetInfo(callee);
1399   // Instead of saving the TOC (if we can't), just reset it afterwards.
1400   if (gen.func()) {
1401     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.func());
1402   }
1403   else if (gen.point()) {
1404     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.point()->func());
1405   }
1406   else {
1407     // Don't need it, and this might be an iRPC
1408   }
1409
1410   if(isStaticBinary)
1411     caller_toc = 0;
1412
1413   //Offset destOff = dest - gen.currAddr();
1414   Offset destOff = dest - caller_toc;
1415
1416   //    insnCodeGen::loadPartialImmIntoReg(gen, TOCreg, destOff);
1417   // Broken to see if any of this generates intellible code.
1418
1419   Register scratchReg = 3; // = gen.rs()->getScratchRegister(gen, true);
1420   int stackSize = 0;
1421   if (scratchReg == REG_NULL) {
1422     std::vector<Register> freeReg;
1423     std::vector<Register> excludeReg;
1424     stackSize = insnCodeGen::createStackFrame(gen, 1, freeReg, excludeReg);
1425     assert (stackSize == 1);
1426     scratchReg = freeReg[0];
1427   }
1428   insnCodeGen::loadImmIntoReg<Offset?(gen, scratchReg, destOff);
1429
1430   if(!isStaticBinary) {
1431     insnCodeGen::generateLoadReg64(gen, scratchReg, scratchReg, TOCreg);
1432
1433     insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1434                      TOCreg, scratchReg, 8);
1435   }
1436   insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1437                    scratchReg, scratchReg, 0);
1438
1439   insnCodeGen::generateMoveToCR(gen, scratchReg);
1440
1441   if (stackSize > 0)
1442     insnCodeGen::removeStackFrame(gen);
1443
1444
1445   instruction branch_insn(call ? BCTRLraw : BCTRraw);
1446   insnCodeGen::generate(gen, branch_insn);
1447
1448   return true;
1449 }
1450 #endif
1451
1452 bool EmitterAARCH64Dyn::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1453     assert(0); //Not implemented
1454     return true;
1455 }
1456
1457 // TODO 32/64-bit?
1458 bool EmitterAARCH64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1459     assert(0); //Not implemented
1460     return emitPLTCommon(callee, true, gen);
1461 }
1462
1463 bool EmitterAARCH64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1464     assert(0); //Not implemented
1465     return emitPLTCommon(callee, false, gen);
1466 }
1467
1468 bool EmitterAARCH64Stat::emitTOCCall(block_instance *block, codeGen &gen) {
1469     assert(0); //Not implemented
1470     return emitTOCCommon(block, true, gen);
1471 }
1472
1473 bool EmitterAARCH64Stat::emitTOCJump(block_instance *block, codeGen &gen) {
1474     assert(0); //Not implemented
1475     return emitTOCCommon(block, false, gen);
1476 }
1477
1478 bool EmitterAARCH64Stat::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1479     assert(0); //Not implemented
1480     return false;
1481 }
1482
1483 bool EmitterAARCH64Stat::emitCallInstruction(codeGen &gen,
1484                                              func_instance *callee,
1485                                              bool setTOC, Address) {
1486     assert(0); //Not implemented
1487     return true;
1488 }
1489
1490 // Generates call instruction sequence for all AARCH64-based systems
1491 // under dynamic instrumentation.
1492 //
1493 // This should be able to stomp on the link register (LR) and TOC
1494 // register (r2), as they were saved by Emitter::emitCall() as necessary.
1495 bool EmitterAARCH64::emitCallInstruction(codeGen &gen, func_instance *callee, bool setTOC, Address toc_anchor) {
1496     assert(0); //Not implemented
1497     return true;
1498 }
1499
1500 void EmitterAARCH64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size,
1501                                     codeGen &gen, Address offset) {
1502     assert(0); //Not implemented
1503     return;
1504 }
1505
1506 void
1507 EmitterAARCH64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen) {
1508     assert(0); //Not implemented
1509     return;
1510 }
1511
1512 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen &gen) {
1513     assert(0); //Not implemented
1514     AddressSpace *addrSpace = gen.addrSpace();
1515     if (!addrSpace)
1516         assert(0 && "No AddressSpace associated with codeGen object");
1517
1518     BinaryEdit *binEdit = addrSpace->edit();
1519     Address relocation_address;
1520     return relocation_address;
1521 }
1522
1523 Address EmitterAARCH64::emitMovePCToReg(Register dest, codeGen &gen) {
1524     assert(0); //Not implemented
1525     insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() + 4, true); // blrl
1526     Address ret = gen.currAddr();
1527     return ret;
1528 }
1529
1530 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen &gen) {
1531     assert(0); //Not implemented
1532     return NULL;
1533 }
1534
1535
1536
1537