mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-21 06:40:33 +00:00
Initial support for D calling convention ##analysis
* Only for x86-32 for now * Uses a reverse register list for passing arguments * See libr/anal/d/README.md for more details * Support ret2 (to return 64bit values) * Add fcn->realname for demangled names
This commit is contained in:
parent
e6a30d820c
commit
c15ace8508
@ -97,6 +97,10 @@ R_API void r_anal_cc_get_json(RAnal *anal, PJ *pj, const char *name) {
|
||||
return;
|
||||
}
|
||||
pj_ks (pj, "ret", ret);
|
||||
const char *ret2 = sdb_const_get (DB, r_strf ("cc.%s.ret2", name), 0);
|
||||
if (ret2) {
|
||||
pj_ks (pj, "ret2", ret2);
|
||||
}
|
||||
char *sig = r_anal_cc_get (anal, name);
|
||||
pj_ks (pj, "signature", sig);
|
||||
free (sig);
|
||||
@ -121,26 +125,40 @@ R_API void r_anal_cc_get_json(RAnal *anal, PJ *pj, const char *name) {
|
||||
}
|
||||
|
||||
R_API char *r_anal_cc_get(RAnal *anal, const char *name) {
|
||||
Sdb *db = anal->sdb_cc;
|
||||
r_return_val_if_fail (anal && name, NULL);
|
||||
int i;
|
||||
// get cc by name and print the expr
|
||||
if (strcmp (sdb_const_get (DB, name, 0), "cc")) {
|
||||
if (strcmp (sdb_const_get (db, name, 0), "cc")) {
|
||||
R_LOG_ERROR ("Invalid calling convention name (%s)", name);
|
||||
return NULL;
|
||||
}
|
||||
r_strf_var (ccret, 128, "cc.%s.ret", name);
|
||||
const char *ret = sdb_const_get (DB, ccret, 0);
|
||||
const char *ret = sdb_const_get (db, ccret, 0);
|
||||
if (!ret) {
|
||||
R_LOG_ERROR ("Cannot find return type for %s", name);
|
||||
return NULL;
|
||||
}
|
||||
r_strf_var (ccret2, 128, "cc.%s.ret2", name);
|
||||
const char *ret2 = sdb_const_get (db, ccret2, 0);
|
||||
|
||||
RStrBuf *sb = r_strbuf_new (NULL);
|
||||
const char *self = r_anal_cc_self (anal, name);
|
||||
r_strbuf_appendf (sb, "%s %s%s%s (", ret, r_str_get (self), self? ".": "", name);
|
||||
if (ret2) {
|
||||
r_strbuf_appendf (sb, "%s:%s %s%s%s (", ret, ret2, r_str_get (self), self? ".": "", name);
|
||||
} else {
|
||||
r_strbuf_appendf (sb, "%s %s%s%s (", ret, r_str_get (self), self? ".": "", name);
|
||||
}
|
||||
bool isFirst = true;
|
||||
bool revarg = false;
|
||||
{
|
||||
r_strf_var (k, 128, "cc.%s.revarg", name);
|
||||
const char *s = sdb_const_get (db, k, 0);
|
||||
revarg = r_str_is_true (s);
|
||||
}
|
||||
for (i = 0; i < R_ANAL_CC_MAXARG; i++) {
|
||||
r_strf_var (k, 128, "cc.%s.arg%d", name, i);
|
||||
const char *arg = sdb_const_get (DB, k, 0);
|
||||
const char *arg = sdb_const_get (db, k, 0);
|
||||
if (!arg) {
|
||||
break;
|
||||
}
|
||||
@ -148,7 +166,7 @@ R_API char *r_anal_cc_get(RAnal *anal, const char *name) {
|
||||
isFirst = false;
|
||||
}
|
||||
r_strf_var (rename, 128, "cc.%s.argn", name);
|
||||
const char *argn = sdb_const_get (DB, rename, 0);
|
||||
const char *argn = sdb_const_get (db, rename, 0);
|
||||
if (argn) {
|
||||
r_strbuf_appendf (sb, "%s%s", isFirst? "": ", ", argn);
|
||||
}
|
||||
@ -160,27 +178,38 @@ R_API char *r_anal_cc_get(RAnal *anal, const char *name) {
|
||||
}
|
||||
|
||||
r_strbuf_append (sb, ";");
|
||||
if (revarg) {
|
||||
r_strbuf_append (sb, " // revarg");
|
||||
}
|
||||
return r_strbuf_drain (sb);
|
||||
}
|
||||
|
||||
R_API bool r_anal_cc_exist(RAnal *anal, const char *convention) {
|
||||
r_return_val_if_fail (anal && convention, false);
|
||||
const char *x = sdb_const_get (DB, convention, 0);
|
||||
return x && *x && !strcmp (x, "cc");
|
||||
R_API bool r_anal_cc_exist(RAnal *anal, const char *cc) {
|
||||
r_return_val_if_fail (anal && cc, false);
|
||||
const char *x = sdb_const_get (DB, cc, 0);
|
||||
return (x != NULL) && !strcmp (x, "cc");
|
||||
}
|
||||
|
||||
R_API const char *r_anal_cc_arg(RAnal *anal, const char *convention, int n) {
|
||||
R_API const char *r_anal_cc_arg(RAnal *anal, const char *cc, int n, int lastn) {
|
||||
r_return_val_if_fail (anal && n >= 0, NULL);
|
||||
if (!convention) {
|
||||
if (!cc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Sdb *db = DB;
|
||||
r_strf_buffer (64);
|
||||
char *query = r_strf ("cc.%s.arg%d", convention, n);
|
||||
const char *ret = sdb_const_get (DB, query, 0);
|
||||
if (lastn >= 0) {
|
||||
char *revarg = r_strf ("cc.%s.revarg", cc);
|
||||
if (r_str_is_true (revarg)) {
|
||||
// check if revarg is set, this is used only for D
|
||||
R_LOG_INFO ("EXPERIMENTAL: Reversing argument position");
|
||||
n = lastn - n;
|
||||
}
|
||||
}
|
||||
char *query = r_strf ("cc.%s.arg%d", cc, n);
|
||||
const char *ret = sdb_const_get (db, query, 0);
|
||||
if (!ret) {
|
||||
query = r_strf ("cc.%s.argn", convention);
|
||||
ret = sdb_const_get (DB, query, 0);
|
||||
query = r_strf ("cc.%s.argn", cc);
|
||||
ret = sdb_const_get (db, query, 0);
|
||||
}
|
||||
return ret? r_str_constpool_get (&anal->constpool, ret): NULL;
|
||||
}
|
||||
@ -207,7 +236,7 @@ R_API const char *r_anal_cc_error(RAnal *anal, const char *convention) {
|
||||
R_CRITICAL_ENTER (anal);
|
||||
r_strf_var (query, 64, "cc.%s.error", convention);
|
||||
const char *error = sdb_const_get (DB, query, 0);
|
||||
const char * res = error? r_str_constpool_get (&anal->constpool, error): NULL;
|
||||
const char *res = error? r_str_constpool_get (&anal->constpool, error): NULL;
|
||||
R_CRITICAL_LEAVE (anal);
|
||||
return res;
|
||||
}
|
||||
|
@ -8,3 +8,45 @@ structures and this is used for the code analysis and type propagation logic.
|
||||
* spec.sdb.txt = format modifiers like %p %d %s its used for type propagation
|
||||
* types.sdb.txt = basic C-like types
|
||||
* $os-$bits.sdb.txt = os-arch-bits structs and enums
|
||||
|
||||
## Types: structs / enums / constants
|
||||
|
||||
## Calling Conventions
|
||||
|
||||
Those are defined in the `cc-${arch}-${bits}.sdb.txt` files.
|
||||
|
||||
### dlang calling convention
|
||||
|
||||
* narg = 1 : edi
|
||||
* narg = 2 : esi, edi
|
||||
* narg = 3 : edx, esi, edi
|
||||
* narg = 4 : ecx, edx, esi, edi
|
||||
* narg = 5 : r8d, ecx, edx, esi, edi
|
||||
* narg = 6 : r9d, r8d, ecx, edx, esi, edi
|
||||
* narg = 7 : push, r9d, r8d, ecx, edx, esi, edi
|
||||
|
||||
```asm
|
||||
mov R9D,1
|
||||
mov R8D,2
|
||||
mov ECX,3
|
||||
mov EDX,4
|
||||
mov ESI,5
|
||||
mov EDI,6
|
||||
|
||||
mov R8D,1
|
||||
mov ECX,2
|
||||
mov EDX,3
|
||||
mov ESI,4
|
||||
mov EDI,5
|
||||
|
||||
push 1
|
||||
push 2
|
||||
mov R9D,3
|
||||
mov R8D,4
|
||||
mov ECX,5
|
||||
mov EDX,6
|
||||
mov ESI,7
|
||||
mov EDI,8
|
||||
call int example.square(int, int, int, int, int, int, int, int)@PLT32
|
||||
add RSP,010h
|
||||
```
|
||||
|
@ -30,3 +30,17 @@ p9=cc
|
||||
cc.p9.arg0=x0
|
||||
cc.p9.argn=stack
|
||||
cc.p9.ret=x0
|
||||
|
||||
dlang=cc
|
||||
cc.dlang.arg0=x0
|
||||
cc.dlang.arg1=x1
|
||||
cc.dlang.arg2=x2
|
||||
cc.dlang.arg3=x3
|
||||
cc.dlang.arg4=x4
|
||||
cc.dlang.arg5=x5
|
||||
cc.dlang.arg6=x6
|
||||
cc.dlang.arg7=x7
|
||||
cc.dlang.argn=stack
|
||||
cc.dlang.self=x20
|
||||
cc.dlang.error=x21
|
||||
cc.dlang.ret=x0
|
||||
|
@ -44,3 +44,16 @@ cc.watcom.argn=stack
|
||||
pascal=cc
|
||||
cc.pascal.ret=eax
|
||||
cc.pascal.argn=stack_rev
|
||||
|
||||
# reverse argument calling convention. only for gcc and dmd, ldc2 uses normal cdecl CC
|
||||
dlang=cc
|
||||
cc.dlang.ret=eax
|
||||
cc.dlang.ret2=edx
|
||||
cc.dlang.revarg=1
|
||||
cc.dlang.arg0=edi
|
||||
cc.dlang.arg1=esi
|
||||
cc.dlang.arg2=edx
|
||||
cc.dlang.arg3=ecx
|
||||
cc.dlang.arg4=r8d
|
||||
cc.dlang.arg5=r9d
|
||||
cc.dlang.argn=stack_rev
|
||||
|
@ -51,3 +51,14 @@ p9=cc
|
||||
cc.p9.arg0=rbp
|
||||
cc.p9.argn=stack
|
||||
cc.p9.ret=rax
|
||||
|
||||
dlang=cc
|
||||
cc.dlang.ret=rax
|
||||
cc.dlang.ret2=rdx
|
||||
cc.dlang.arg0=rdi
|
||||
cc.dlang.arg1=rsi
|
||||
cc.dlang.arg2=rdx
|
||||
cc.dlang.arg3=rcx
|
||||
cc.dlang.arg4=r8d
|
||||
cc.dlang.arg5=r9d
|
||||
cc.dlang.argn=stack
|
||||
|
@ -589,9 +589,10 @@ R_API int r_anal_var_get_argnum(RAnalVar *var) {
|
||||
r_unref (ri);
|
||||
int i;
|
||||
char *cc = var->fcn->cc ? strdup (var->fcn->cc): NULL;
|
||||
int arg_max = cc ? r_anal_cc_max_arg (anal, cc) : 0;
|
||||
const int arg_max = cc ? r_anal_cc_max_arg (anal, cc) : 0;
|
||||
int total = 0;
|
||||
for (i = 0; i < arg_max; i++) {
|
||||
const char *reg_arg = r_anal_cc_arg (anal, cc, i);
|
||||
const char *reg_arg = r_anal_cc_arg (anal, cc, i, total);
|
||||
if (reg_arg && !strcmp (ri_name, reg_arg)) {
|
||||
free (cc);
|
||||
free (ri_name);
|
||||
@ -1001,6 +1002,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
||||
R_LOG_WARN ("Analysis didn't fill op->src/dst at 0x%" PFMT64x, op->addr);
|
||||
}
|
||||
|
||||
const int maxarg = 32; // TODO: use maxarg ?
|
||||
int rw = (op->direction == R_ANAL_OP_DIR_WRITE) ? R_ANAL_VAR_ACCESS_TYPE_WRITE : R_ANAL_VAR_ACCESS_TYPE_READ;
|
||||
if (*sign == '+') {
|
||||
const bool isarg = type == R_ANAL_VAR_KIND_SPV ? ptr >= fcn->stack : ptr >= fcn->bp_off;
|
||||
@ -1021,7 +1023,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
||||
}
|
||||
char *varname = NULL, *vartype = NULL;
|
||||
if (isarg) {
|
||||
const char *place = fcn->cc ? r_anal_cc_arg (anal, fcn->cc, ST32_MAX) : NULL;
|
||||
const char *place = fcn->cc ? r_anal_cc_arg (anal, fcn->cc, maxarg, -1) : NULL;
|
||||
bool stack_rev = place ? !strcmp (place, "stack_rev") : false;
|
||||
char *fname = r_type_func_guess (anal->sdb_types, fcn->name);
|
||||
if (fname) {
|
||||
@ -1245,6 +1247,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
|
||||
callee_rargs_l = r_anal_var_list (anal, f, R_ANAL_VAR_KIND_REG);
|
||||
}
|
||||
int i;
|
||||
const int total = callee_rargs;
|
||||
for (i = 0; i < callee_rargs; i++) {
|
||||
if (reg_set[i]) {
|
||||
continue;
|
||||
@ -1253,7 +1256,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
|
||||
char *type = NULL;
|
||||
char *name = NULL;
|
||||
int delta = 0;
|
||||
const char *regname = r_anal_cc_arg (anal, fcn->cc, i);
|
||||
const char *regname = r_anal_cc_arg (anal, fcn->cc, i, total);
|
||||
if (regname) {
|
||||
RRegItem *ri = r_reg_get (anal->reg, regname, -1);
|
||||
if (ri) {
|
||||
@ -1300,8 +1303,9 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
|
||||
return;
|
||||
}
|
||||
|
||||
const int total = 0; // TODO: pass argn
|
||||
for (i = 0; i < max_count; i++) {
|
||||
const char *regname = r_anal_cc_arg (anal, fcn->cc, i);
|
||||
const char *regname = r_anal_cc_arg (anal, fcn->cc, i, total);
|
||||
if (!regname) {
|
||||
// WIP break;
|
||||
} else {
|
||||
|
@ -415,13 +415,14 @@ static void type_match(RCore *core, char *fcn_name, ut64 addr, ut64 baddr, const
|
||||
return;
|
||||
}
|
||||
int i, j, pos = 0, size = 0, max = r_type_func_args_count (TDB, fcn_name);
|
||||
const char *place = r_anal_cc_arg (anal, cc, ST32_MAX);
|
||||
int lastarg = ST32_MAX;
|
||||
const char *place = r_anal_cc_arg (anal, cc, lastarg, -1);
|
||||
r_cons_break_push (NULL, NULL);
|
||||
|
||||
if (place && !strcmp (place, "stack_rev")) {
|
||||
stack_rev = true;
|
||||
}
|
||||
place = r_anal_cc_arg (anal, cc, 0);
|
||||
place = r_anal_cc_arg (anal, cc, 0, -1);
|
||||
if (place && r_str_startswith (place, "stack")) {
|
||||
in_stack = true;
|
||||
}
|
||||
@ -468,7 +469,7 @@ static void type_match(RCore *core, char *fcn_name, ut64 addr, ut64 baddr, const
|
||||
// XXX: param arg_num must be fixed to support floating point register
|
||||
// before this change place could be null
|
||||
DD eprintf ("not in stack\n");
|
||||
const char *p = r_anal_cc_arg (anal, cc, arg_num);
|
||||
const char *p = r_anal_cc_arg (anal, cc, arg_num, -1);
|
||||
if (p && r_str_startswith (p, "stack")) {
|
||||
in_stack = true;
|
||||
place = p;
|
||||
|
@ -25,7 +25,7 @@ static void set_fcn_args_info(RAnalFuncArg *arg, RAnal *anal, const char *fcn_na
|
||||
arg->fmt = sdb_const_get (TDB, query, 0);
|
||||
const char *t_query = r_strf ("type.%s.size", arg->c_type);
|
||||
arg->size = sdb_num_get (TDB, t_query, 0) / 8;
|
||||
arg->cc_source = r_anal_cc_arg (anal, cc, arg_num);
|
||||
arg->cc_source = r_anal_cc_arg (anal, cc, arg_num, -1);
|
||||
}
|
||||
|
||||
R_API char *resolve_fcn_name(RAnal *anal, const char *func_name) {
|
||||
@ -231,7 +231,7 @@ R_API RList *r_core_get_func_args(RCore *core, const char *fcn_name) {
|
||||
return NULL;
|
||||
}
|
||||
char *cc = strdup (r_anal_cc_func (core->anal, key));
|
||||
const char *src = r_anal_cc_arg (core->anal, cc, 0); // src of first argument
|
||||
const char *src = r_anal_cc_arg (core->anal, cc, 0, -1); // src of first argument
|
||||
if (!cc) {
|
||||
// unsupported calling convention
|
||||
free (key);
|
||||
|
@ -287,8 +287,8 @@ R_API int r_core_pseudo_code(RCore *core, const char *input) {
|
||||
pj_ka (pj, "annotations");
|
||||
}
|
||||
const char *cc = fcn->cc ? fcn->cc: "default";
|
||||
const char *cc_a0 = r_anal_cc_arg (core->anal, cc, 0);
|
||||
const char *cc_a1 = r_anal_cc_arg (core->anal, cc, 1);
|
||||
const char *cc_a0 = r_anal_cc_arg (core->anal, cc, 0, -1);
|
||||
const char *cc_a1 = r_anal_cc_arg (core->anal, cc, 1, -1);
|
||||
const char *a0 = cc_a0? cc_a0: r_reg_get_name_by_type (core->anal->reg, "A0");
|
||||
const char *a1 = cc_a1? cc_a1: r_reg_get_name_by_type (core->anal->reg, "A1");
|
||||
const char *r0 = r_reg_get_name_by_type (core->anal->reg, "R0");
|
||||
|
@ -27,7 +27,7 @@ R_API ut64 r_debug_arg_get(RDebug *dbg, const char *cc, int num) {
|
||||
return (ut64)n32;
|
||||
}
|
||||
}
|
||||
const char *rn = r_anal_cc_arg (dbg->anal, cc, num);
|
||||
const char *rn = r_anal_cc_arg (dbg->anal, cc, num, -1);
|
||||
if (rn) {
|
||||
return r_debug_reg_get (dbg, rn);
|
||||
}
|
||||
@ -43,7 +43,7 @@ R_API bool r_debug_arg_set(RDebug *dbg, const char *cc, int num, ut64 val) {
|
||||
if (!R_STR_ISEMPTY (cc)) {
|
||||
cc = r_anal_syscc_default (dbg->anal);
|
||||
}
|
||||
const char *rn = r_anal_cc_arg (dbg->anal, cc, num);
|
||||
const char *rn = r_anal_cc_arg (dbg->anal, cc, num, -1);
|
||||
if (rn) {
|
||||
r_debug_reg_set (dbg, rn, val);
|
||||
return true;
|
||||
|
@ -255,7 +255,6 @@ struct r_anal_attr_t {
|
||||
};
|
||||
|
||||
/* Stores useful function metadata */
|
||||
/* TODO: Think about moving more stuff to this structure? */
|
||||
typedef struct r_anal_function_meta_t {
|
||||
// _min and _max are calculated lazily when queried.
|
||||
// On changes, they will either be updated (if this can be done trivially) or invalidated.
|
||||
@ -269,7 +268,7 @@ typedef struct r_anal_function_meta_t {
|
||||
|
||||
typedef struct r_anal_function_t {
|
||||
char *name;
|
||||
// R2_590: add realname for the mangled one
|
||||
char *realname; // R2_590: add realname for the mangled one
|
||||
int bits; // ((> bits 0) (set-bits bits))
|
||||
int type;
|
||||
const char *cc; // calling convention, should come from RAnal.constpool
|
||||
@ -1203,7 +1202,7 @@ R_API bool r_anal_cc_set(RAnal *anal, const char *expr);
|
||||
R_API char *r_anal_cc_get(RAnal *anal, const char *name);
|
||||
R_API bool r_anal_cc_once(RAnal *anal);
|
||||
R_API void r_anal_cc_get_json(RAnal *anal, PJ *pj, const char *name);
|
||||
R_API const char *r_anal_cc_arg(RAnal *anal, const char *convention, int n);
|
||||
R_API const char *r_anal_cc_arg(RAnal *anal, const char *convention, int n, int lastn);
|
||||
R_API const char *r_anal_cc_self(RAnal *anal, const char *convention);
|
||||
R_API void r_anal_cc_set_self(RAnal *anal, const char *convention, const char *self);
|
||||
R_API const char *r_anal_cc_error(RAnal *anal, const char *convention);
|
||||
|
@ -9,6 +9,7 @@ EOF
|
||||
EXPECT=<<EOF
|
||||
amd64
|
||||
amd64syscall
|
||||
dlang
|
||||
ms
|
||||
p9
|
||||
reg
|
||||
@ -74,6 +75,7 @@ afcl
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
arm64
|
||||
dlang
|
||||
p9
|
||||
reg
|
||||
swift
|
||||
|
@ -92,6 +92,7 @@ EOF
|
||||
EXPECT=<<EOF
|
||||
amd64
|
||||
amd64syscall
|
||||
dlang
|
||||
ms
|
||||
p9
|
||||
reg
|
||||
@ -100,6 +101,7 @@ r0 reg(r0, r1, r2, r3)
|
||||
rax reg(rdi, rsi, rdx, rcx)
|
||||
amd64
|
||||
amd64syscall
|
||||
dlang
|
||||
ms
|
||||
p9
|
||||
reg
|
||||
|
@ -3230,6 +3230,16 @@ EXPECT=<<EOF
|
||||
"cc.cdecl-fastcall-ms.ret=eax",
|
||||
"cc.cdecl.argn=stack",
|
||||
"cc.cdecl.ret=eax",
|
||||
"cc.dlang.arg0=edi",
|
||||
"cc.dlang.arg1=esi",
|
||||
"cc.dlang.arg2=edx",
|
||||
"cc.dlang.arg3=ecx",
|
||||
"cc.dlang.arg4=r8d",
|
||||
"cc.dlang.arg5=r9d",
|
||||
"cc.dlang.argn=stack_rev",
|
||||
"cc.dlang.ret=eax",
|
||||
"cc.dlang.ret2=edx",
|
||||
"cc.dlang.revarg=1",
|
||||
"cc.fastcall.arg0=ecx",
|
||||
"cc.fastcall.arg1=edx",
|
||||
"cc.fastcall.argn=stack",
|
||||
@ -3257,6 +3267,7 @@ EXPECT=<<EOF
|
||||
"cdecl=cc",
|
||||
"cdecl-fastcall-ms=cc",
|
||||
"default.cc=cdecl",
|
||||
"dlang=cc",
|
||||
"fastcall=cc",
|
||||
"optlink=cc",
|
||||
"pascal=cc",
|
||||
|
@ -8,6 +8,7 @@ EOF
|
||||
EXPECT=<<EOF
|
||||
amd64
|
||||
amd64syscall
|
||||
dlang
|
||||
ms
|
||||
p9
|
||||
reg
|
||||
@ -21,6 +22,7 @@ CMDS=tcc
|
||||
EXPECT=<<EOF
|
||||
amd64
|
||||
amd64syscall
|
||||
dlang
|
||||
ms
|
||||
p9
|
||||
reg
|
||||
@ -36,15 +38,17 @@ tccl
|
||||
tcc*
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
{"amd64":{"ret":"rax","signature":"rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"]},"amd64syscall":{"ret":"rax","signature":"rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);","args":["rdi","rsi","rdx","r10","r8","r9"]},"ms":{"ret":"rax","signature":"rax ms (rcx, rdx, r8, r9, stack);","args":["rcx","rdx","r8","r9"],"argn":"stack"},"p9":{"ret":"rax","signature":"rax p9 (rbp, stack);","args":["rbp"],"argn":"stack"},"reg":{"ret":"rax","signature":"rax reg (rdi, rsi, rdx, rcx);","args":["rdi","rsi","rdx","rcx"]},"swift":{"ret":"rax","signature":"rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"],"error":"r12"}}
|
||||
{"amd64":{"ret":"rax","signature":"rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"]},"amd64syscall":{"ret":"rax","signature":"rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);","args":["rdi","rsi","rdx","r10","r8","r9"]},"dlang":{"ret":"rax","ret2":"rdx","signature":"rax:rdx dlang (rdi, rsi, rdx, rcx, r8d, r9d, stack);","args":["rdi","rsi","rdx","rcx","r8d","r9d"],"argn":"stack"},"ms":{"ret":"rax","signature":"rax ms (rcx, rdx, r8, r9, stack);","args":["rcx","rdx","r8","r9"],"argn":"stack"},"p9":{"ret":"rax","signature":"rax p9 (rbp, stack);","args":["rbp"],"argn":"stack"},"reg":{"ret":"rax","signature":"rax reg (rdi, rsi, rdx, rcx);","args":["rdi","rsi","rdx","rcx"]},"swift":{"ret":"rax","signature":"rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"],"error":"r12"}}
|
||||
rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);
|
||||
rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);
|
||||
rax:rdx dlang (rdi, rsi, rdx, rcx, r8d, r9d, stack);
|
||||
rax ms (rcx, rdx, r8, r9, stack);
|
||||
rax p9 (rbp, stack);
|
||||
rax reg (rdi, rsi, rdx, rcx);
|
||||
rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;
|
||||
tcc rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);
|
||||
tcc rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);
|
||||
tcc rax:rdx dlang (rdi, rsi, rdx, rcx, r8d, r9d, stack);
|
||||
tcc rax ms (rcx, rdx, r8, r9, stack);
|
||||
tcc rax p9 (rbp, stack);
|
||||
tcc rax reg (rdi, rsi, rdx, rcx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user