vex_state->guest_TILEN = 0;
vex_state->guest_NRADDR = 0;
+ vex_state->guest_NRADDR_GPR2 = 0;
vex_state->guest_REDIR_SP = -1;
for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
Int maxoff )
{
+ /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
+ prudent to be conservative with it, even though thus far there
+ is no evidence to suggest that it actually needs to be kept up
+ to date wrt possible exceptions. */
Int lr_min = offsetof(VexGuestPPC64State, guest_LR);
Int lr_max = lr_min + 8 - 1;
Int r1_min = offsetof(VexGuestPPC64State, guest_GPR1);
Int r1_max = r1_min + 8 - 1;
+ Int r2_min = offsetof(VexGuestPPC64State, guest_GPR2);
+ Int r2_max = r2_min + 8 - 1;
Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
Int cia_max = cia_min + 8 - 1;
return True;
}
+ if (maxoff < r2_min || minoff > r2_max) {
+ /* no overlap with R2 */
+ } else {
+ return True;
+ }
+
if (maxoff < cia_min || minoff > cia_max) {
/* no overlap with CIA */
} else {
/* Describe any sections to be regarded by Memcheck as
'always-defined'. */
- .n_alwaysDefd = 10,
+ .n_alwaysDefd = 11,
.alwaysDefd
= { /* 0 */ ALWAYSDEFD64(guest_CIA),
/* 5 */ ALWAYSDEFD64(guest_FPROUND),
/* 6 */ ALWAYSDEFD64(guest_RESVN),
/* 7 */ ALWAYSDEFD64(guest_NRADDR),
- /* 8 */ ALWAYSDEFD64(guest_REDIR_SP),
- /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK)
+ /* 8 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
+ /* 9 */ ALWAYSDEFD64(guest_REDIR_SP),
+ /* 10 */ ALWAYSDEFD64(guest_REDIR_STACK)
}
};
7C210B78 (or 1,1,1) %R3 = client_request ( %R4 )
7C421378 (or 2,2,2) %R3 = guest_NRADDR
7C631B78 (or 3,3,3) branch-and-link-to-noredir %R11
+ 7C842378 (or 4,4,4) %R3 = guest_NRADDR_GPR2 (64-bit mode only)
Any other bytes following the 16-byte preamble are illegal and
constitute a failure in instruction decoding. This all assumes
#define OFFB_RESVN offsetofPPCGuestState(guest_RESVN)
#define OFFB_NRADDR offsetofPPCGuestState(guest_NRADDR)
+/* This only exists in the 64-bit guest state */
+#define OFFB64_NRADDR_GPR2 \
+ offsetof(VexGuestPPC64State,guest_NRADDR_GPR2)
+
/*------------------------------------------------------------*/
/*--- Extract instruction fields --- */
- Non-IEEE Mode
*/
if (mask & 0xFC) { // Exception Control, Non-IEE mode
- VexEmWarn ew = EmWarn_PPC32exns;
+ VexEmWarn ew = EmWarn_PPCexns;
/* If any of the src::exception_control bits are actually set,
side-exit to the next insn, reporting the warning,
dres.whatNext = Dis_StopHere;
goto decode_success;
}
+ else
+ if (mode64
+ && getUIntBigendianly(code+16) == 0x7C842378 /* or 4,4,4 */) {
+ /* %R3 = guest_NRADDR_GPR2 */
+ DIP("r3 = guest_NRADDR_GPR2\n");
+ delta += 20;
+ dres.len = 20;
+ vassert(ty == Ity_I64);
+ putIReg(3, IRExpr_Get( OFFB64_NRADDR_GPR2, ty ));
+ goto decode_success;
+ }
/* We don't know what it is. Set opc1/opc2 so decode_failure
can print the insn following the Special-insn preamble. */
theInstr = getUIntBigendianly(code+16);
/* Throw out any cases we don't need. In theory there might be a
day where we need to handle others, but not today. */
- if (nElems != 16)
+ if (nElems != 16 && nElems != 32)
vpanic("genGuestArrayOffset(ppc64 host)(1)");
switch (elemSz) {
/* Compute off into a reg, %off. Then return:
addi %tmp, %off, bias (if bias != 0)
- andi %tmp, 15
+ andi %tmp, nElems-1
sldi %tmp, shift
addi %tmp, %tmp, base
... Baseblockptr + %tmp ...
/*--- Vex's representation of the PPC64 CPU state ---*/
/*---------------------------------------------------------------*/
-#define VEX_GUEST_PPC64_REDIR_STACK_SIZE 16
+#define VEX_GUEST_PPC64_REDIR_STACK_SIZE (16/*entries*/ * 2/*words per entry*/)
typedef
struct {
Note, this is only set for wrap-style redirects, not for
replace-style ones. */
/* 1112 */ ULong guest_NRADDR;
+ /* 1120 */ ULong guest_NRADDR_GPR2;
/* A grows-upwards stack for hidden saves/restores of LR and R2
needed for function interception and wrapping on ppc64-linux.
A horrible hack. REDIR_SP points to the highest live entry,
and so starts at -1. */
- /* 1120 */ ULong guest_REDIR_SP;
- /* 1128 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZE];
+ /* 1128 */ ULong guest_REDIR_SP;
+ /* 1136 */ ULong guest_REDIR_STACK[VEX_GUEST_PPC64_REDIR_STACK_SIZE];
/* Padding to make it have an 8-aligned size */
/* UInt padding; */