Skip to content

Commit

Permalink
i#5383: arm v8.3 pac instructions for M1
Browse files Browse the repository at this point in the history
Updates to aarch64 to execute code with PAC features; mainly just strips
off any PAC bits before jumping anywhere.

Issue: DynamoRIO#5383
  • Loading branch information
Anthony Romano committed Jun 1, 2022
1 parent 8ba9b14 commit ac27bb1
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 14 deletions.
25 changes: 18 additions & 7 deletions core/arch/aarchxx/mangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,8 @@ mangle_indirect_call(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
instr_t *next_instr, bool mangle_calls, uint flags)
{
#ifdef AARCH64
ASSERT(instr_get_opcode(instr) == OP_blr);
int opc = instr_get_opcode(instr);
ASSERT(opc == OP_blr || opc == OP_blraaz);
PRE(ilist, instr,
instr_create_save_to_tls(dcontext, IBL_TARGET_REG, IBL_TARGET_SLOT));
ASSERT(opnd_is_reg(instr_get_target(instr)));
Expand All @@ -1460,6 +1461,9 @@ mangle_indirect_call(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
XINST_CREATE_move(dcontext, opnd_create_reg(IBL_TARGET_REG),
instr_get_target(instr)));
}
if (opc == OP_blraaz) {
PRE(ilist, instr, INSTR_CREATE_xpaci(dcontext, opnd_create_reg(IBL_TARGET_REG)));
}
insert_mov_immed_ptrsz(dcontext, get_call_return_address(dcontext, ilist, instr),
opnd_create_reg(DR_REG_X30), ilist, next_instr, NULL, NULL);
instrlist_remove(ilist, instr); /* remove OP_blr */
Expand Down Expand Up @@ -1521,26 +1525,33 @@ instr_t *
mangle_indirect_jump(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
instr_t *next_instr, uint flags)
{
int opc = instr_get_opcode(instr);
#ifdef AARCH64
ASSERT(instr_get_opcode(instr) == OP_br || instr_get_opcode(instr) == OP_ret);
ASSERT(opc == OP_br || opc == OP_ret || opc == OP_reta || opc == OP_braa);
PRE(ilist, instr,
instr_create_save_to_tls(dcontext, IBL_TARGET_REG, IBL_TARGET_SLOT));
ASSERT(opnd_is_reg(instr_get_target(instr)));
if (opnd_same(instr_get_target(instr), opnd_create_reg(dr_reg_stolen))) {
opnd_t target =
opc == OP_reta ? opnd_create_reg(DR_REG_X30) : instr_get_target(instr);
ASSERT(opnd_is_reg(target));

if (opnd_same(target, opnd_create_reg(dr_reg_stolen))) {
/* if the target reg is dr_reg_stolen, the app value is in TLS */
PRE(ilist, instr,
instr_create_restore_from_tls(dcontext, IBL_TARGET_REG, TLS_REG_STOLEN_SLOT));
} else {
PRE(ilist, instr,
XINST_CREATE_move(dcontext, opnd_create_reg(IBL_TARGET_REG),
instr_get_target(instr)));
XINST_CREATE_move(dcontext, opnd_create_reg(IBL_TARGET_REG), target));
}

if (opc == OP_reta || opc == OP_braa) {
PRE(ilist, instr, INSTR_CREATE_xpaci(dcontext, opnd_create_reg(IBL_TARGET_REG)));
}

instrlist_remove(ilist, instr); /* remove OP_br or OP_ret */
instr_destroy(dcontext, instr);
return next_instr;
#else
bool remove_instr = false;
int opc = instr_get_opcode(instr);
dr_isa_mode_t isa_mode = instr_get_isa_mode(instr);
bool in_it = app_instr_is_in_it_block(dcontext, instr);
instr_t *bound_start = INSTR_CREATE_label(dcontext);
Expand Down
26 changes: 26 additions & 0 deletions core/ir/aarch64/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,30 @@ encode_opnd_op2(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
return encode_opnd_int(5, 3, false, 0, 0, opnd, enc_out);
}

/* x5p8 : X register, add 8 */

static inline bool
decode_opnd_x5p8(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
*opnd = opnd_create_reg(decode_reg(8 + ((enc >> 5) & 7), true, false));
return true;
}

static inline bool
encode_opnd_x5p8(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
{
reg_id_t reg;
uint n;
if (!opnd_is_reg(opnd))
return false;
reg = opnd_get_reg(opnd);
n = reg - DR_REG_X0;
if (n < 8 || n > (8 + 7))
return false;
*enc_out = (n - 8) << 5;
return true;
}

/* w5: W register or WZR at bit position 5 */

static inline bool
Expand Down Expand Up @@ -5085,11 +5109,13 @@ get_el_hs_sz(OUT uint *elsz_out, opnd_t opnd)
#include "opnd_decode_funcs.h"
#include "opnd_encode_funcs.h"
#include "decode_gen_sve.h"
#include "decode_gen_v83.h"
#include "decode_gen_v82.h"
#include "decode_v81.h"
#include "decode_gen_v81.h" /* Redirects decoding to decode_v81.h */
#include "decode_gen_v80.h"
#include "encode_gen_sve.h"
#include "encode_gen_v83.h"
#include "encode_gen_v82.h"
#include "encode_v81.h"
#include "encode_gen_v81.h" /* Redirects encoding to encode_v81.h */
Expand Down
2 changes: 1 addition & 1 deletion core/ir/aarch64/codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ def main():
# partially supported. The null terminator element at the end is required
# by some generator functions to correctly generate links between each
# version's decode/encode logic.
isa_versions = ['v80', 'v81', 'v82', 'sve', '']
isa_versions = ['v80', 'v81', 'v82', 'v83', 'sve', '']

# Read the instruction operand definitions. Used by the codec when
# generating code to decode and encode instructions.
Expand Down
53 changes: 53 additions & 0 deletions core/ir/aarch64/codec_v83.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# **********************************************************
# Copyright (c) 2016-2022 ARM Limited. All rights reserved.
# **********************************************************

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of ARM Limited nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL ARM LIMITED OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.

# See header comments in codec_v80.txt and opnd_defs.txt to understand how
# instructions are defined for the purposes of decode and encode code
# generation.

# Instruction definitions:

# retaa, retab
11010110010111110000101111111111 n 579 reta :
11010110010111110000111111111111 n 579 reta :
11010101000000110010001101111111 n 580 pacibsp :
11010101000000110010001111111111 n 581 autibsp :
1101011000111111000010xxxxx11111 n 582 blraaz impx30 : x5
# blraa
110101110011111100001001xxxxxxxx n 582 blraaz impx30 : x5p8 x0
1101011100011111000010xxxxxxxxxx n 583 braa : x5 x0
110110101100000100100011111xxxxx n 584 paciza : x0
110110101100000101000011111xxxxx n 585 xpaci : x0
110110101100000101000111111xxxxx n 586 xpacd : x0
1101101011000001000010xxxxxxxxxx n 587 pacda : x0 x5
1101101011000001000000xxxxxxxxxx n 588 pacia : x0 x5
1101101011000001000001xxxxxxxxxx n 589 pacib : x0 x5
110110101100000100011101xxxxxxxx n 590 autdb : x5p8 x0

16 changes: 10 additions & 6 deletions core/ir/aarch64/instr.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ instr_branch_type(instr_t *cti_instr)
case OP_tbnz:
case OP_tbz: return LINK_DIRECT | LINK_JMP;
case OP_bl: return LINK_DIRECT | LINK_CALL;
case OP_blraaz:
case OP_blr: return LINK_INDIRECT | LINK_CALL;
case OP_br: return LINK_INDIRECT | LINK_JMP;
case OP_ret: return LINK_INDIRECT | LINK_RETURN;
case OP_br:
case OP_braa: return LINK_INDIRECT | LINK_JMP;
case OP_ret:
case OP_reta: return LINK_INDIRECT | LINK_RETURN;
}
CLIENT_ASSERT(false, "instr_branch_type: unknown opcode");
return LINK_INDIRECT;
Expand All @@ -105,7 +108,7 @@ bool
instr_is_call_arch(instr_t *instr)
{
int opc = instr->opcode; /* caller ensures opcode is valid */
return (opc == OP_bl || opc == OP_blr);
return (opc == OP_bl || opc == OP_blr || opc == OP_blraaz);
}

bool
Expand All @@ -126,14 +129,14 @@ bool
instr_is_call_indirect(instr_t *instr)
{
int opc = instr_get_opcode(instr);
return (opc == OP_blr);
return (opc == OP_blr || opc == OP_blraaz);
}

bool
instr_is_return(instr_t *instr)
{
int opc = instr_get_opcode(instr);
return (opc == OP_ret);
return (opc == OP_ret || opc == OP_reta);
}

bool
Expand All @@ -149,7 +152,8 @@ bool
instr_is_mbr_arch(instr_t *instr)
{
int opc = instr->opcode; /* caller ensures opcode is valid */
return (opc == OP_blr || opc == OP_br || opc == OP_ret);
return (opc == OP_blr || opc == OP_blraaz || opc == OP_br || opc == OP_braa ||
opc == OP_ret || opc == OP_reta);
}

bool
Expand Down
7 changes: 7 additions & 0 deletions core/ir/aarch64/instr_create_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -3376,4 +3376,11 @@
*/
#define INSTR_CREATE_fmov_scalar_imm(dc, Rd, f) instr_create_1dst_1src(dc, OP_fmov, Rd, f)

/**
* Creates a XPACI instruction.
* \param dc The void * dcontext used to allocate memory for the instr_t.
* \param Rd Register with PAC bits to remove.
*/
#define INSTR_CREATE_xpaci(dc, Rd) instr_create_0dst_1src((dc), OP_xpaci, (Rd))

#endif /* DR_IR_MACROS_AARCH64_H */
1 change: 1 addition & 0 deletions core/ir/aarch64/opnd_defs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
---------------------------xxxxx q0p3 # Q register, add 3
---------------------------xxxxx prfop # prefetch operation
------------------------xxx----- op2 # 3 bit immediate from 5-7
------------------------xxx----- x5p8 # X register, add 8
----------------------xxxxx----- w5 # W register (or WZR)
----------------------xxxxx----- x5 # X register (or XZR)
----------------------xxxxx----- x5sp # X register or XSP
Expand Down

0 comments on commit ac27bb1

Please sign in to comment.