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