mirror of
https://github.com/radareorg/r2hermes.git
synced 2026-11-09 17:47:09 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11284e7081 | ||
|
|
5ff2a61c2c | ||
|
|
29c1cadb98 | ||
|
|
a1d520c845 | ||
|
|
40be994134 |
No files matched your search
-339
@@ -1,339 +0,0 @@
|
||||
add=binary add of two registers (numeric or string concatenation)
|
||||
add_empty_string=convert a value to string by concatenating with the empty string
|
||||
add_n=numeric add (operands known to be numeric)
|
||||
add_own_private_by_sym=add a private own property using a symbol key
|
||||
add_s=string add (operands known to be strings)
|
||||
add32=32-bit integer add
|
||||
async_break_check=check if execution should break asynchronously
|
||||
bit_and=bitwise AND of two registers
|
||||
bit_not=bitwise NOT of a register
|
||||
bit_or=bitwise OR of two registers
|
||||
bit_xor=bitwise XOR of two registers
|
||||
call=call a function with a given number of arguments
|
||||
call_builtin=call a builtin function by id
|
||||
call_builtin_long=call a builtin function by id (long form)
|
||||
call_direct=call a function whose code address is statically known
|
||||
call_direct_long_index=call a function with a long function index
|
||||
call_long=call a function with a long argument count
|
||||
call_require=call the require builtin to import a module
|
||||
call_with_new_target=call a function passing an explicit new.target
|
||||
call_with_new_target_long=call with new.target (long form)
|
||||
call1=call a function with 1 argument
|
||||
call2=call a function with 2 arguments
|
||||
call3=call a function with 3 arguments
|
||||
call4=call a function with 4 arguments
|
||||
catch=mark catch handler entry, receives the thrown exception
|
||||
coerce_this_n_s=coerce 'this' to an object in non-strict mode
|
||||
coerce_this_ns=coerce 'this' to an object in non-strict mode
|
||||
complete_generator=mark generator as completed
|
||||
construct=invoke a constructor with a given number of arguments
|
||||
construct_long=invoke a constructor (long form)
|
||||
create_async_closure=create an async closure
|
||||
create_async_closure_long_index=create an async closure (long function index)
|
||||
create_base_class=create a class with no superclass
|
||||
create_base_class_long_index=create a base class (long function index)
|
||||
create_closure=create a closure from a function
|
||||
create_closure_long_index=create a closure (long function index)
|
||||
create_derived_class=create a class that extends a superclass
|
||||
create_derived_class_long_index=create a derived class (long function index)
|
||||
create_environment=create a new lexical environment for the current function
|
||||
create_function_environment=create the function's lexical environment
|
||||
create_generator=create a generator function instance
|
||||
create_generator_closure=create a generator closure
|
||||
create_generator_closure_long_index=create a generator closure (long function index)
|
||||
create_generator_long_index=create a generator (long function index)
|
||||
create_inner_environment=create an inner (nested) lexical environment
|
||||
create_private_name=create a unique private name symbol
|
||||
create_reg_exp=create a RegExp object from a pattern and flags
|
||||
create_this=create the 'this' object for a constructor call
|
||||
create_this_for_new=allocate 'this' for a 'new' expression
|
||||
create_this_for_super=allocate 'this' for a super constructor call
|
||||
create_top_level_environment=create the top-level lexical environment
|
||||
debugger=trigger the JavaScript debugger statement
|
||||
debugger_check=check if a debugger break is requested
|
||||
debugger_check_break=check and yield to debugger if breakpoint is set
|
||||
dec=decrement a register by 1
|
||||
declare_global_var=declare a variable on the global object
|
||||
define_own_by_id=define an own property by string id
|
||||
define_own_by_id_long=define an own property by string id (long form)
|
||||
define_own_by_index=define an own indexed property
|
||||
define_own_by_index_l=define an own indexed property (long form)
|
||||
define_own_by_val=define an own property by computed value
|
||||
define_own_getter_setter_by_val=define accessor (getter/setter) property
|
||||
define_own_in_dense_array=define an element in a dense array literal
|
||||
define_own_in_dense_array_l=define an element in a dense array literal (long)
|
||||
del_by_id=delete a property by string id
|
||||
del_by_id_long=delete a property by string id (long form)
|
||||
del_by_id_loose=delete a property by id (loose mode)
|
||||
del_by_id_loose_long=delete a property by id (loose, long form)
|
||||
del_by_id_strict=delete a property by id (strict mode)
|
||||
del_by_id_strict_long=delete a property by id (strict, long form)
|
||||
del_by_val=delete a property by computed value
|
||||
del_by_val_loose=delete a property by computed value (loose mode)
|
||||
del_by_val_strict=delete a property by computed value (strict mode)
|
||||
direct_eval=invoke direct eval()
|
||||
div=divide two registers
|
||||
div_n=numeric divide (operands known to be numeric)
|
||||
divi32=signed 32-bit integer divide
|
||||
divu32=unsigned 32-bit integer divide
|
||||
eq=loose equality comparison (==)
|
||||
fast_array_append=append all elements of a fast array to another
|
||||
fast_array_length=read the length of a fast array
|
||||
fast_array_load=load element from a fast array by index
|
||||
fast_array_push=push a value into a fast array
|
||||
fast_array_store=store value into a fast array at index
|
||||
get_arguments_length=read 'arguments.length' lazily
|
||||
get_arguments_prop_by_val=read an element from 'arguments' lazily
|
||||
get_arguments_prop_by_val_loose=read 'arguments' element (loose mode)
|
||||
get_arguments_prop_by_val_strict=read 'arguments' element (strict mode)
|
||||
get_builtin_closure=get a closure for a builtin function
|
||||
get_by_id=load a property by string id
|
||||
get_by_id_long=load a property by string id (long form)
|
||||
get_by_id_short=load a property by string id (short cache)
|
||||
get_by_id_with_receiver_long=load a property with explicit receiver (long form)
|
||||
get_by_index=load an element by integer index
|
||||
get_by_val=load a property by computed value
|
||||
get_by_val_with_receiver=load a property by computed value with receiver
|
||||
get_closure_environment=get the environment of an enclosing closure
|
||||
get_environment=get the lexical environment at a given depth
|
||||
get_global_object=get the global object
|
||||
get_new_target=read the new.target meta-property
|
||||
get_next_p_name=advance a for-in property iterator
|
||||
get_next_pname=advance a for-in property iterator
|
||||
get_own_by_slot_idx=load own property by inline cache slot index
|
||||
get_own_by_slot_idx_long=load own property by slot index (long form)
|
||||
get_own_private_by_sym=load an own private property by symbol
|
||||
get_p_name_list=initialize a for-in property name list
|
||||
get_parent_environment=get the parent of a lexical environment
|
||||
get_pname_list=initialize a for-in property name list
|
||||
greater=greater than comparison (>)
|
||||
greater_eq=greater than or equal comparison (>=)
|
||||
inc=increment a register by 1
|
||||
instance_of=instanceof operator
|
||||
is_in='in' operator (property exists in object)
|
||||
iterator_begin=start iteration over an iterable
|
||||
iterator_close=close (cleanup) an iterator
|
||||
iterator_next=advance an iterator and read the next value
|
||||
j_equal=branch if loose equal
|
||||
j_equal_long=branch if loose equal (long offset)
|
||||
j_greater=branch if greater than
|
||||
j_greater_equal=branch if greater than or equal
|
||||
j_greater_equal_long=branch if greater than or equal (long offset)
|
||||
j_greater_equal_n=branch if greater or equal (numeric)
|
||||
j_greater_equal_n_long=branch if greater or equal (numeric, long offset)
|
||||
j_greater_long=branch if greater than (long offset)
|
||||
j_greater_n=branch if greater than (numeric)
|
||||
j_greater_n_long=branch if greater than (numeric, long offset)
|
||||
j_less=branch if less than
|
||||
j_less_equal=branch if less than or equal
|
||||
j_less_equal_long=branch if less than or equal (long offset)
|
||||
j_less_equal_n=branch if less than or equal (numeric)
|
||||
j_less_equal_n_long=branch if less than or equal (numeric, long offset)
|
||||
j_less_long=branch if less than (long offset)
|
||||
j_less_n=branch if less than (numeric)
|
||||
j_less_n_long=branch if less than (numeric, long offset)
|
||||
j_not_equal=branch if loose not equal
|
||||
j_not_equal_long=branch if loose not equal (long offset)
|
||||
j_not_greater=branch if not greater than
|
||||
j_not_greater_equal=branch if not greater than or equal
|
||||
j_not_greater_equal_long=branch if not greater than or equal (long offset)
|
||||
j_not_greater_equal_n=branch if not greater than or equal (numeric)
|
||||
j_not_greater_equal_n_long=branch if not greater than or equal (numeric, long offset)
|
||||
j_not_greater_long=branch if not greater than (long offset)
|
||||
j_not_greater_n=branch if not greater than (numeric)
|
||||
j_not_greater_n_long=branch if not greater than (numeric, long offset)
|
||||
j_not_less=branch if not less than
|
||||
j_not_less_equal=branch if not less than or equal
|
||||
j_not_less_equal_long=branch if not less than or equal (long offset)
|
||||
j_not_less_equal_n=branch if not less than or equal (numeric)
|
||||
j_not_less_equal_n_long=branch if not less than or equal (numeric, long offset)
|
||||
j_not_less_long=branch if not less than (long offset)
|
||||
j_not_less_n=branch if not less than (numeric)
|
||||
j_not_less_n_long=branch if not less than (numeric, long offset)
|
||||
j_strict_equal=branch if strict equal (===)
|
||||
j_strict_equal_long=branch if strict equal (long offset)
|
||||
j_strict_not_equal=branch if strict not equal (!==)
|
||||
j_strict_not_equal_long=branch if strict not equal (long offset)
|
||||
jequal=branch if loose equal
|
||||
jequal_long=branch if loose equal (long offset)
|
||||
jgreater=branch if greater than
|
||||
jgreater_equal=branch if greater than or equal
|
||||
jgreater_equal_long=branch if greater than or equal (long offset)
|
||||
jgreater_equal_n=branch if greater or equal (numeric)
|
||||
jgreater_equal_nlong=branch if greater or equal (numeric, long offset)
|
||||
jgreater_long=branch if greater than (long offset)
|
||||
jgreater_n=branch if greater than (numeric)
|
||||
jgreater_nlong=branch if greater than (numeric, long offset)
|
||||
jless=branch if less than
|
||||
jless_equal=branch if less than or equal
|
||||
jless_equal_long=branch if less than or equal (long offset)
|
||||
jless_equal_n=branch if less than or equal (numeric)
|
||||
jless_equal_nlong=branch if less than or equal (numeric, long offset)
|
||||
jless_long=branch if less than (long offset)
|
||||
jless_n=branch if less than (numeric)
|
||||
jless_nlong=branch if less than (numeric, long offset)
|
||||
jmp=unconditional branch
|
||||
jmp_builtin_is=branch if value is a specific builtin
|
||||
jmp_builtin_is_long=branch if value is a specific builtin (long offset)
|
||||
jmp_builtin_is_not=branch if value is not a specific builtin
|
||||
jmp_builtin_is_not_long=branch if value is not a specific builtin (long offset)
|
||||
jmp_false=branch if value is falsy
|
||||
jmp_false_long=branch if value is falsy (long offset)
|
||||
jmp_long=unconditional branch (long offset)
|
||||
jmp_true=branch if value is truthy
|
||||
jmp_true_long=branch if value is truthy (long offset)
|
||||
jmp_type_of_is=branch if typeof value matches a tag
|
||||
jmp_undefined=branch if value is undefined
|
||||
jmp_undefined_long=branch if value is undefined (long offset)
|
||||
jnot_equal=branch if loose not equal
|
||||
jnot_equal_long=branch if loose not equal (long offset)
|
||||
jnot_greater=branch if not greater than
|
||||
jnot_greater_equal=branch if not greater than or equal
|
||||
jnot_greater_equal_long=branch if not greater than or equal (long offset)
|
||||
jnot_greater_equal_n=branch if not greater than or equal (numeric)
|
||||
jnot_greater_equal_nlong=branch if not greater than or equal (numeric, long offset)
|
||||
jnot_greater_long=branch if not greater than (long offset)
|
||||
jnot_greater_n=branch if not greater than (numeric)
|
||||
jnot_greater_nlong=branch if not greater than (numeric, long offset)
|
||||
jnot_less=branch if not less than
|
||||
jnot_less_equal=branch if not less than or equal
|
||||
jnot_less_equal_long=branch if not less than or equal (long offset)
|
||||
jnot_less_equal_n=branch if not less than or equal (numeric)
|
||||
jnot_less_equal_nlong=branch if not less than or equal (numeric, long offset)
|
||||
jnot_less_long=branch if not less than (long offset)
|
||||
jnot_less_n=branch if not less than (numeric)
|
||||
jnot_less_nlong=branch if not less than (numeric, long offset)
|
||||
jstrict_equal=branch if strict equal (===)
|
||||
jstrict_equal_long=branch if strict equal (long offset)
|
||||
jstrict_not_equal=branch if strict not equal (!==)
|
||||
jstrict_not_equal_long=branch if strict not equal (long offset)
|
||||
l_shift=left shift (<<)
|
||||
less=less than comparison (<)
|
||||
less_eq=less than or equal comparison (<=)
|
||||
load_const_big_int=load a BigInt constant
|
||||
load_const_big_int_long_index=load a BigInt constant (long index)
|
||||
load_const_double=load a double-precision float constant
|
||||
load_const_empty=load the 'empty' sentinel value
|
||||
load_const_false=load the boolean false constant
|
||||
load_const_int=load an integer constant
|
||||
load_const_null=load the null constant
|
||||
load_const_string=load a string constant by id
|
||||
load_const_string_long_index=load a string constant by id (long index)
|
||||
load_const_true=load the boolean true constant
|
||||
load_const_u_int8=load an 8-bit unsigned integer constant
|
||||
load_const_uint8=load an 8-bit unsigned integer constant
|
||||
load_const_undefined=load the undefined constant
|
||||
load_const_zero=load the integer zero constant
|
||||
load_from_environment=read a variable from a lexical environment slot
|
||||
load_from_environment_l=read from environment slot (long index)
|
||||
load_param=read a function parameter into a register
|
||||
load_param_long=read a function parameter (long index)
|
||||
load_parent_no_traps=load object's prototype skipping proxy traps
|
||||
load_this_n_s=load 'this' in non-strict mode
|
||||
load_this_ns=load 'this' in non-strict mode
|
||||
loadi16=load a signed 16-bit integer
|
||||
loadi32=load a signed 32-bit integer
|
||||
loadi8=load a signed 8-bit integer
|
||||
loadu16=load an unsigned 16-bit integer
|
||||
loadu32=load an unsigned 32-bit integer
|
||||
loadu8=load an unsigned 8-bit integer
|
||||
lshift=left shift (<<)
|
||||
mod=modulo (%) operation
|
||||
mov=copy a register into another register
|
||||
mov_long=copy a register (long form)
|
||||
mul=multiply two registers
|
||||
mul_n=numeric multiply (operands known to be numeric)
|
||||
mul32=32-bit integer multiply
|
||||
name=get the name (string id) of an object
|
||||
negate=arithmetic negation (unary minus)
|
||||
neq=loose inequality comparison (!=)
|
||||
new_array=create an empty array of given size
|
||||
new_array_with_buffer=create an array initialized from a literal buffer
|
||||
new_array_with_buffer_long=create an array from a literal buffer (long form)
|
||||
new_fast_array=create a new fast (dense, integer-indexed) array
|
||||
new_object=create an empty object
|
||||
new_object_with_buffer=create an object initialized from a literal buffer
|
||||
new_object_with_buffer_and_parent=create an object from a buffer with a given prototype
|
||||
new_object_with_buffer_long=create an object from a literal buffer (long form)
|
||||
new_object_with_parent=create an empty object with a given prototype
|
||||
new_typed_object_with_buffer=create a typed object from a literal buffer
|
||||
not=logical NOT (!)
|
||||
private_is_in=test if a private name is present in an object
|
||||
profile_point=marker used by the profiler to record execution
|
||||
put_by_id=store a property by string id
|
||||
put_by_id_long=store a property by string id (long form)
|
||||
put_by_id_loose=store a property by id (loose mode)
|
||||
put_by_id_loose_long=store a property by id (loose, long form)
|
||||
put_by_id_strict=store a property by id (strict mode)
|
||||
put_by_id_strict_long=store a property by id (strict, long form)
|
||||
put_by_val=store a property by computed value
|
||||
put_by_val_loose=store a property by computed value (loose mode)
|
||||
put_by_val_strict=store a property by computed value (strict mode)
|
||||
put_by_val_with_receiver=store a property by computed value with receiver
|
||||
put_new_own_by_id=define a new own property by id
|
||||
put_new_own_by_id_long=define a new own property by id (long form)
|
||||
put_new_own_by_id_short=define a new own property by id (short form)
|
||||
put_new_own_n_eby_id=define a new own non-enumerable property by id
|
||||
put_new_own_n_eby_id_long=define a new own non-enumerable property by id (long form)
|
||||
put_new_own_ne_by_id=define a new own non-enumerable property by id
|
||||
put_new_own_ne_by_id_long=define a new own non-enumerable property by id (long form)
|
||||
put_own_by_index=define an own property by integer index
|
||||
put_own_by_index_l=define an own property by integer index (long form)
|
||||
put_own_by_slot_idx=store an own property by inline cache slot
|
||||
put_own_by_slot_idx_long=store an own property by slot index (long form)
|
||||
put_own_by_val=define an own property by computed value
|
||||
put_own_getter_setter_by_val=define an own accessor (getter/setter) property
|
||||
put_own_private_by_sym=store an own private property by symbol
|
||||
r_shift=signed right shift (>>)
|
||||
reify_arguments=create the actual 'arguments' object lazily
|
||||
reify_arguments_loose=reify 'arguments' object in loose mode
|
||||
reify_arguments_strict=reify 'arguments' object in strict mode
|
||||
resume_generator=resume a suspended generator
|
||||
ret=return from the current function
|
||||
rshift=signed right shift (>>)
|
||||
save_generator=suspend the current generator and yield
|
||||
save_generator_long=suspend the current generator (long offset)
|
||||
select_object=pick the object operand among two values
|
||||
start_generator=initialize execution of a generator body
|
||||
store_n_pto_environment=store non-pointer value to environment slot
|
||||
store_n_pto_environment_l=store non-pointer value to environment slot (long index)
|
||||
store_np_to_environment=store non-pointer value to environment slot
|
||||
store_np_to_environment_l=store non-pointer value to environment slot (long index)
|
||||
store_to_environment=store a variable into a lexical environment slot
|
||||
store_to_environment_l=store into environment slot (long index)
|
||||
store16=store a 16-bit value to memory
|
||||
store32=store a 32-bit value to memory
|
||||
store8=store an 8-bit value to memory
|
||||
strict_eq=strict equality comparison (===)
|
||||
strict_neq=strict inequality comparison (!==)
|
||||
string_switch_imm=switch on a string with an inline jump table
|
||||
sub=subtract two registers
|
||||
sub_n=numeric subtract (operands known to be numeric)
|
||||
sub32=32-bit integer subtract
|
||||
switch_imm=switch on an integer with an inline jump table
|
||||
throw=throw an exception
|
||||
throw_if_empty=throw a ReferenceError if value is the empty sentinel (TDZ)
|
||||
throw_if_has_restricted_global_property=throw if a restricted global property already exists
|
||||
throw_if_this_initialized=throw if 'this' has already been initialized in a derived ctor
|
||||
throw_if_undefined=throw a TypeError if the value is undefined
|
||||
throw_if_undefined_inst=throw TypeError if the value is undefined (instance form)
|
||||
to_int32=convert a value to a signed 32-bit integer (ToInt32)
|
||||
to_number=convert a value to a number (ToNumber)
|
||||
to_numeric=convert a value to numeric (ToNumeric, supports BigInt)
|
||||
to_property_key=convert a value to a property key (ToPropertyKey)
|
||||
to_uint32=convert a value to an unsigned 32-bit integer (ToUint32)
|
||||
try_get_by_id=load a property by id, throwing if missing
|
||||
try_get_by_id_long=load a property by id, throwing if missing (long form)
|
||||
try_put_by_id=store a property by id, throwing if missing
|
||||
try_put_by_id_long=store a property by id, throwing if missing (long form)
|
||||
try_put_by_id_loose=store a property by id, throwing if missing (loose)
|
||||
try_put_by_id_loose_long=store a property by id, throwing if missing (loose, long form)
|
||||
try_put_by_id_strict=store a property by id, throwing if missing (strict)
|
||||
try_put_by_id_strict_long=store a property by id, throwing if missing (strict, long form)
|
||||
type_of=typeof operator
|
||||
type_of_is=test if typeof value equals a specific tag
|
||||
typed_load_parent=load the prototype of a typed object
|
||||
u_int_switch_imm=switch on an unsigned integer with an inline jump table
|
||||
u_rshift=unsigned right shift (>>>)
|
||||
unreachable=trap; this point should never be reached
|
||||
urshift=unsigned right shift (>>>)
|
||||
+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