* This can create new BB at \p addr even if it then cannot split function * on this new BB. Is this desirable behavior? */
| 472 | * on this new BB. Is this desirable behavior? |
| 473 | */ |
| 474 | llvm::Function* Decoder::splitFunctionOn(common::Address addr) |
| 475 | { |
| 476 | if (auto* bb = getBasicBlockAtAddress(addr)) |
| 477 | { |
| 478 | LOG << "\t\t\t\t" << "S: splitFunctionOn @ " << addr << std::endl; |
| 479 | return bb->getPrevNode() |
| 480 | ? splitFunctionOn(addr, bb) |
| 481 | : bb->getParent(); |
| 482 | } |
| 483 | // There is an instruction at address, but not BB -> do not split |
| 484 | // existing blocks to create functions. |
| 485 | // |
| 486 | else if (auto ai = AsmInstruction(_module, addr)) |
| 487 | { |
| 488 | if (ai.isInvalid()) |
| 489 | { |
| 490 | LOG << "\t\t\t\t" << "S: invalid ASM @ " << addr << std::endl; |
| 491 | return nullptr; |
| 492 | } |
| 493 | else |
| 494 | { |
| 495 | LOG << "\t\t\t\t" << "S: ASM @ " << addr << std::endl; |
| 496 | return nullptr; |
| 497 | } |
| 498 | } |
| 499 | else if (getFunctionContainingAddress(addr)) |
| 500 | { |
| 501 | LOG << "\t\t\t\t" << "S: getFunctionContainingAddress() @ " << addr << std::endl; |
| 502 | auto* before = getBasicBlockBeforeAddress(addr); |
| 503 | assert(before); |
| 504 | auto* newBb = createBasicBlock(addr, before->getParent(), before); |
| 505 | return splitFunctionOn(addr, newBb); |
| 506 | } |
| 507 | else |
| 508 | { |
| 509 | LOG << "\t\t\t\t" << "S: createFunction() @ " << addr << std::endl; |
| 510 | return createFunction(addr); |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | llvm::Function* Decoder::splitFunctionOn( |
| 515 | common::Address addr, |
nothing calls this directly
no test coverage detected