On Fri, Apr 23, 2021 at 11:51 AM Jan Hubicka <hubi...@ucw.cz> wrote:
>
> > > That needs to be combined with the generated auto-host.h header file.
> > > From which locations do you want to build the hash? Any other $objdir
> > > files except auto-host.h?
> >
> > In fact for PCH just summing the gengtype generated files would be
> > good enough I guess ...
>
> I think one can, for example, change datastructure layout/meaning of a
> bit in tree.h that invalidates PCH but makes the accessors same.

True, the question is on how much detail we have to pay attention to.
For us of course the build-id solution works fine.  And hopefully the
days of PCH are counted...

Richard.

> Honza
> >
> > > Note 'git archive' can append arbitrary non-git files.
> > >
> > > 2) Doing checksum of *.[cC] in a given folder + auto-host.h.
> > >
> > > 3) Using git hash (+ auto-host.h), but it's likely too gross, right?
> > >
> > > > link and my "hack" to re-use the version from prev-gcc
> > > > as well as our openSUSE "hack" for reproducible builds
> > > > which elides genchecksum.c for the use of the build-id
> > > > in the actual executables.
> > >
> > > What a hack. The binary is reading it's buildid right from the memory,
> > > right?
> >
> > Well, yes (I think I've posted the patch as RFC once, attached for 
> > reference).
> >
> > Richard.
> >
> > > Thoughts?
> > >
> > > Martin
> > >
> > > >
> > > > Richard.
> > > >
> > > >> Thanks,
> > > >> Martin
> > >
>
> > Use the binaries build-id as checksum for PCH purposes.
> >
> > diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
> > index a2292f46a7d..94d633d139a 100644
> > --- a/gcc/c-family/c-pch.c
> > +++ b/gcc/c-family/c-pch.c
> > @@ -65,6 +65,66 @@ static FILE *pch_outfile;
> >
> >  static const char *get_ident (void);
> >
> > +#if _GNU_SOURCE
> > +#include <link.h>
> > +
> > +#define ALIGN(val, align)      (((val) + (align) - 1) & ~((align) - 1))
> > +
> > +static int
> > +get_build_id_1 (struct dl_phdr_info *info, size_t, void *data)
> > +{
> > +  for (unsigned i = 0; i < info->dlpi_phnum; ++i)
> > +    {
> > +      if (info->dlpi_phdr[i].p_type != PT_NOTE)
> > +     continue;
> > +      ElfW(Nhdr) *nhdr
> > +     = (ElfW(Nhdr) *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
> > +      ptrdiff_t size = info->dlpi_phdr[i].p_filesz;
> > +      ptrdiff_t align = info->dlpi_phdr[i].p_align;
> > +      if (align != 8)
> > +     align = 4;
> > +      while (size >= (ptrdiff_t)sizeof (ElfW(Nhdr)))
> > +     {
> > +       if (nhdr->n_type == NT_GNU_BUILD_ID
> > +           && nhdr->n_namesz == 4
> > +           && strncmp ((char *)nhdr
> > +                       + sizeof (ElfW(Nhdr)),
> > +                       "GNU", 4) == 0
> > +           && nhdr->n_descsz >= 16)
> > +         {
> > +           memcpy (data,
> > +                   (char *)nhdr
> > +                   + ALIGN (sizeof (ElfW(Nhdr))
> > +                            + nhdr->n_namesz, align), 16);
> > +           return 1;
> > +         }
> > +       size_t offset = (ALIGN (sizeof (ElfW(Nhdr))
> > +                               + nhdr->n_namesz, align)
> > +                        + ALIGN(nhdr->n_descsz, align));
> > +       nhdr = (ElfW(Nhdr) *)((char *)nhdr + offset);
> > +       size -= offset;
> > +     }
> > +    }
> > +
> > +  return 0;
> > +}
> > +
> > +static const unsigned char *
> > +get_build_id ()
> > +{
> > +  static unsigned char build_id[16];
> > +  if (!dl_iterate_phdr (get_build_id_1, build_id))
> > +    return NULL;
> > +  return build_id;
> > +}
> > +#else
> > +static const unsigned char *
> > +get_build_id ()
> > +{
> > +  return NULL;
> > +}
> > +#endif
> > +
> >  /* Compute an appropriate 8-byte magic number for the PCH file, so that
> >     utilities like file(1) can identify it, and so that GCC can quickly
> >     ignore non-PCH files and PCH files that are of a completely different
> > @@ -120,8 +180,11 @@ pch_init (void)
> >    v.pch_init = &pch_init;
> >    target_validity = targetm.get_pch_validity (&v.target_data_length);
> >
> > +  const unsigned char *chksum = get_build_id ();
> > +  if (!chksum)
> > +    chksum = executable_checksum;
> >    if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
> > -      || fwrite (executable_checksum, 16, 1, f) != 1
> > +      || fwrite (chksum, 16, 1, f) != 1
> >        || fwrite (&v, sizeof (v), 1, f) != 1
> >        || fwrite (target_validity, v.target_data_length, 1, f) != 1)
> >      fatal_error (input_location, "cannot write to %s: %m", pch_file);
> > @@ -237,7 +300,10 @@ c_common_valid_pch (cpp_reader *pfile, const char 
> > *name, int fd)
> >       }
> >        return 2;
> >      }
> > -  if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
> > +  const unsigned char *chksum = get_build_id ();
> > +  if (!chksum)
> > +    chksum = executable_checksum;
> > +  if (memcmp (ident + IDENT_LENGTH, chksum, 16) != 0)
> >      {
> >        if (cpp_get_options (pfile)->warn_invalid_pch)
> >       cpp_error (pfile, CPP_DL_WARNING,
> > diff --git a/gcc/genchecksum.c b/gcc/genchecksum.c
> > index 09fbb63fa93..ec8b3281d53 100644
> > --- a/gcc/genchecksum.c
> > +++ b/gcc/genchecksum.c
> > @@ -113,8 +113,13 @@ main (int argc, char ** argv)
> >    puts ("#include \"config.h\"");
> >    puts ("#include \"system.h\"");
> >    fputs ("EXPORTED_CONST unsigned char executable_checksum[16] = { ", 
> > stdout);
> > +#if _GNU_SOURCE
> > +  for (i = 0; i < 16; i++)
> > +    printf ("0x%02x%s", 0, i == 15 ? " };\n" : ", ");
> > +#else
> >    for (i = 0; i < 16; i++)
> >      printf ("0x%02x%s", result[i], i == 15 ? " };\n" : ", ");
> > +#endif
> >
> >    return 0;
> >  }
>

Reply via email to