> > 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. 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; > }