Fix rare crash building PCH

Geoffrey Keating gkeating@apple.com
Thu Aug 14 03:10:00 GMT 2003


This fixes a crash that happens on Darwin like this:

A 'struct function' at 0x7ae200 contains a x_parm_reg_stack_loc field
pointing to 0x7ae400.  In the PCH file, the x_parm_reg_stack_loc
pointer will be relocated to 0x7ae200.  In the generated function
gt_pch_p_8function when relocating the 'struct function', the
x_parm_reg_stack_loc field is relocated, and then the generated
function tests whether it is relocating the 'struct function' or the
pointed-to data.  Because the field now holds the relocated value, and
it is the same as the original address of the 'struct function', the
generated function believes it is supposed to be relocating the
pointed-to data, and an abort is tripped while trying to interpret the
'struct function' as the x_parm_reg_stack_loc data.

Before the recent invention of darwin_rs6000_gt_pch_get_address, this
was impossible because a PCH was relocated to a chunk of address space
that didn't overlap the existing data structures.

Bootstrapped & tested on powerpc-darwin.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-3370702.patch=========================
2003-08-13  Geoffrey Keating  <geoffk@apple.com>

	* gengtype.c (walk_type): Process a subobject before processing
	the pointer that points to the subobject.

Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.38
diff -u -p -u -p -r1.38 gengtype.c
--- gengtype.c	17 Jul 2003 13:25:14 -0000	1.38
+++ gengtype.c	14 Aug 2003 03:06:03 -0000
@@ -1480,12 +1480,13 @@ output_escaped_param (struct walk_type_d
 /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
    which is of type T.  Write code to D->OF to constrain execution (at
    the point that D->PROCESS_FIELD is called) to the appropriate
-   cases.  D->PREV_VAL lists the objects containing the current object,
-   D->OPT is a list of options to apply, D->INDENT is the current
-   indentation level, D->LINE is used to print error messages,
-   D->BITMAP indicates which languages to print the structure for, and
-   D->PARAM is the current parameter (from an enclosing param_is
-   option).  */
+   cases.  Call D->PROCESS_FIELD on subobjects before calling it on
+   pointers to those objects.  D->PREV_VAL lists the objects
+   containing the current object, D->OPT is a list of options to
+   apply, D->INDENT is the current indentation level, D->LINE is used
+   to print error messages, D->BITMAP indicates which languages to
+   print the structure for, and D->PARAM is the current parameter
+   (from an enclosing param_is option).  */
 
 static void
 walk_type (type_p t, struct walk_type_data *d)
@@ -1622,7 +1623,6 @@ walk_type (type_p t, struct walk_type_da
 	    oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
 	    d->indent += 2;
 	    oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
-	    d->process_field(t, d);
 	    oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
 		     loopcounter, loopcounter);
 	    output_escaped_param (d, length, "length");
@@ -1638,6 +1638,7 @@ walk_type (type_p t, struct walk_type_da
 	    d->used_length = 0;
 	    d->indent -= 2;
 	    oprintf (d->of, "%*s}\n", d->indent, "");
+	    d->process_field(t, d);
 	    d->indent -= 2;
 	    oprintf (d->of, "%*s}\n", d->indent, "");
 	  }
============================================================



More information about the Gcc-patches mailing list