diff mbox series

[24/27] modpost: generate linker script to collect symbol versions

Message ID 20220424190811.1678416-25-masahiroy@kernel.org (mailing list archive)
State New, archived
Headers show
Series kbuild: yet another series of cleanups (modpost and LTO) | expand

Commit Message

Masahiro Yamada April 24, 2022, 7:08 p.m. UTC
Merge version CRCs per vmlinux or per module.

These linker scripts will be fed to the final link stage.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 .gitignore            |  1 +
 Makefile              |  1 +
 scripts/mod/modpost.c | 27 +++++++++++++++++++++++++++
 3 files changed, 29 insertions(+)

Comments

Nick Desaulniers April 28, 2022, 9:49 p.m. UTC | #1
On Sun, Apr 24, 2022 at 12:10 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> Merge version CRCs per vmlinux or per module.
>
> These linker scripts will be fed to the final link stage.
>
> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
> ---
>
>  .gitignore            |  1 +
>  Makefile              |  1 +
>  scripts/mod/modpost.c | 27 +++++++++++++++++++++++++++
>  3 files changed, 29 insertions(+)
>
> diff --git a/.gitignore b/.gitignore
> index 265959544978..f9dad6b917e6 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -42,6 +42,7 @@
>  *.so.dbg
>  *.su
>  *.symtypes
> +*.symver.lds
>  *.symversions
>  *.tab.[ch]
>  *.tar
> diff --git a/Makefile b/Makefile
> index 235d68fa1470..0779db3d1c0c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1859,6 +1859,7 @@ clean: $(clean-dirs)
>                 -o -name '*.c.[012]*.*' \
>                 -o -name '*.ll' \
>                 -o -name '*.gcno' \
> +               -o -name '*.symver.lds' \
>                 -o -name '*.*.symversions' \) -type f -print | xargs rm -f
>
>  # Generate tags for editors
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 43ab4f000ae3..ef779ada04c6 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -2577,6 +2577,30 @@ static void write_dump(const char *fname)
>         free(buf.p);
>  }
>
> +static void write_symversions_lds(struct module *mod)
> +{
> +       struct buffer buf = { };
> +       struct symbol *sym;
> +       char lds_file[PATH_MAX];
> +       int ret;
> +
> +       ret = snprintf(lds_file, sizeof(lds_file), "%s.symver.lds", mod->name);
> +       if (ret >= sizeof(lds_file)) {
> +               error("%s: too long path was truncated\n", lds_file);
> +               return;

If this exceptional case occurs, we should probably halt or return an
error code to main?

> +       }
> +
> +       list_for_each_entry(sym, &mod->exported_symbols, list) {
> +               if (!sym->crc_valid)
> +                       continue;
> +
> +               buf_printf(&buf, "__crc_%s = 0x%08x;\n", sym->name, sym->crc);
> +       }
> +
> +       write_if_changed(&buf, lds_file);
> +       free(buf.p);
> +}
> +
>  static void write_namespace_deps_files(const char *fname)
>  {
>         struct module *mod;
> @@ -2673,6 +2697,9 @@ int main(int argc, char **argv)
>                 char fname[PATH_MAX];
>                 int ret;
>
> +               if (modversions && !mod->from_dump)
> +                       write_symversions_lds(mod);
> +
>                 if (mod->is_vmlinux || mod->from_dump)
>                         continue;
>
> --
> 2.32.0
>
Masahiro Yamada April 29, 2022, 1:31 a.m. UTC | #2
On Fri, Apr 29, 2022 at 6:49 AM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> On Sun, Apr 24, 2022 at 12:10 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > Merge version CRCs per vmlinux or per module.
> >
> > These linker scripts will be fed to the final link stage.
> >
> > Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
> > ---
> >
> >  .gitignore            |  1 +
> >  Makefile              |  1 +
> >  scripts/mod/modpost.c | 27 +++++++++++++++++++++++++++
> >  3 files changed, 29 insertions(+)
> >
> > diff --git a/.gitignore b/.gitignore
> > index 265959544978..f9dad6b917e6 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -42,6 +42,7 @@
> >  *.so.dbg
> >  *.su
> >  *.symtypes
> > +*.symver.lds
> >  *.symversions
> >  *.tab.[ch]
> >  *.tar
> > diff --git a/Makefile b/Makefile
> > index 235d68fa1470..0779db3d1c0c 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -1859,6 +1859,7 @@ clean: $(clean-dirs)
> >                 -o -name '*.c.[012]*.*' \
> >                 -o -name '*.ll' \
> >                 -o -name '*.gcno' \
> > +               -o -name '*.symver.lds' \
> >                 -o -name '*.*.symversions' \) -type f -print | xargs rm -f
> >
> >  # Generate tags for editors
> > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> > index 43ab4f000ae3..ef779ada04c6 100644
> > --- a/scripts/mod/modpost.c
> > +++ b/scripts/mod/modpost.c
> > @@ -2577,6 +2577,30 @@ static void write_dump(const char *fname)
> >         free(buf.p);
> >  }
> >
> > +static void write_symversions_lds(struct module *mod)
> > +{
> > +       struct buffer buf = { };
> > +       struct symbol *sym;
> > +       char lds_file[PATH_MAX];
> > +       int ret;
> > +
> > +       ret = snprintf(lds_file, sizeof(lds_file), "%s.symver.lds", mod->name);
> > +       if (ret >= sizeof(lds_file)) {
> > +               error("%s: too long path was truncated\n", lds_file);
> > +               return;
>
> If this exceptional case occurs, we should probably halt or return an
> error code to main?



Could you see the comments at the bottom of
scripts/mod/modpost.h  ?


error() functions sets 'error_occurred' variable,
so main() function will exist with 1 at the end.


If we bail out at the very first error, users would
compile the kernel again and again
to fix errors one by one.

modpost continues running as far as possible
to display as many errors as possible.

Compilers usually do similar things.








> > +       }
> > +
> > +       list_for_each_entry(sym, &mod->exported_symbols, list) {
> > +               if (!sym->crc_valid)
> > +                       continue;
> > +
> > +               buf_printf(&buf, "__crc_%s = 0x%08x;\n", sym->name, sym->crc);
> > +       }
> > +
> > +       write_if_changed(&buf, lds_file);
> > +       free(buf.p);
> > +}
> > +
> >  static void write_namespace_deps_files(const char *fname)
> >  {
> >         struct module *mod;
> > @@ -2673,6 +2697,9 @@ int main(int argc, char **argv)
> >                 char fname[PATH_MAX];
> >                 int ret;
> >
> > +               if (modversions && !mod->from_dump)
> > +                       write_symversions_lds(mod);
> > +
> >                 if (mod->is_vmlinux || mod->from_dump)
> >                         continue;
> >
> > --
> > 2.32.0
> >
>
>
> --
> Thanks,
> ~Nick Desaulniers
diff mbox series

Patch

diff --git a/.gitignore b/.gitignore
index 265959544978..f9dad6b917e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@ 
 *.so.dbg
 *.su
 *.symtypes
+*.symver.lds
 *.symversions
 *.tab.[ch]
 *.tar
diff --git a/Makefile b/Makefile
index 235d68fa1470..0779db3d1c0c 100644
--- a/Makefile
+++ b/Makefile
@@ -1859,6 +1859,7 @@  clean: $(clean-dirs)
 		-o -name '*.c.[012]*.*' \
 		-o -name '*.ll' \
 		-o -name '*.gcno' \
+		-o -name '*.symver.lds' \
 		-o -name '*.*.symversions' \) -type f -print | xargs rm -f
 
 # Generate tags for editors
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 43ab4f000ae3..ef779ada04c6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2577,6 +2577,30 @@  static void write_dump(const char *fname)
 	free(buf.p);
 }
 
+static void write_symversions_lds(struct module *mod)
+{
+	struct buffer buf = { };
+	struct symbol *sym;
+	char lds_file[PATH_MAX];
+	int ret;
+
+	ret = snprintf(lds_file, sizeof(lds_file), "%s.symver.lds", mod->name);
+	if (ret >= sizeof(lds_file)) {
+		error("%s: too long path was truncated\n", lds_file);
+		return;
+	}
+
+	list_for_each_entry(sym, &mod->exported_symbols, list) {
+		if (!sym->crc_valid)
+			continue;
+
+		buf_printf(&buf, "__crc_%s = 0x%08x;\n", sym->name, sym->crc);
+	}
+
+	write_if_changed(&buf, lds_file);
+	free(buf.p);
+}
+
 static void write_namespace_deps_files(const char *fname)
 {
 	struct module *mod;
@@ -2673,6 +2697,9 @@  int main(int argc, char **argv)
 		char fname[PATH_MAX];
 		int ret;
 
+		if (modversions && !mod->from_dump)
+			write_symversions_lds(mod);
+
 		if (mod->is_vmlinux || mod->from_dump)
 			continue;