Defer constructing blocksByRange to function finalizing, and removing the use blocksB...
[dyninst.git] / parseAPI / src / IA_power.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
32 #include "IA_power.h"
33
34 #include "Register.h"
35 #include "Dereference.h"
36 #include "Immediate.h"
37 #include "BinaryFunction.h"
38
39 #include "common/src/arch.h"
40
41 #include "parseAPI/src/debug_parse.h"
42
43 #include <deque>
44 #include <iostream>
45 #include <sstream>
46 #include <functional>
47 #include <algorithm>
48 #include <set>
49
50 using namespace Dyninst;
51 using namespace InstructionAPI;
52 using namespace Dyninst::ParseAPI;
53 using namespace Dyninst::InsnAdapter;
54
55 static RegisterAST::Ptr ppc32_R11 (new RegisterAST (ppc32::r11));
56 static RegisterAST::Ptr ppc32_LR  (new RegisterAST (ppc32::lr));
57 static RegisterAST::Ptr ppc32_SP  (new RegisterAST (ppc32::r1));
58
59 static RegisterAST::Ptr ppc64_R11 (new RegisterAST (ppc64::r11));
60 static RegisterAST::Ptr ppc64_LR  (new RegisterAST (ppc64::lr));
61 static RegisterAST::Ptr ppc64_SP  (new RegisterAST (ppc64::r1));
62
63 IA_power::IA_power(Dyninst::InstructionAPI::InstructionDecoder dec_,
64                Address start_, 
65                Dyninst::ParseAPI::CodeObject* o,
66                Dyninst::ParseAPI::CodeRegion* r,
67                Dyninst::InstructionSource *isrc,
68                Dyninst::ParseAPI::Block * curBlk_):
69                    IA_IAPI(dec_, start_, o, r, isrc, curBlk_) {
70 }
71 IA_power::IA_power(const IA_power& rhs): IA_IAPI(rhs) {}
72
73 IA_power* IA_power::clone() const{
74     return new IA_power(*this);
75 }
76
77
78 bool IA_power::isFrameSetupInsn(Instruction) const
79 {
80     return false;
81 }
82
83 bool IA_power::isNop() const
84 {
85     return false;
86 }
87
88 bool IA_power::isThunk() const {
89     return false;
90 }
91
92 bool IA_power::isTailCall(const Function* context, EdgeTypeEnum type, unsigned int, const set<Address>& knownTargets) const
93 {
94    // Collapse down to "branch" or "fallthrough"
95     switch(type) {
96        case CALL:
97        case COND_TAKEN:
98        case DIRECT:
99        case INDIRECT:
100        case RET:
101           type = DIRECT;
102           break;
103        case COND_NOT_TAKEN:
104        case FALLTHROUGH:
105        case CALL_FT:
106           type = FALLTHROUGH;
107           break;
108        default:
109           return false;
110     }
111
112     parsing_printf("Checking for Tail Call for powerpc\n");
113     context->obj()->cs()->incrementCounter(PARSE_TAILCALL_COUNT); 
114
115     if (tailCalls.find(type) != tailCalls.end()) {
116         parsing_printf("\tReturning cached tail call check result: %d\n", tailCalls[type]);
117         if (tailCalls[type]) {
118             context->obj()->cs()->incrementCounter(PARSE_TAILCALL_FAIL);
119             return true;
120         }
121         return false;
122     }
123
124     bool valid; Address addr;
125     boost::tie(valid, addr) = getCFT();
126
127     Function* callee = _obj->findFuncByEntry(_cr, addr);
128     Block* target = _obj->findBlockByEntry(_cr, addr);
129
130     if (callee == NULL) {
131         // It could be that this is a within linkage tail call.
132         // So, the function symbol is two instructions ahead of the call target.
133         addr -= 8;
134         callee = _obj->findFuncByEntry(_cr, addr);
135         target = _obj->findBlockByEntry(_cr, addr);     
136     }
137
138     if(curInsn().getCategory() == c_BranchInsn &&
139        valid &&
140        callee && 
141        callee != context &&
142        target &&
143        !context->contains(target)
144        )
145     {
146       parsing_printf("\tjump to 0x%lx, TAIL CALL\n", addr);
147       tailCalls[type] = true;
148       return true;
149     }
150
151     if (curInsn().getCategory() == c_BranchInsn &&
152             valid &&
153             !callee) {
154         if (target) {
155             parsing_printf("\tjump to 0x%lx is known block, but not func entry, NOT TAIL CALL\n", addr);
156             tailCalls[type] = false;
157             return false;
158         } else if (knownTargets.find(addr) != knownTargets.end()) {
159             parsing_printf("\tjump to 0x%lx is known target in this function, NOT TAIL CALL\n", addr);
160             tailCalls[type] = false;
161             return false;
162         }
163     }
164
165     if(allInsns.size() < 2) {
166       if(context->addr() == _curBlk->start() && curInsn().getCategory() == c_BranchInsn)
167       {
168         parsing_printf("\tjump as only insn in entry block, TAIL CALL\n");
169         tailCalls[type] = true;
170         return true;
171       }
172       else
173       {
174         parsing_printf("\ttoo few insns to detect tail call\n");
175         context->obj()->cs()->incrementCounter(PARSE_TAILCALL_FAIL);
176         tailCalls[type] = false;
177         return false;
178       }
179     }
180    
181     tailCalls[type] = false;
182     context->obj()->cs()->incrementCounter(PARSE_TAILCALL_FAIL);
183     return false;
184 }
185
186 bool IA_power::savesFP() const
187 {
188     return false;
189 }
190
191 bool IA_power::isStackFramePreamble() const
192 {
193     return false;
194 }
195
196 bool IA_power::cleansStack() const
197 {
198     return false;
199 }
200
201 class PPCReturnPredicates : public Slicer::Predicates {
202   virtual bool widenAtPoint(Assignment::Ptr p) {
203     for (std::vector<AbsRegion>::const_iterator iter = p->inputs().begin();
204          iter != p->inputs().end(); ++iter) {
205       if ((*iter).type() != Absloc::Unknown)
206         return true;
207     }
208     return false;
209   }
210 };
211
212
213
214 bool IA_power::sliceReturn(ParseAPI::Block* bit, Address ret_addr, ParseAPI::Function * func) const {
215
216   parsing_printf(" sliceReturn ret 0x%lx address 0x%lx func %s addr 0x%lx \n", ret_addr, bit->lastInsnAddr(), func->name().c_str(), func->addr() );
217   AST::Ptr pcDef;
218   AssignmentConverter converter(true, true);
219   vector<Assignment::Ptr>::iterator ait;
220   vector<Assignment::Ptr> assgns;
221   PPCReturnPredicates preds;
222
223   Address retnAddr = bit->lastInsnAddr();
224   InstructionDecoder retdec( _isrc->getPtrToInstruction( retnAddr ), 
225                              InstructionDecoder::maxInstructionLength, 
226                              _cr->getArch() );
227   Instruction retn = retdec.decode();
228   converter.convert(retn, retnAddr, func, bit, assgns);
229   for (ait = assgns.begin(); assgns.end() != ait; ait++) {
230       AbsRegion & outReg = (*ait)->out();
231       if ( outReg.absloc().isPC() ) {
232           Slicer slicer(*ait,bit,func);
233           Graph::Ptr slGraph = slicer.backwardSlice(preds);
234           DataflowAPI::Result_t slRes;
235           DataflowAPI::SymEval::expand(slGraph,slRes);
236           pcDef = slRes[*ait];
237           /*
238           for (DataflowAPI::SymEval::Result_t::const_iterator r_iter = slRes.begin();
239                r_iter != slRes.end(); ++r_iter) {
240               cout << "-----------------" << endl;
241               cout << r_iter->first->format();
242               cout << " == ";
243               cout << (r_iter->second ? r_iter->second->format() : "<NULL>") << endl;
244           }
245           */
246           break;
247       }
248   }
249
250   if (!pcDef) { return false; }
251   PPC_BLR_Visitor checker(ret_addr);
252   pcDef->accept(&checker);
253   if (checker.returnState() == PPC_BLR_Visitor::PPC_BLR_RETURN) {
254     return true;
255   } else {
256             return false;
257   }
258 }
259
260 bool IA_power::isReturnAddrSave(Address& retAddr) const
261 {
262   RegisterAST::Ptr regLR, regSP;
263   regLR = ppc32_LR; regSP = ppc32_SP;
264
265  /* FIXME: InstructionAPI doesn't handle ppc64:LR correctly. 
266   * For now, use ppc32:LR for ppc64 also.
267
268   switch (_isrc->getArch()) {
269   case Arch_ppc32: regLR = ppc32_LR; regSP = ppc32_SP; break;
270   case Arch_ppc64: regLR = ppc64_LR; regSP = ppc64_SP; break;
271   default: assert(0 && "Inappropriate _isrc architechture.");
272   }
273   */
274
275   std::set < RegisterAST::Ptr > regs;
276   RegisterAST::Ptr destLRReg;
277   bool foundMFLR = false;
278   Address ret = 0;
279   int cnt = 1;
280   Instruction ci = curInsn ();
281    parsing_printf(" Examining address 0x%lx to check if LR is saved on stack \n", getAddr());
282     parsing_printf("\t\tchecking insn %s \n", ci.format().c_str());
283
284   if (ci.getOperation().getID () == power_op_mfspr &&
285       ci.isRead (regLR))
286     {
287       foundMFLR = true;
288       ci.getWriteSet (regs);
289       if (regs.size () != 1)
290         {
291           parsing_printf ("mfspr wrote %d registers instead of 1. insn: %s\n",
292                           regs.size (), ci.format ().c_str ());
293           return 0;
294         }
295       destLRReg = *(regs.begin ());
296       retAddr = getAddr();
297       parsing_printf ("Found MFLR saved in %s at 0x%lx\n",
298                       destLRReg->format ().c_str (), getAddr());
299     }
300
301   if (foundMFLR)
302     {
303
304       // walk to first control flow transfer instruction, looking
305       // for a save of destLRReg
306       IA_power copy (dec, getAddr (), _obj, _cr, _isrc, _curBlk);
307       while (!copy.hasCFT ())
308         {
309           ci = copy.curInsn ();
310           if (ci.writesMemory () &&
311               ci.isRead (regSP) && ci.isRead (destLRReg))
312             {
313               ret = true;
314               break;
315             }
316           else if (ci.isWritten (destLRReg))
317             {
318               ret = false;
319               break;
320             }
321           copy.advance ();
322           ++cnt;
323         }
324     }
325   parsing_printf ("[%s:%d] isReturnAddrSave examined %d instructions - returning %d \n", FILE__, __LINE__, cnt, ret);
326   return ret;
327 }
328
329 bool IA_power::isReturn(Dyninst::ParseAPI::Function * context, Dyninst::ParseAPI::Block* currBlk) const
330 {
331   /* Check for leaf node or lw - mflr - blr pattern */
332   if (curInsn().getCategory() != c_ReturnInsn) {
333         parsing_printf(" Not BLR - returning false \n");
334         return false;
335    }
336   Instruction ci = curInsn ();
337   Function *func = context;
338   parsing_printf
339     ("isblrReturn at 0x%lx Addr 0x%lx 0x%lx Function addr 0x%lx leaf %d \n",
340      current, getAddr (), currBlk->start (), context->addr (),
341      func->_is_leaf_function);
342   if (!func->_is_leaf_function)
343     {
344       parsing_printf ("\t LR saved for %s \n", func->name().c_str());
345       // Check for lwz from Stack - mtlr - blr 
346       RegisterAST::Ptr regLR, regSP, reg11;
347                 regLR = ppc32_LR; regSP = ppc32_SP; reg11 = ppc32_R11;
348
349  /* FIXME: InstructionAPI doesn't handle ppc64:LR correctly. 
350   * For now, use ppc32:LR for ppc64 also.
351
352       switch (_isrc->getArch()) {
353       case Arch_ppc32:
354           regLR = ppc32_LR; regSP = ppc32_SP; reg11 = ppc32_R11; break;
355       case Arch_ppc64:
356           regLR = ppc64_LR; regSP = ppc64_SP; reg11 = ppc64_R11; break;
357       default: assert(0 && "Inappropriate _isrc architechture.");
358       }
359 */
360       std::set < RegisterAST::Ptr > regs;
361       RegisterAST::Ptr sourceLRReg;
362
363       Instruction ci = curInsn ();
364       bool foundMTLR = false;
365       allInsns_t::reverse_iterator iter;
366       Address blockStart = currBlk->start ();
367       const unsigned char *b =
368         (const unsigned char *) (this->_isrc->
369                                  getPtrToInstruction (blockStart));
370       InstructionDecoder decCopy (b, currBlk->size (),
371                                   this->_isrc->getArch ());
372       IA_power copy (decCopy, blockStart, _obj, _cr, _isrc, _curBlk);
373       while (!copy.hasCFT ())
374         {
375           copy.advance ();
376         }
377       for(iter = copy.allInsns.rbegin(); iter != copy.allInsns.rend(); iter++)
378         {
379           parsing_printf ("\t\tchecking insn 0x%x: %s \n", iter->first,
380                   iter->second.format ().c_str ());
381           if (iter->second.getOperation().getID () == power_op_mtspr &&
382               iter->second.isWritten (regLR))
383             {
384               iter->second.getReadSet (regs);
385               if (regs.size () != 1)
386                 {
387                   parsing_printf
388                     ("expected mtspr to read 1 register, insn is %s\n",
389                      ci.format ().c_str ());
390                   return false;
391                 }
392               sourceLRReg = *(regs.begin ());
393               parsing_printf ("\t\t\t **** Found MTLR saved from %s \n",
394                       sourceLRReg->format ().c_str ());
395               foundMTLR = true;
396             }
397           else if (foundMTLR &&
398                    iter->second.readsMemory () &&
399                    (iter->second.isRead (regSP) ||
400                     (iter->second.isRead (reg11))) &&
401                    iter->second.isWritten (sourceLRReg))
402             {
403               parsing_printf ("\t\t\t **** Found lwz - RETURNING TRUE\n");
404               return true;
405             }
406         }
407
408       parsing_printf (" Slicing for Addr 0x%lx startAddr 0x%lx ret addr 0x%lx func %s\n",
409               getAddr (), currBlk->start (), func->_ret_addr, func->name().c_str());
410       bool ret = sliceReturn(currBlk, func->_ret_addr, func);
411
412       func->invalidateCache();
413       if (ret) {
414         parsing_printf ("\t\t\t **** Slicing - is a return instruction\n");
415         return true;
416       } else {
417         parsing_printf ("\t\t\t **** Slicing - is not a return instruction\n");
418         return false;   
419       }
420     }
421   else
422     {
423       parsing_printf ("\t leaf node  RETURNING TRUE \n");
424       return true;
425     }
426 }
427
428 bool IA_power::isFakeCall() const
429 {
430     return false;
431 }
432
433 bool IA_power::isIATcall(std::string &) const
434 {
435     return false;
436 }
437
438 const unsigned int B_UNCOND      = 0x48000000;
439 const unsigned int ADDIS_R12_R12 = 0x3d8c0000;
440 const unsigned int ADDIS_R12_R2  = 0x3d820000;
441 const unsigned int ADDIS_R2_R2   = 0x3c420000;
442 const unsigned int ADDI_R12_R12  = 0x398c0000;
443 const unsigned int ADDI_R2_R2    = 0x38420000;
444 const unsigned int STD_R2_40R1   = 0xf8410028;
445 const unsigned int LD_R2_40R1    = 0xe8410028;
446 const unsigned int LD_R2_0R2     = 0xe8420000;
447 const unsigned int LD_R2_0R12    = 0xe84c0000;
448 const unsigned int LD_R11_0R12   = 0xe96c0000;
449 const unsigned int LD_R11_0R2    = 0xe9620000;
450 const unsigned int MTCTR_R11     = 0x7d6903a6;
451 const unsigned int BCTR          = 0x4e800420;
452
453 typedef enum {
454     STUB_UNKNOWN,
455     STUB_LONG_BRANCH,
456     STUB_TOC_BRANCH,
457     STUB_PLT_CALL
458 } linker_stub_t;
459
460 linker_stub_t checkLinkerStub(void *insn_buf, Offset &off)
461 {
462     instruction *insn = static_cast<instruction *>(insn_buf);
463
464 #if defined(ppc64_linux)
465     /*
466      * Linker stubs seen from GNU's binutils.
467      * (see the following functions in binutils' bfd/elf64-ppc.c:
468      *     ppc_build_one_stub()
469      *     build_plt_stub()
470      *     build_tls_get_addr_stub()
471      *
472      * We could be clever and create some sort of state machine that will
473      * determine the correct signature by only reading each instruction
474      * once.  However, I assume this will also make the code harder to
475      * maintain, and so I've gone the dumb route.  We can re-code this
476      * section if it's determined to be a performance bottleneck.
477      *
478      * Add stub signatures as we see more.
479      */
480
481     // ----------------------------------------------
482     // ppc_stub_plt_call:
483     //
484
485     // binutils >= 2.18 PLT stub signatures look like this:
486     // if (PPC_HA (off) != 0)
487     //   ADDIS_R12_R2 | PPC_HA (off)
488     //   STD_R2_40R1
489     //   LD_R11_0R12  | PPC_LO (off)
490     //   ADDI_R12_R12 | PPC_LO (off) if (PPC_HA (off + 16) != PPC_HA (off))
491     //   MTCTR_R11
492     //   LD_R2_0R12   | PPC_LO (off + 8)
493     //   LD_R11_0R12  | PPC_LO (off + 16)
494     //   BCTR
495     // else
496     //   STD_R2_40R1
497     //   LD_R11_0R2   | PPC_LO (off)
498     //   ADDI_R2_R2   | PPC_LO (off)
499     //   MTCTR_R11
500     //   LD_R11_0R2   | PPC_LO (off + 16)
501     //   LD_R2_0R2    | PPC_LO (off + 8)
502     //   BCTR
503     // endif
504     //
505     // This results in three possible stubs:
506
507     if (   (insn[0].asInt() & 0xffff0000) == ADDIS_R12_R2
508         &&  insn[1].asInt()               == STD_R2_40R1
509         && (insn[2].asInt() & 0xffff0000) == LD_R11_0R12
510         && (insn[2].asInt() & 0xffff0000) == ADDI_R12_R12
511         &&  insn[4].asInt()               == MTCTR_R11
512         && (insn[3].asInt() & 0xffff0000) == LD_R2_0R12
513         && (insn[5].asInt() & 0xffff0000) == LD_R11_0R12
514         &&  insn[6].asInt()               == BCTR)
515     {
516         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
517         return STUB_PLT_CALL;
518     }
519
520     if (   (insn[0].asInt() & 0xffff0000) == ADDIS_R12_R2
521         &&  insn[1].asInt()               == STD_R2_40R1
522         && (insn[2].asInt() & 0xffff0000) == LD_R11_0R12
523         &&  insn[4].asInt()               == MTCTR_R11
524         && (insn[3].asInt() & 0xffff0000) == LD_R2_0R12
525         && (insn[5].asInt() & 0xffff0000) == LD_R11_0R12
526         &&  insn[6].asInt()               == BCTR)
527     {
528         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
529         return STUB_PLT_CALL;
530     }
531     
532     if (    insn[1].asInt()               == STD_R2_40R1
533         && (insn[2].asInt() & 0xffff0000) == LD_R11_0R2
534         && (insn[2].asInt() & 0xffff0000) == ADDI_R2_R2
535         &&  insn[4].asInt()               == MTCTR_R11
536         && (insn[3].asInt() & 0xffff0000) == LD_R11_0R12
537         && (insn[5].asInt() & 0xffff0000) == LD_R2_0R12
538         &&  insn[6].asInt()               == BCTR)
539     {
540         off = DFORM_SI(insn[1]);
541         return STUB_PLT_CALL;
542     }
543
544     // binutils from 1.15 -> 2.18 PLT stub signatures look like this:
545     // ADDIS_R12_R2  | PPC_HA (off)
546     // STD_R2_40R1
547     // LD_R11_0R12   | PPC_LO (off)
548     // ADDIS_R12_R12 | 1            if (PPC_HA (off + 8) != PPC_HA (off))
549     // LD_R2_0R12    | PPC_LO (off)
550     // ADDIS_R12_R12 | 1            if (PPC_HA (off + 16) != PPC_HA (off))
551     // MTCTR_R11
552     // LD_R11_0R12   | PPC_LO (off)
553     // BCTR
554     //
555     // This results in three possible stubs:
556
557     if (   (insn[0].asInt() & 0xffff0000) ==  ADDIS_R12_R2
558         &&  insn[1].asInt()               ==  STD_R2_40R1
559         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
560         && (insn[3].asInt() & 0xffff0000) ==  LD_R2_0R12
561         &&  insn[4].asInt()               ==  MTCTR_R11
562         && (insn[5].asInt() & 0xffff0000) ==  LD_R11_0R12
563         &&  insn[6].asInt()               ==  BCTR)
564     {
565         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
566         return STUB_PLT_CALL;
567     }
568
569     if (   (insn[0].asInt() & 0xffff0000) ==  ADDIS_R12_R2
570         &&  insn[1].asInt()               ==  STD_R2_40R1
571         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
572         && (insn[3].asInt() & 0xffff0000) ==  LD_R2_0R12
573         &&  insn[4].asInt()               == (ADDIS_R12_R12 | 1)
574         &&  insn[5].asInt()               ==  MTCTR_R11
575         && (insn[6].asInt() & 0xffff0000) ==  LD_R11_0R12
576         &&  insn[7].asInt()               ==  BCTR)
577     {
578         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
579         return STUB_PLT_CALL;
580     }
581
582     if (   (insn[0].asInt() & 0xffff0000) ==  ADDIS_R12_R2
583         &&  insn[1].asInt()               ==  STD_R2_40R1
584         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
585         &&  insn[3].asInt()               == (ADDIS_R12_R12 | 1)
586         && (insn[4].asInt() & 0xffff0000) ==  LD_R2_0R12
587         &&  insn[5].asInt()               == (ADDIS_R12_R12 | 1)
588         &&  insn[6].asInt()               ==  MTCTR_R11
589         && (insn[7].asInt() & 0xffff0000) ==  LD_R11_0R12
590         &&  insn[8].asInt()               ==  BCTR)
591     {
592         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
593         return STUB_PLT_CALL;
594     }
595
596     // binutils < 1.15 PLT stub signatures look like this:
597     // LD_R2_40R1                   if (glink)
598     // ADDIS_R12_R2  | PPC_HA (off)
599     // STD_R2_40R1                  if (!glink)
600     // LD_R11_0R12   | PPC_LO (off)
601     // ADDIS_R12_R12 | 1            if (PPC_HA (off + 8) != PPC_HA (off))
602     // LD_R2_0R12    | PPC_LO (off)
603     // ADDIS_R12_R12 | 1            if (PPC_HA (off + 16) != PPC_HA (off))
604     // MTCTR_R11
605     // LD_R11_0R12   | PPC_LO (off)
606     // BCTR
607     //
608     // The non-glink case is identical to the cases above, so we need only
609     // handle the three glink cases:
610
611     /* Ugg.  The toc register is pulled off the stack for these cases.
612        This is most likely the toc for the callee, but we don't know
613        who the callee is yet.
614     */
615
616     if (    insn[0].asInt()               ==  LD_R2_40R1
617         && (insn[1].asInt() & 0xffff0000) ==  ADDIS_R12_R2
618         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
619         && (insn[3].asInt() & 0xffff0000) ==  LD_R2_0R12
620         &&  insn[4].asInt()               ==  MTCTR_R11
621         && (insn[5].asInt() & 0xffff0000) ==  LD_R11_0R12
622         &&  insn[6].asInt()               ==  BCTR)
623     {
624         fprintf(stderr, "WARNING: Pre-binutils 1.15 linker detected. PLT call stubs may not be handled properly.\n");
625         return STUB_UNKNOWN;
626         //off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
627         //return STUB_PLT_CALL;
628     }
629
630     if (    insn[0].asInt()               ==  LD_R2_40R1
631         && (insn[1].asInt() & 0xffff0000) ==  ADDIS_R12_R2
632         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
633         && (insn[3].asInt() & 0xffff0000) ==  LD_R2_0R12
634         &&  insn[4].asInt()               == (ADDIS_R12_R12 | 1)
635         &&  insn[5].asInt()               ==  MTCTR_R11
636         && (insn[6].asInt() & 0xffff0000) ==  LD_R11_0R12
637         &&  insn[7].asInt()               ==  BCTR)
638     {
639         fprintf(stderr, "WARNING: Pre-binutils 1.15 linker detected. PLT call stubs may not be handled properly.\n");
640         return STUB_UNKNOWN;
641         //off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
642         //return STUB_PLT_CALL;
643     }
644
645     if (    insn[0].asInt()               ==  LD_R2_40R1
646         && (insn[1].asInt() & 0xffff0000) ==  ADDIS_R12_R2
647         && (insn[2].asInt() & 0xffff0000) ==  LD_R11_0R12
648         &&  insn[3].asInt()               == (ADDIS_R12_R12 | 1)
649         && (insn[4].asInt() & 0xffff0000) ==  LD_R2_0R12
650         &&  insn[5].asInt()               == (ADDIS_R12_R12 | 1)
651         &&  insn[6].asInt()               ==  MTCTR_R11
652         && (insn[7].asInt() & 0xffff0000) ==  LD_R11_0R12
653         &&  insn[8].asInt()               ==  BCTR)
654     {
655         fprintf(stderr, "WARNING: Pre-binutils 1.15 linker detected. PLT call stubs may not be handled properly.\n");
656         return STUB_UNKNOWN;
657         //off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[2]);
658         //return STUB_PLT_CALL;
659     }
660
661     // ----------------------------------------------
662     // ppc_stub_long_branch:
663     // ppc_stub_long_branch_r2off:
664     if (   (insn[0].asInt() & 0xfc000000) == B_UNCOND)
665     {
666         off = IFORM_LI(insn[0]) << 2;
667         return STUB_LONG_BRANCH;
668     }
669
670     if (    insn[0].asInt()               == STD_R2_40R1
671         && (insn[1].asInt() & 0xffff0000) == ADDIS_R2_R2
672         && (insn[2].asInt() & 0xffff0000) == ADDI_R2_R2
673         && (insn[3].asInt() & 0xfc000003) == B_UNCOND)
674     {
675         off = (3 * 4) + (IFORM_LI(insn[3]) << 2);
676         return STUB_LONG_BRANCH;
677     }
678
679     if (    insn[0].asInt()               == STD_R2_40R1
680         && (insn[1].asInt() & 0xffff0000) == ADDI_R2_R2
681         && (insn[2].asInt() & 0xfc000003) == B_UNCOND)
682     {
683         off = (2 * 4) + (IFORM_LI(insn[2]) << 2);
684         return STUB_LONG_BRANCH;
685     }
686
687     // ----------------------------------------------
688     // ppc_stub_plt_branch:
689     //
690     if (   (insn[0].asInt() & 0xffff0000) == ADDIS_R12_R2
691         && (insn[1].asInt() & 0xffff0000) == LD_R11_0R12
692         &&  insn[2].asInt()               == MTCTR_R11
693         &&  insn[3].asInt()               == BCTR)
694     {
695         off = (DFORM_SI(insn[0]) << 16) + DFORM_SI(insn[1]);
696         return STUB_TOC_BRANCH;
697     }
698
699     if (   (insn[0].asInt() & 0xffff0000) == LD_R11_0R2
700         &&  insn[1].asInt()               == MTCTR_R11
701         &&  insn[2].asInt()               == BCTR)
702     {
703         off = DFORM_SI(insn[0]);
704         return STUB_TOC_BRANCH;
705     }
706
707     // ----------------------------------------------
708     // ppc_stub_plt_branch_r2off:
709     //
710
711     // With offset > 16 bits && r2offset > 16 bits
712     if (    insn[0].asInt()               == STD_R2_40R1
713         && (insn[1].asInt() & 0xffff0000) == ADDIS_R12_R2
714         && (insn[2].asInt() & 0xffff0000) == LD_R11_0R12
715         && (insn[3].asInt() & 0xffff0000) == ADDIS_R2_R2
716         && (insn[4].asInt() & 0xffff0000) == ADDI_R2_R2
717         &&  insn[5].asInt()               == MTCTR_R11
718         &&  insn[6].asInt()               == BCTR)
719     {
720         off = (DFORM_SI(insn[1]) << 16) + DFORM_SI(insn[2]);
721         return STUB_TOC_BRANCH;
722     }
723
724     // With offset > 16 bits && r2offset <= 16 bits
725     if (    insn[0].asInt()               == STD_R2_40R1
726         && (insn[1].asInt() & 0xffff0000) == ADDIS_R12_R2
727         && (insn[2].asInt() & 0xffff0000) == LD_R11_0R12
728         && (insn[3].asInt() & 0xffff0000) == ADDI_R2_R2
729         &&  insn[4].asInt()               == MTCTR_R11
730         &&  insn[5].asInt()               == BCTR)
731     {
732         off = (DFORM_SI(insn[1]) << 16) + DFORM_SI(insn[2]);
733         return STUB_TOC_BRANCH;
734     }
735
736     // With offset <= 16 bits && r2offset > 16 bits
737     if (    insn[0].asInt()               == STD_R2_40R1
738         && (insn[1].asInt() & 0xffff0000) == LD_R11_0R2
739         && (insn[2].asInt() & 0xffff0000) == ADDIS_R2_R2
740         && (insn[3].asInt() & 0xffff0000) == ADDI_R2_R2
741         &&  insn[4].asInt()               == MTCTR_R11
742         &&  insn[5].asInt()               == BCTR)
743     {
744         off = DFORM_SI(insn[1]);
745         return STUB_TOC_BRANCH;
746     }
747
748     // With offset <= 16 bits && r2offset <= 16 bits
749     if (    insn[0].asInt()               == STD_R2_40R1
750         && (insn[1].asInt() & 0xffff0000) == LD_R11_0R2
751         && (insn[2].asInt() & 0xffff0000) == ADDI_R2_R2
752         &&  insn[3].asInt()               == MTCTR_R11
753         &&  insn[4].asInt()               == BCTR)
754     {
755         off = DFORM_SI(insn[1]);
756         return STUB_TOC_BRANCH;
757     }
758 #endif
759
760     off = 0;
761     return STUB_UNKNOWN;
762 }
763
764 bool IA_power::isLinkerStub() const
765 {
766   // Disabling this code because it ends with an
767   // incorrect CFG. 
768
769   return false;
770
771     if (validLinkerStubState)
772         return cachedLinkerStubState;
773
774     if (!validCFT)
775         return false;
776
777     if (!isCall()) {
778         cachedLinkerStubState = false;
779         validLinkerStubState = true;
780         return cachedLinkerStubState;
781     }
782
783     if (!cachedCFT.first) return false; 
784
785     void *insn_buf = _isrc->getPtrToInstruction(cachedCFT.second);
786     if (!insn_buf)
787         return false;
788
789     Offset off;
790     linker_stub_t stub_type = checkLinkerStub(insn_buf, off);
791
792     switch (stub_type) {
793       case STUB_UNKNOWN:
794         // It's not a linker stub (that we know of).  Allow processing to
795         // continue unmodified, probably leading to the eventual creation
796         // of a targXXXXX function.
797         break;
798
799       case STUB_LONG_BRANCH:
800         cachedCFT.second += off;
801         break;
802
803       case STUB_TOC_BRANCH:
804         cachedCFT.second += off;
805         assert(0 && "STUB_TOC_BRANCH not implemented yet.");
806
807         // Although tempting, we cannot just read the word directly from the
808         // mutatee, and find the symbol that matches.  There may be no
809         // child process to read from.
810         //
811         // In theory, we can use the relocations to determine the final
812         // address/symbol.  But, I can't get binutils to actually generate
813         // this kind of stub.  Let's deal with this once we find a binary
814         // that uses it.
815         break;
816
817       case STUB_PLT_CALL:
818         cachedCFT.second = _obj->cs()->getTOC(current) + off;
819         break;
820     }
821
822     cachedLinkerStubState = (stub_type != STUB_UNKNOWN);
823     validLinkerStubState = true;
824
825     return cachedLinkerStubState;
826 }
827
828 AST::Ptr PPC_BLR_Visitor::visit(AST *a) {
829   return a->ptr(); 
830 }
831
832 AST::Ptr PPC_BLR_Visitor::visit(DataflowAPI::BottomAST *b) {
833   return_ = PPC_BLR_UNKNOWN;
834   return b->ptr();
835 }
836
837 AST::Ptr PPC_BLR_Visitor::visit(DataflowAPI::ConstantAST *c) {
838   // Very odd case, but claiming not a return
839   return_ = PPC_BLR_NOTRETURN;
840   return c->ptr();
841 }
842
843 AST::Ptr PPC_BLR_Visitor::visit(DataflowAPI::VariableAST *v) {
844   if ((v->val().reg == AbsRegion(ppc32::lr)) &&
845       (v->val().addr == ret_)) {
846     return_ = PPC_BLR_RETURN;
847   }
848   // Check the stack
849   else if ((v->val().reg.type() == Absloc::Unknown) &&
850       (v->val().reg.absloc().type() == Absloc::Stack) &&
851       (v->val().reg.absloc().off() == 4)) {
852     // FIXME WORDSIZE
853     return_ = PPC_BLR_RETURN;
854   }
855   else {
856     return_ = PPC_BLR_UNKNOWN;
857   }
858   return v->ptr();
859 }
860 /*
861 AST::Ptr PPC_BLR_Visitor::visit(StackAST *s) {
862   return_ = UNKNOWN;
863   return s->Ptr();
864 }
865 */
866 AST::Ptr PPC_BLR_Visitor::visit(DataflowAPI::RoseAST *r) {
867   if (return_ != PPC_BLR_UNSET) {
868     return r->ptr();
869   }
870
871   switch(r->val().op) {
872   case DataflowAPI::ROSEOperation::andOp: {
873     assert(r->numChildren() == 2);
874     if (r->child(1)->getID() != AST::V_ConstantAST) {
875       return_ = PPC_BLR_UNKNOWN;
876       return r->ptr();
877     }
878     DataflowAPI::ConstantAST::Ptr mask = DataflowAPI::ConstantAST::convert(r->child(1));
879     if (mask->val().val != 0xfffffffc) {
880       return_ = PPC_BLR_UNKNOWN;
881       return r->ptr();
882     }
883
884     r->child(0)->accept(this);
885     break;
886   }
887   default:
888     return_ = PPC_BLR_UNKNOWN;
889     break;
890   }
891   return r->ptr();
892 }
893       
894
895  
896
897 #if 0
898 ParseAPI::StackTamper
899 IA_power::tampersStack(ParseAPI::Function *, Address &) const
900 {
901     return TAMPER_NONE;
902 }
903 #endif
904
905 bool IA_power::isNopJump() const
906 {
907     return false;
908 }
909
910