* Send (or emulate) a push instruction. */
| 961 | * Send (or emulate) a push instruction. |
| 962 | */ |
| 963 | std::pair<bool, bool> sendPush(FILE *out, int32_t offset, bool before, |
| 964 | Register reg, Register rscratch) |
| 965 | { |
| 966 | // Special cases: |
| 967 | int scratch = -1, old_scratch = -1; |
| 968 | bool rax_stack = false; |
| 969 | switch (reg) |
| 970 | { |
| 971 | case REGISTER_RIP: |
| 972 | case REGISTER_RSP: |
| 973 | case REGISTER_FLAGS: |
| 974 | scratch = getRegIdx(rscratch); |
| 975 | assert(scratch != RSP_IDX && scratch != FLAGS_IDX && |
| 976 | scratch != RIP_IDX); |
| 977 | if (scratch < 0) |
| 978 | { |
| 979 | // No available scratch register. Evict %rax to into stack |
| 980 | // redzone at offset -16: |
| 981 | sendMovFromR64ToStack(out, RAX_IDX, -16); |
| 982 | scratch = RAX_IDX; |
| 983 | rax_stack = true; |
| 984 | } |
| 985 | if (reg == REGISTER_FLAGS && scratch != RAX_IDX) |
| 986 | { |
| 987 | // %rflags requires %rax as the scratch register: |
| 988 | sendMovFromR64ToR64(out, RAX_IDX, scratch); |
| 989 | old_scratch = scratch; |
| 990 | scratch = RAX_IDX; |
| 991 | } |
| 992 | break; |
| 993 | default: |
| 994 | break; |
| 995 | } |
| 996 | switch (reg) |
| 997 | { |
| 998 | case REGISTER_RIP: |
| 999 | if (before) |
| 1000 | sendLeaFromPCRelToR64(out, "{\"rel32\":\".Linstr\"}", |
| 1001 | scratch); |
| 1002 | else |
| 1003 | sendLeaFromPCRelToR64(out, "{\"rel32\":\".Lbreak\"}", |
| 1004 | scratch); |
| 1005 | sendMovFromR64ToStack(out, scratch, offset - RIP_SLOT); |
| 1006 | break; |
| 1007 | |
| 1008 | case REGISTER_RSP: |
| 1009 | // lea offset(%rsp),%rax |
| 1010 | // mov %rax,0x4000-8(%rax) |
| 1011 | sendLeaFromStackToR64(out, offset, scratch); |
| 1012 | sendMovFromR64ToStack(out, scratch, offset - RSP_SLOT); |
| 1013 | break; |
| 1014 | |
| 1015 | case REGISTER_FLAGS: |
| 1016 | // seto %al |
| 1017 | // lahf |
| 1018 | assert(scratch == RAX_IDX); |
| 1019 | fprintf(out, "%u,%u,%u,", 0x0f, 0x90, 0xc0); |
| 1020 | fprintf(out, "%u,", 0x9f); |
no test coverage detected