> 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
>