* Patch the instruction at the given offset. */
| 880 | * Patch the instruction at the given offset. |
| 881 | */ |
| 882 | bool patch(Binary &B, Instr *I, const Trampoline *T) |
| 883 | { |
| 884 | switch (I->STATE[0]) |
| 885 | { |
| 886 | case STATE_INSTRUCTION: |
| 887 | break; |
| 888 | default: |
| 889 | error("failed to patch instruction 0x%lx (%zu) with invalid " |
| 890 | "state (0x%.2X) (maybe \"patch\" messages are not sent " |
| 891 | "in reverse order?)", I->addr, I->size, I->STATE[0]); |
| 892 | } |
| 893 | |
| 894 | // Try all patching tactics in order T0/B1/B2/T1/T2/T3: |
| 895 | Patch *P = nullptr; |
| 896 | if (P == nullptr) |
| 897 | P = tactic_T0(B, I, T); |
| 898 | if (P == nullptr) |
| 899 | P = tactic_B1(B, I, T); |
| 900 | if (P == nullptr) |
| 901 | P = tactic_B2(B, I, T); |
| 902 | if (P == nullptr) |
| 903 | P = tactic_T1(B, I, T); |
| 904 | if (P == nullptr) |
| 905 | P = tactic_T2(B, I, T); |
| 906 | if (P == nullptr) |
| 907 | P = tactic_T3(B, I, T); |
| 908 | if (P == nullptr) |
| 909 | P = tactic_B0(B, I, T); |
| 910 | |
| 911 | if (P == nullptr) |
| 912 | { |
| 913 | debug("failed to patch instruction at address 0x%lx (%zu)", I->addr, |
| 914 | I->size); |
| 915 | log(COLOR_RED, 'X'); |
| 916 | return false; // Failed :( |
| 917 | } |
| 918 | |
| 919 | bool uses_B0 = (P->tactic == TACTIC_B0); |
| 920 | const char *name = getTacticName(P->tactic); |
| 921 | commit(B, P); |
| 922 | if (option_debug) |
| 923 | { |
| 924 | intptr_t entry = getTrampolineEntry(B.Es, I); |
| 925 | intptr_t lb = entry - getTrampolinePrologueSize(&B, I); |
| 926 | intptr_t ub = entry + getTrampolineSize(&B, T, I); |
| 927 | debug("patched instruction 0x%lx [size=%zu, tactic=%s, " |
| 928 | "entry=" ADDRESS_FORMAT ", " |
| 929 | "trampoline=" ADDRESS_FORMAT ".." ADDRESS_FORMAT ", " |
| 930 | "offset=%zd]", |
| 931 | I->addr, I->size, name, ADDRESS(entry), ADDRESS(lb), ADDRESS(ub), |
| 932 | (ssize_t)(entry - lb)); |
| 933 | } |
| 934 | log((uses_B0? COLOR_YELLOW: COLOR_GREEN), |
| 935 | (uses_B0? 'T': '.')); |
| 936 | return true; // Success! |
| 937 | } |
| 938 |
no test coverage detected