mirror of
https://github.com/radareorg/r2hermes.git
synced 2026-11-09 12:31:29 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11284e7081 | ||
|
|
5ff2a61c2c | ||
|
|
29c1cadb98 | ||
|
|
a1d520c845 | ||
|
|
40be994134 |
No files matched your search
+1
-1
@@ -1,7 +1,7 @@
|
||||
project(
|
||||
'r2hermes',
|
||||
'c',
|
||||
version: '1.2.2',
|
||||
version: '1.2.4',
|
||||
license: 'MIT',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
||||
@@ -233,11 +233,10 @@ static Result emit_call_fixed(TokenString *out, const ParsedInstruction *insn, i
|
||||
static Result emit_call_with_argc(TokenString *out, const ParsedInstruction *insn) {
|
||||
RETURN_IF_ERROR (add (out, reg_l_safe (insn, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_assignment_token ()));
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_left_parenthesis_token ()));
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn, 1)));
|
||||
RETURN_IF_ERROR (add (out, create_left_parenthesis_token ()));
|
||||
char buf2[32];
|
||||
snprintf (buf2, sizeof (buf2), ", /*argc:%u*/", (unsigned)insn->arg3);
|
||||
snprintf (buf2, sizeof (buf2), "/*argc:%u*/", (unsigned)insn->arg3);
|
||||
RETURN_IF_ERROR (add (out, create_raw_token (buf2)));
|
||||
return add (out, create_right_parenthesis_token ());
|
||||
}
|
||||
@@ -685,12 +684,12 @@ Result _hbc_translate_instruction_to_tokens(const ParsedInstruction *insn_c, Tok
|
||||
RETURN_IF_ERROR (add (out, reg_l_safe (insn_c, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_assignment_token ()));
|
||||
StringBuffer sb;
|
||||
_hbc_string_buffer_init (&sb, 48);
|
||||
RETURN_IF_ERROR (_hbc_string_buffer_init (&sb, 48));
|
||||
_hbc_string_buffer_append (&sb, "try_get(");
|
||||
char nb[16];
|
||||
snprintf (nb, sizeof (nb), "r%u", (unsigned)insn->arg2);
|
||||
_hbc_string_buffer_append (&sb, nb);
|
||||
_hbc_format_property_from_string_id (insn->hbc_reader, (op == OP_TryGetById)? insn->arg4: insn->arg4, &sb);
|
||||
_hbc_format_property_from_string_id (insn->hbc_reader, insn->arg4, &sb);
|
||||
_hbc_string_buffer_append (&sb, ")");
|
||||
Token *t = create_raw_token (sb.data? sb.data: "try_get(r0)");
|
||||
_hbc_string_buffer_free (&sb);
|
||||
@@ -724,13 +723,13 @@ Result _hbc_translate_instruction_to_tokens(const ParsedInstruction *insn_c, Tok
|
||||
case OP_PutOwnByIndex:
|
||||
case OP_PutOwnByIndexL:
|
||||
{
|
||||
/* obj[idx] = value */
|
||||
/* obj[idx] = value; operands: obj reg, value reg, literal idx */
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn_c, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("[")));
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn_c, 1)));
|
||||
RETURN_IF_ERROR (add (out, num_token_u32 (insn->arg3)));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("]")));
|
||||
RETURN_IF_ERROR (add (out, create_assignment_token ()));
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn_c, 2)));
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn_c, 1)));
|
||||
break;
|
||||
}
|
||||
case OP_PutByVal:
|
||||
@@ -750,7 +749,7 @@ Result _hbc_translate_instruction_to_tokens(const ParsedInstruction *insn_c, Tok
|
||||
/* rObj["name"] = rVal */
|
||||
RETURN_IF_ERROR (add (out, reg_r_safe (insn_c, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("[")));
|
||||
u32 sid = (op == OP_PutById)? insn->arg4: insn->arg4;
|
||||
u32 sid = insn->arg4;
|
||||
RETURN_IF_ERROR (add (out, quoted_string (insn->hbc_reader, sid)));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("]")));
|
||||
RETURN_IF_ERROR (add (out, create_assignment_token ()));
|
||||
@@ -1098,10 +1097,10 @@ Result _hbc_translate_instruction_to_tokens(const ParsedInstruction *insn_c, Tok
|
||||
RETURN_IF_ERROR (add (out, reg_l_safe (insn_c, 0)));
|
||||
RETURN_IF_ERROR (add (out, create_assignment_token ()));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("fn_")));
|
||||
RETURN_IF_ERROR (add (out, num_token_u32 ((op == OP_CallDirect)? insn->arg4: insn->arg4)));
|
||||
RETURN_IF_ERROR (add (out, num_token_u32 (insn->arg3)));
|
||||
RETURN_IF_ERROR (add (out, create_left_parenthesis_token ()));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("/*argc:")));
|
||||
RETURN_IF_ERROR (add (out, num_token_u32 (insn->arg3)));
|
||||
RETURN_IF_ERROR (add (out, num_token_u32 (insn->arg2)));
|
||||
RETURN_IF_ERROR (add (out, create_raw_token ("*/")));
|
||||
RETURN_IF_ERROR (add (out, create_right_parenthesis_token ()));
|
||||
break;
|
||||
@@ -1340,7 +1339,7 @@ Result _hbc_translate_instruction_to_tokens(const ParsedInstruction *insn_c, Tok
|
||||
|
||||
/* Fallback: emit a comment-like raw token with mnemonic */
|
||||
StringBuffer sb;
|
||||
_hbc_string_buffer_init (&sb, 64);
|
||||
RETURN_IF_ERROR (_hbc_string_buffer_init (&sb, 64));
|
||||
_hbc_string_buffer_append (&sb, "/* ");
|
||||
_hbc_string_buffer_append (&sb, insn->inst->name);
|
||||
_hbc_string_buffer_append (&sb, " */");
|
||||
|
||||
+4
-1
@@ -455,10 +455,13 @@ Result hbc_dec(const HBCDecodeCtx *ctx, HBCInsnInfo *out) {
|
||||
switch (operand_type) {
|
||||
case OPERAND_TYPE_REG8:
|
||||
case OPERAND_TYPE_UINT8:
|
||||
case OPERAND_TYPE_ADDR8:
|
||||
operand_values[i] = ctx->bytes[pos];
|
||||
pos += 1;
|
||||
break;
|
||||
case OPERAND_TYPE_ADDR8:
|
||||
operand_values[i] = (u32)(i32)(i8)ctx->bytes[pos];
|
||||
pos += 1;
|
||||
break;
|
||||
case OPERAND_TYPE_UINT16:
|
||||
operand_values[i] = ctx->bytes[pos] | (ctx->bytes[pos + 1] << 8);
|
||||
pos += 2;
|
||||
|
||||
+15
-13
@@ -131,7 +131,7 @@ Result hbc_encoder_parse_instruction(HBCEncoder *encoder, const char *asm_line,
|
||||
}
|
||||
|
||||
/* Parse operands separated by commas */
|
||||
while (*line && operand_count < 6) {
|
||||
while (*line) {
|
||||
/* Skip whitespace */
|
||||
while (*line && isspace (*line)) {
|
||||
line++;
|
||||
@@ -177,13 +177,16 @@ Result hbc_encoder_parse_instruction(HBCEncoder *encoder, const char *asm_line,
|
||||
}
|
||||
*trim_end = '\0';
|
||||
|
||||
/* Parse operand based on expected type */
|
||||
if (operand_count < 6 && inst->operands[operand_count].operand_type != OPERAND_TYPE_NONE) {
|
||||
OperandType expected_type = inst->operands[operand_count].operand_type;
|
||||
char *endptr;
|
||||
bool parse_success = false;
|
||||
if (operand_count >= 6 || inst->operands[operand_count].operand_type == OPERAND_TYPE_NONE) {
|
||||
return ERROR_RESULT (RESULT_ERROR_PARSING_FAILED, "Incorrect number of operands");
|
||||
}
|
||||
|
||||
switch (expected_type) {
|
||||
/* Parse operand based on expected type */
|
||||
OperandType expected_type = inst->operands[operand_count].operand_type;
|
||||
char *endptr;
|
||||
bool parse_success = false;
|
||||
|
||||
switch (expected_type) {
|
||||
case OPERAND_TYPE_REG8:
|
||||
case OPERAND_TYPE_REG32:
|
||||
/* Register: rN or RN */
|
||||
@@ -268,13 +271,12 @@ Result hbc_encoder_parse_instruction(HBCEncoder *encoder, const char *asm_line,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!parse_success) {
|
||||
return ERROR_RESULT (RESULT_ERROR_PARSING_FAILED, "Invalid operand format");
|
||||
}
|
||||
|
||||
operand_count++;
|
||||
if (!parse_success) {
|
||||
return ERROR_RESULT (RESULT_ERROR_PARSING_FAILED, "Invalid operand format");
|
||||
}
|
||||
|
||||
operand_count++;
|
||||
|
||||
/* Move to next operand */
|
||||
line = operand_end;
|
||||
if (*line == ',') {
|
||||
@@ -338,7 +340,7 @@ Result hbc_encoder_encode_instruction(HBCEncoder *encoder, const HBCEncodedInstr
|
||||
/* Write operands based on their types */
|
||||
for (int i = 0; i < 6 && inst->operands[i].operand_type != OPERAND_TYPE_NONE; i++) {
|
||||
OperandType type = inst->operands[i].operand_type;
|
||||
u32 value = operand_values[i];
|
||||
u64 value = operand_values[i];
|
||||
|
||||
switch (type) {
|
||||
case OPERAND_TYPE_REG8:
|
||||
|
||||
@@ -984,12 +984,9 @@ Result _hbc_reader_read_string_tables(HBCReader *reader) {
|
||||
is_utf16 = reader->small_string_table[i].isUTF16;
|
||||
}
|
||||
|
||||
size_t decoded_length = (size_t)length;
|
||||
size_t available = (size_t)offset > string_storage_size? 0: string_storage_size - (size_t)offset;
|
||||
if ((size_t)offset > string_storage_size ||
|
||||
decoded_length == SIZE_MAX ||
|
||||
(is_utf16 && decoded_length > available / 2) ||
|
||||
(!is_utf16 && decoded_length > available)) {
|
||||
/* Overflow-safe bounds check via subtraction */
|
||||
const u32 bpc = is_utf16? 2: 1;
|
||||
if (offset > string_storage_size || length > (string_storage_size - offset) / bpc) {
|
||||
fprintf (stderr, "Warning: String %u offset/length out of bounds, treating as empty string\n", i);
|
||||
reader->strings[i] = strdup ("");
|
||||
if (!reader->strings[i]) {
|
||||
@@ -1000,9 +997,7 @@ Result _hbc_reader_read_string_tables(HBCReader *reader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate string buffer (+1 for null terminator) */
|
||||
size_t buffer_size = decoded_length + 1;
|
||||
char *str = (char *)malloc (buffer_size);
|
||||
char *str = (char *)malloc (length * bpc + 1);
|
||||
if (!str) {
|
||||
free (string_storage);
|
||||
reader->string_table_storage = NULL;
|
||||
@@ -1339,10 +1334,8 @@ Result _hbc_reader_read_bigints(HBCReader *reader) {
|
||||
u32 offset = bigint_table[i].offset;
|
||||
u32 length = bigint_table[i].length;
|
||||
|
||||
/* Check bounds */
|
||||
size_t bigint_available = (size_t)offset > reader->header.bigIntStorageSize? 0:
|
||||
(size_t)reader->header.bigIntStorageSize - (size_t)offset;
|
||||
if ((size_t)offset > reader->header.bigIntStorageSize || (size_t)length > bigint_available) {
|
||||
/* Overflow-safe bounds check via subtraction */
|
||||
if (offset > reader->header.bigIntStorageSize || length > reader->header.bigIntStorageSize - offset) {
|
||||
fprintf (stderr, "Warning: BigInt %u has invalid offset/length (%u+%u exceeds %u)\n", i, offset, length, reader->header.bigIntStorageSize);
|
||||
/* Use zero for this value */
|
||||
reader->bigint_values[i] = 0;
|
||||
|
||||
+4
-7
@@ -363,11 +363,9 @@ Result _hbc_generate_r2_script(const char *input_file, const char *output_file)
|
||||
u32 length = string_infos[i].length;
|
||||
bool isUTF16 = string_infos[i].isUTF16;
|
||||
|
||||
/* Skip strings with obviously invalid offsets/lengths */
|
||||
size_t available = (size_t)offset > string_storage_size? 0: string_storage_size - (size_t)offset;
|
||||
if ((size_t)offset > string_storage_size ||
|
||||
(isUTF16 && (size_t)length > available / 2) ||
|
||||
(!isUTF16 && (size_t)length > available)) {
|
||||
/* Overflow-safe bounds check via subtraction */
|
||||
const u32 bpc = isUTF16? 2: 1;
|
||||
if (offset > string_storage_size || length > (string_storage_size - offset) / bpc) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -433,9 +431,8 @@ Result _hbc_generate_r2_script(const char *input_file, const char *output_file)
|
||||
snprintf (unique_name, sizeof (unique_name), "%s_%u", sanitized_name[0]? sanitized_name: "str", i);
|
||||
|
||||
/* Write the string flag - offset is relative to string storage base */
|
||||
size_t size = isUTF16? (size_t)length * 2: (size_t)length;
|
||||
uint32_t addr = (unsigned long) (reader.file_buffer.position - string_storage_size + offset);
|
||||
fprintf (out, "'f str.%s %zu 0x%08x\n", unique_name, size, addr);
|
||||
fprintf (out, "'f str.%s %u 0x%08x\n", unique_name, length * bpc, addr);
|
||||
#if 0
|
||||
/* Add flag for string length */
|
||||
if (isUTF16) {
|
||||
|
||||
+7
-10
@@ -285,21 +285,18 @@ static RList *strings(RBinFile *bf) {
|
||||
if (hbc_get_string_meta (hbc, i, &meta).code != RESULT_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (meta.length == 0) {
|
||||
const size_t str_len = strlen (str);
|
||||
if (str_len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RBinString *ptr = R_NEW0 (RBinString);
|
||||
if (meta.length >= R_BIN_SIZEOF_STRINGS) {
|
||||
ptr->string = r_str_ndup (str, R_BIN_SIZEOF_STRINGS - 4);
|
||||
if (ptr->string) {
|
||||
char *tmp = r_str_newf ("%s...", ptr->string);
|
||||
free (ptr->string);
|
||||
ptr->string = tmp;
|
||||
}
|
||||
if (str_len >= R_BIN_SIZEOF_STRINGS) {
|
||||
char *trunc = r_str_ndup (str, R_BIN_SIZEOF_STRINGS - 4);
|
||||
ptr->string = r_str_newf ("%s...", trunc? trunc: "");
|
||||
free (trunc);
|
||||
} else {
|
||||
ptr->string = r_str_ndup (str, meta.length);
|
||||
ptr->string = r_str_ndup (str, str_len);
|
||||
}
|
||||
if (!ptr->string) {
|
||||
free (ptr);
|
||||
|
||||
+288
-1
@@ -284,7 +284,7 @@ EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc assembler
|
||||
NAME=hbc pa ret
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
@@ -294,3 +294,290 @@ EXPECT=<<EOF
|
||||
5c00
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa get_global_object
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa get_global_object r0
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
3000
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa mov two regs
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa mov r2, r1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
080201
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa construct three operands
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa construct r0, r0, 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
50000001
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa select_object three regs
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa select_object r0, r1, r0
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
6b000100
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa store_to_environment
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa store_to_environment r1, 1, r0
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
2a010100
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects extra operand
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
"pa ret r0, r1"
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects multiple extra operands
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
"pa ret r0, r1, r2"
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects extra operand on zero-arg instr
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
"pa get_global_object r0, r1"
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects missing operand
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa ret
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects truncated mov
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa mov r2
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa rejects unknown mnemonic
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pa bogus_op r0
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad ret
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 5c00
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
ret r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad get_global_object
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 3000
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
get_global_object r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad mov
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 080201
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
mov r2, r1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad construct
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 50000001
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
construct r0, r0, 1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad select_object
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 6b000100
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
select_object r0, r1, r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pad store_to_environment
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad 2a010100
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
store_to_environment r1, 1, r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+pad roundtrip ret
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad `pa ret r0`
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
ret r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+pad roundtrip mov
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad `pa mov r2, r1`
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
mov r2, r1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+pad roundtrip construct
|
||||
FILE=--
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
pad `pa construct r0, r0, 1`
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
construct r0, r0, 1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pi ret after wx
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx 5c00
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
ret r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pi mov after wx
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx 080201
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
mov r2, r1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pi construct after wx
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx 50000001
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
construct r0, r0, 1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+wx+pi roundtrip ret
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx `pa ret r0`
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
ret r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+wx+pi roundtrip mov
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx `pa mov r2, r1`
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
mov r2, r1
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=hbc pa+wx+pi roundtrip store_to_environment
|
||||
FILE=malloc://16
|
||||
CMDS=<<EOF
|
||||
-a hbc
|
||||
wx `pa store_to_environment r1, 1, r0`
|
||||
pi 1
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
store_to_environment r1, 1, r0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
Reference in new issue
Block a user