------- Additional Comments From suriya at cs dot utexas dot edu  2005-01-20 
18:07 -------

(In reply to comment #1)
> GCC 3.3 used the magic number of 1000 when initializing the number of 
> arguments.  This bug report does not state the exact failure mode of the 
> example, but the slightly greater than 1000 words (256 arguments) might 
> interact incorrectly with the magic value 1000.  The use of "1000" was 
> removed 
> in GCC 3.4, so I would recommend retesting with that GCC release.  The lack 
> of 
> description about the failure makes it difficult for anyone else to confirm 
> the report or test if the problem already is corrected.


The same problem exists with GCC 3.4.

Let me restate the problem. va_start(va_list, param) sets fields { gpr, fpr,
overflow_arg_area, reg_save_area } in the va_list structure. `gpr' is an index
into the reg_save_area. Parameters are passed into integer registers r3 through
r10. So, the index into the integer portion of reg_save_area (where the 8
integer registers, followed by the floating point registers are saved) should be
between 0 and 7 (both inclusive) to be meaningful. Any value greater than 7
indicates that the next parameter is not in the integer save area but in
overflow_arg_area.

For example, if the function was int foo(int a0, int a1, ...), then gpr would be
2, to indicate that the next integer parameter (afdter a1) is in offset 2 (the
parameter was passed in r5) of the reg_save_area.

For example, if the function was int foo(int a0, int a1, int a2, int a3, int a4,
int a5, int a6, int a7, ...), then gpr would be 8. This means that this is an
offset greater than 7 and as a result the next integer parameter (passed after
a7) is inthe overflow_arg_area.

For example, if the function was foo(int a0, int a1, int a2, int a3, int a4, int
a5, int a6, int a7, int a8, ...), then gprturns out to be be 9 (confirmed using
 gdb). This is again a value greater than 7 indicating that the next integer
parameter (passed after a8) is in the overflow_arg_area.

va_arg which gets the next argument, compares gpr to 8 to decide from which area
the load the parameter from.

In the above examples, gpr is not bound to a maximum value of 8, but instead
increments for each additional argument. gpr is of type char. As a result, if
there are 256 parameters before the ellipsis '...', gpr takes a value 0 (due to
overflow). This, incorrectly indicates (because va_arg compares gpr to 8, and 0
< 8) that the parameter is in the reg_save_area, though in reality, the
parameter is in the overflow_arg_area.

The test program I sent, had 256 parameters followed by the ellipsis.
va_arg(list, int) should give the value of the 257th parameter (counting from
one), which is 5555 (in the example, the last argument passed by main). The
program should return success, however it doesn't, because of incorrect setting
of gpr in va_start.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19491

Reply via email to