> On 9 Nov 2021, at 12:18, Jakub Jelinek via Gcc-patches 
> <gcc-patches@gcc.gnu.org> wrote:
> 
> On Tue, Nov 09, 2021 at 11:40:08AM +0000, Iain Sandoe wrote:
>> There were two issues, of which one remains and probably affects all targets.
>> 
>> 1.  The Darwin PCH memory allocation scheme used a system that works reliably
>>    for no-PIE but not for PIE
>> 
>> .. I hacked in a similar scheme to the mmap one used on Linux .. the suspect 
>> stuff
>>   there is in choosing some place in the map that is likely to succeed…
>> 
>>  With that I get passes on all c-family pch.exp (I didn’t try to bootstrap).
> 
> Yeah, certainly.

Overnight testing for i686, powerpc and x86_64 darwin suggests I’ve found some
suitable compromise map addresses (but that scheme has always seemed a bit
fragile if the ASLR parameters get updated for a new OS edition).

>> 2. This problem remains.
>> 
>>  - if we try to emit a diagnostic when the PCH read-in has failed, it seems 
>> that
>>   cc1 hangs somewhere in trying to lookup line table info.
>> 
>> - this was happening with the Darwin fixed PCH memory address because it
>>   was trying to report a fatal error in being unable to read the file (or 
>> trying to
>>  execute fancy_abort, in response to a segv).
> 
> I guess once we:
>  /* Read in all the scalar variables.  */
>  for (rt = gt_pch_scalar_rtab; *rt; rt++)
>    for (rti = *rt; rti->base != NULL; rti++)
>      if (fread (rti->base, rti->stride, 1, f) != 1)
>        fatal_error (input_location, "cannot read PCH file: %m");
> 
>  /* Read in all the global pointers, in 6 easy loops.  */
>  for (rt = gt_ggc_rtab; *rt; rt++)
>    for (rti = *rt; rti->base != NULL; rti++)
>      for (i = 0; i < rti->nelt; i++)
>        if (fread ((char *)rti->base + rti->stride * i,
>                   sizeof (void *), 1, f) != 1)
>          fatal_error (input_location, "cannot read PCH file: %m");
> we overwrite the GTY(()) marked global vars including
> extern GTY(()) class line_maps *line_table;
> with pointers into the area we haven't mapped yet (or if the error happens
> after that mmap but before everything is fixed up (e.g. the new relocation
> processing), it is no wonder it doesn't work well.
> 
> Could we save line_table (and perhaps a few other vars) into non-GTY! copies
> of them in ggc-common.c and instead of those fatal_error (input_location, ...)
> calls in gt_pch_restore and ggc_pch_read call fatal_pch_error (...) where
> void
> fatal_pch_error (const char *gmsg)
> {
>  line_table = saved_line_table;
>  // Restore anything else that is needed for fatal_error
>  fatal_error (input_location, gmsg);
> }

That seems reasonable for the case that we call fatal_error from ggc-common, but
I don’t think it will work if fancy_abort is called (for e.g. a segv) - we 
might need to 
make a local fancy_abort() as well for that specific file, perhaps.

Or in some way defer overwriting the data until we’ve succeeded in 
reading/relocating
the whole file (not sure what the largest PCH is we might encounter).

ISTR that we force clear everything before starting the read, since I had 
problems with
phasing diagnostic output when making a previous change to this area, so the 
snapshot
might be needed quite early.

Iain


> 
>       Jakub
> 

Reply via email to