Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?

Wu Zhou
2005-11-04T03:15:11Z

Hi Mark,

On Thu, 3 Nov 2005, Mark Kettenis wrote:

> > Date: Thu, 3 Nov 2005 11:14:51 +0800 (CST)
> > From: Wu Zhou <woodzltc@cn.ibm.com>
> >
> > Maybe we can convert the argument to its pointer before we enter into
> > call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?
> > Normally what function you will use to allocate memory on the stack? I am
> > not very familar with that kind of code. Thanks!
>
> Allocating memory on the stack is actually quite eazy. Just
> substract/add the amount of space you need from/to the stack pointer,
> and use the new/old stack pointer as the address for the memory.
> Whether you should substract or add depends on whether the stack grows
> downward or upward. Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> There's quite a bit of code in infcall.c that uses this trick.
>

Thanks. I did some tests following this way. But didn't get any success.
So I had to post here again to see if anybody can help me out.

My basic idea is to create a value which hold the address to the original
argument. This is done in valur_addr for these argument which is not lval
and whose type is TYPE_CODE_INT. Then I use the above method to get a new
value which hold the address to the original address. Although it doesn't
report SEGV or "can not access memory" message, it didn't ouptut the
correct result I expected. I expect 4 (which is 2 * 2), but it return
different number for me every time I run it.

Following is the changed I made to valur_arg_coerce and value_addr. Could
anyone help me pointed out what is the reason why it fail. Thanks a lot!

Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 infcall.c
*** infcall.c 2 Sep 2005 19:02:44 -0000 1.73
--- infcall.c 4 Nov 2005 03:11:35 -0000
*************** value_arg_coerce (struct value *arg, str
*** 109,114 ****
--- 109,115 ----
switch (TYPE_CODE (type))
{
case TYPE_CODE_REF:
+ case TYPE_CODE_PTR:
if (TYPE_CODE (arg_type) != TYPE_CODE_REF
&& TYPE_CODE (arg_type) != TYPE_CODE_PTR)
{
*************** value_arg_coerce (struct value *arg, str
*** 154,160 ****
type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
break;
case TYPE_CODE_UNDEF:
- case TYPE_CODE_PTR:
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
case TYPE_CODE_VOID:
--- 155,160 ----
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.161
diff -c -3 -p -r1.161 valops.c
*** valops.c 27 May 2005 04:39:32 -0000 1.161
--- valops.c 4 Nov 2005 03:11:49 -0000
*************** value_addr (struct value *arg1)
*** 868,877 ****
}
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
return value_coerce_function (arg1);
!
if (VALUE_LVAL (arg1) != lval_memory)
error (_("Attempt to take address of value not located in memory."));

/* Get target memory address */
arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
(VALUE_ADDRESS (arg1)
--- 868,905 ----
}
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
return value_coerce_function (arg1);
! /*
if (VALUE_LVAL (arg1) != lval_memory)
error (_("Attempt to take address of value not located in memory."));
+ */
+
+ if (TYPE_CODE (type) == TYPE_CODE_INT && VALUE_LVAL (arg1) == not_lval)
+ {
+ int len = TYPE_LENGTH (type);
+ CORE_ADDR addr;
+ CORE_ADDR sp = read_sp ();
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= len;
+ /* ... so the address of the thing we push is the
+ stack pointer after we push it. */
+ addr = sp;
+ }
+ else
+ {
+ /* The stack grows up, so the address of the thing
+ we push is the stack pointer before we push it. */
+ addr = sp;
+ sp += len;
+ }
+
+ addr = (CORE_ADDR) malloc (len);
+ write_memory (addr, value_contents_all (arg1), len);
+ arg2 = value_from_pointer (lookup_pointer_type (type), addr);

+ return arg2;
+ }
/* Get target memory address */
arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
(VALUE_ADDRESS (arg1)

Regards
- Wu Zhou