| 243 | } |
| 244 | |
| 245 | static bool LiftBranches(Architecture* arch, LowLevelILFunction &il, const uint8_t* data, uint64_t addr, bool le) |
| 246 | { |
| 247 | // MYLOG("%s() addr:0x%08llx\n", __func__, addr); |
| 248 | uint32_t insn = *(const uint32_t *) data; |
| 249 | bool lk; |
| 250 | size_t addressSize_l = arch->GetAddressSize(); |
| 251 | |
| 252 | if (!le) |
| 253 | { |
| 254 | insn = bswap32(insn); |
| 255 | } |
| 256 | |
| 257 | lk = insn & 1; |
| 258 | |
| 259 | switch (insn >> 26) |
| 260 | { |
| 261 | case PPC_INS_BCA: /* b (b, ba, bl, bla) */ |
| 262 | { |
| 263 | uint64_t target = insn & 0x03fffffc; |
| 264 | |
| 265 | /* sign extend target */ |
| 266 | target = sign_extend(addressSize_l, target, 25); |
| 267 | |
| 268 | /* account for absolute addressing */ |
| 269 | if (!(insn & 2)) |
| 270 | { |
| 271 | target += addr; |
| 272 | ADDRMASK(addressSize_l, target); |
| 273 | } |
| 274 | |
| 275 | BNLowLevelILLabel* label = il.GetLabelForAddress(arch, target); |
| 276 | |
| 277 | if (label && !(lk && (target != (addr+4)))) |
| 278 | { |
| 279 | /* branch to an instruction within the same function -- take |
| 280 | * 'lk' bit behavior into account, but don't emit as a call |
| 281 | */ |
| 282 | if (lk) |
| 283 | { |
| 284 | il.AddInstruction(il.SetRegister(addressSize_l, PPC_REG_LR, il.ConstPointer(addressSize_l, addr + 4))); |
| 285 | } |
| 286 | |
| 287 | il.AddInstruction(il.Goto(*label)); |
| 288 | } |
| 289 | else |
| 290 | { |
| 291 | ExprId dest = il.ConstPointer(4, target); |
| 292 | |
| 293 | if (lk) |
| 294 | il.AddInstruction(il.Call(dest)); |
| 295 | else |
| 296 | il.AddInstruction(il.Jump(dest)); |
| 297 | } |
| 298 | |
| 299 | break; |
| 300 | } |
| 301 | case PPC_INS_BA: /* bc */ |
| 302 | { |
no test coverage detected