diff options
author | marcel <marcel@FreeBSD.org> | 2005-07-02 23:52:37 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2005-07-02 23:52:37 +0000 |
commit | 9e64e57e54a92f1dcb01125eafa15a65af897cdc (patch) | |
tree | 8c592ac5708941dd17f386936bfc56f9692ddb3e /sys/ddb/db_command.c | |
parent | d7e928629d1fd82199b336e5a513e6308c7ec45b (diff) | |
download | FreeBSD-src-9e64e57e54a92f1dcb01125eafa15a65af897cdc.zip FreeBSD-src-9e64e57e54a92f1dcb01125eafa15a65af897cdc.tar.gz |
Implement functions calls from within DDB on ia64. On ia64 a function
pointer doesn't point to the first instruction of that function, but
rather to a descriptor. The descriptor has the address of the first
instruction, as well as the value of the global pointer. The symbol
table doesn't know anything about descriptors, so if you lookup the
name of a function you get the address of the first instruction. The
cast from the address, which is the result of the symbol lookup, to a
function pointer as is done in db_fncall is therefore invalid.
Abstract this detail behind the DB_CALL macro. By default DB_CALL is
defined as db_fncall_generic, which yields the old behaviour. On ia64
the macro is defined as db_fncall_ia64, in which a descriptor is
constructed to yield a valid function pointer.
While here, introduce DB_MAXARGS. DB_MAXARGS replaces the existing
(local) MAXARGS. The DB_MAXARGS macro can be defined by platforms to
create a convenient maximum. By default this will be the legacy 10.
On ia64 we define this macro to be 8, for 8 is the maximum number of
arguments that can be passed in registers. This avoids having to
implement spilling of arguments on the memory stack.
Approved by: re (dwhite)
Diffstat (limited to 'sys/ddb/db_command.c')
-rw-r--r-- | sys/ddb/db_command.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 904b6a6..238a9f9 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -472,6 +472,25 @@ db_error(s) * Call random function: * !expr(arg,arg,arg) */ + +/* The generic implementation supports a maximum of 10 arguments. */ +typedef db_expr_t __db_f(db_expr_t, db_expr_t, db_expr_t, db_expr_t, + db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t); + +static __inline int +db_fncall_generic(db_expr_t addr, db_expr_t *rv, int nargs, db_expr_t args[]) +{ + __db_f *f = (__db_f *)addr; + + if (nargs > 10) { + db_printf("Too many arguments (max 10)\n"); + return (0); + } + *rv = (*f)(args[0], args[1], args[2], args[3], args[4], args[5], + args[6], args[7], args[8], args[9]); + return (1); +} + static void db_fncall(dummy1, dummy2, dummy3, dummy4) db_expr_t dummy1; @@ -480,14 +499,9 @@ db_fncall(dummy1, dummy2, dummy3, dummy4) char * dummy4; { db_expr_t fn_addr; -#define MAXARGS 11 /* XXX only 10 are passed */ - db_expr_t args[MAXARGS]; + db_expr_t args[DB_MAXARGS]; int nargs = 0; db_expr_t retval; - typedef db_expr_t fcn_10args_t(db_expr_t, db_expr_t, db_expr_t, - db_expr_t, db_expr_t, db_expr_t, db_expr_t, - db_expr_t, db_expr_t, db_expr_t); - fcn_10args_t *func; int t; if (!db_expression(&fn_addr)) { @@ -495,15 +509,14 @@ db_fncall(dummy1, dummy2, dummy3, dummy4) db_flush_lex(); return; } - func = (fcn_10args_t *)fn_addr; /* XXX */ t = db_read_token(); if (t == tLPAREN) { if (db_expression(&args[0])) { nargs++; while ((t = db_read_token()) == tCOMMA) { - if (nargs == MAXARGS) { - db_printf("Too many arguments\n"); + if (nargs == DB_MAXARGS) { + db_printf("Too many arguments (max %d)\n", DB_MAXARGS); db_flush_lex(); return; } @@ -524,13 +537,8 @@ db_fncall(dummy1, dummy2, dummy3, dummy4) } db_skip_to_eol(); - while (nargs < MAXARGS) { - args[nargs++] = 0; - } - - retval = (*func)(args[0], args[1], args[2], args[3], args[4], - args[5], args[6], args[7], args[8], args[9] ); - db_printf("%#lr\n", (long)retval); + if (DB_CALL(fn_addr, &retval, nargs, args)) + db_printf("= %#lr\n", (long)retval); } static void |