On Fri, Apr 23, 2021 at 9:59 AM Martin Liška <mli...@suse.cz> wrote: > > On 4/23/21 9:28 AM, Richard Biener wrote: > > On Tue, Apr 20, 2021 at 8:49 PM Martin Liška <mli...@suse.cz> wrote: > >> > >> On 4/20/21 2:46 PM, Richard Biener wrote: > >>> OK. Can you somehow arrange for trunk to pick up LTO_major from GCC > >>> major automagically then? > >> > >> I have a pretty nice solution for it where I extended (and simplified) > >> the existing gcov-iov.c generator. Doing that we can remove > >> gcc/version.[ch]. > >> > >> Using the patch, the following version.h is generated: > >> > >> #ifndef VERSION_H > >> #define VERSION_H > >> > >> /* Generated automatically by genversion. */ > >> > >> #define GCC_major_version 12 > >> > >> /* The complete version string, assembled from several pieces. > >> BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the > >> Makefile. */ > >> > >> #define version_string "12.0.0 20210420 (experimental)" > >> #define pkgversion_string "(GCC) " > >> > >> /* This is the location of the online document giving instructions for > >> reporting bugs. If you distribute a modified version of GCC, > >> please configure with --with-bugurl pointing to a document giving > >> instructions for reporting bugs to you, not us. (You are of course > >> welcome to forward us bugs reported to you, if you determine that > >> they are not bugs in your modifications.) */ > >> > >> #define bug_report_url "<https://gcc.gnu.org/bugs/>" > >> > >> #define GCOV_VERSION ((gcov_unsigned_t)0x42323020) /* B20 */ > >> > >> #endif /* VERSION_H */ > >> > >> Ready for master? > > > > Nice. This is OK if others do not have further comments. > > Thanks, I'm going to install it once GCC 11.1 is released. > > > > > I think we'd want to explore whether we can integrate > > genchecksum.c as well and make the PCH checksum > > based on a set of source files (including the generated > > auto-host.h) - that might allow removing the two-stage > > Definitely. I see multiple options: > > 1) using git, it can make provide a hash for content of a folder: > > $ git ls-tree HEAD -- gcc > > 040000 tree db613554ec17462c63bace2015c877d6bed70bbe gcc > > One can do that per-file as well: > git ls-tree HEAD -- gcc/c/*.c > > 100644 blob bae5757ad137c0af58dbe66229d4201a45094aca gcc/c/c-aux-info.c > > 100644 blob d0035a31723447657a04c2ef79c9fd7c0ddc7568 gcc/c/c-convert.c > > 100644 blob 3ea4708c5075d9274601a0676f86a6900a9345b0 gcc/c/c-decl.c > > 100644 blob de98958ceabac9d631f937f9f28547d8aed26af2 gcc/c/c-errors.c > > 100644 blob 68c74cc1eb2ef908545b36e2dbff65606f756e15 gcc/c/c-fold.c > > ...
I think using git is out of the question unless we want to check in the generated file. We ship tarballs (w/o generated files for snapshots) and those have to build as well. > 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 ... > 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; }