From 81d362732bac05f656cdc4bbe776ac20cfd30c45 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 6 Mar 2023 16:47:52 -0600 Subject: kbuild: Disallow DTB overlays to built from .dts named source files As a follow up to the series allowing DTB overlays to built from .dtso files. Now that all overlays have been renamed, remove the ability to build from overlays from .dts files to prevent any files with the old name from accidental being added. Signed-off-by: Andrew Davis Reviewed-by: Geert Uytterhoeven Acked-by: Andy Shevchenko Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 100a386fcd71..68d0134bdbf9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -418,9 +418,6 @@ endif $(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE $(call if_changed_dep,dtb) -$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE - $(call if_changed_dep,dtc) - $(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE $(call if_changed_dep,dtc) -- cgit v1.2.3 From 64f140417d818aa374788acc9cb8328165747262 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 12 May 2023 01:24:22 +0900 Subject: modpost: error out if addend_*_rel() is not implemented for REL arch The section mismatch check relies on the relocation entries. For REL, the addend value is implicit, so we need some code to compute it. Currently, EM_386, EM_ARM, and EM_MIPS are supported. This commit makes sure we covered all the cases. I believe the other architectures use RELA, where the explicit r_addend field exists. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d4531d09984d..c1c523adb139 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1628,6 +1628,8 @@ static void section_rel(const char *modname, struct elf_info *elf, if (addend_mips_rel(elf, sechdr, &r)) continue; break; + default: + fatal("Please add code to calculate addend for this architecture\n"); } sym = elf->symtab_start + r_sym; /* Skip special sections */ -- cgit v1.2.3 From d0acc76a49aa917c1a455d11d32d34a01e8b2835 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:19 +0900 Subject: modpost: remove broken calculation of exception_table_entry size find_extable_entry_size() is completely broken. It has awesome comments about how to calculate sizeof(struct exception_table_entry). It was based on these assumptions: - struct exception_table_entry has two fields - both of the fields have the same size Then, we came up with this equation: (offset of the second field) * 2 == (size of struct) It was true for all architectures when commit 52dc0595d540 ("modpost: handle relocations mismatch in __ex_table.") was applied. Our mathematics broke when commit 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") introduced the third field. Now, the definition of exception_table_entry is highly arch-dependent. For x86, sizeof(struct exception_table_entry) is apparently 12, but find_extable_entry_size() sets extable_entry_size to 8. I could fix it, but I do not see much value in this code. extable_entry_size is used just for selecting a slightly different error message. If the first field ("insn") references to a non-executable section, The relocation at %s+0x%lx references section "%s" which is not executable, IOW it is not possible for the kernel to fault at that address. Something is seriously wrong and should be fixed. If the second field ("fixup") references to a non-executable section, The relocation at %s+0x%lx references section "%s" which is not executable, IOW the kernel will fault if it ever tries to jump to it. Something is seriously wrong and should be fixed. Merge the two error messages rather than adding even more complexity. Change fatal() to error() to make it continue running and catch more possible errors. Fixes: 548acf19234d ("x86/mm: Expand the exception table logic to allow new handling options") Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 60 +++------------------------------------------------ 1 file changed, 3 insertions(+), 57 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c1c523adb139..ba4577aa4f1d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1292,43 +1292,6 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); } -/* - * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size() - * to know the sizeof(struct exception_table_entry) for the target architecture. - */ -static unsigned int extable_entry_size = 0; -static void find_extable_entry_size(const char* const sec, const Elf_Rela* r) -{ - /* - * If we're currently checking the second relocation within __ex_table, - * that relocation offset tells us the offsetof(struct - * exception_table_entry, fixup) which is equal to sizeof(struct - * exception_table_entry) divided by two. We use that to our advantage - * since there's no portable way to get that size as every architecture - * seems to go with different sized types. Not pretty but better than - * hard-coding the size for every architecture.. - */ - if (!extable_entry_size) - extable_entry_size = r->r_offset * 2; -} - -static inline bool is_extable_fault_address(Elf_Rela *r) -{ - /* - * extable_entry_size is only discovered after we've handled the - * _second_ relocation in __ex_table, so only abort when we're not - * handling the first reloc and extable_entry_size is zero. - */ - if (r->r_offset && extable_entry_size == 0) - fatal("extable_entry size hasn't been discovered!\n"); - - return ((r->r_offset == 0) || - (r->r_offset % extable_entry_size == 0)); -} - -#define is_second_extable_reloc(Start, Cur, Sec) \ - (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0)) - static void report_extable_warnings(const char* modname, struct elf_info* elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, @@ -1384,22 +1347,9 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf, "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", fromsec, (long)r->r_offset, tosec, modname); - else if (!is_executable_section(elf, get_secindex(elf, sym))) { - if (is_extable_fault_address(r)) - fatal("The relocation at %s+0x%lx references\n" - "section \"%s\" which is not executable, IOW\n" - "it is not possible for the kernel to fault\n" - "at that address. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - else - fatal("The relocation at %s+0x%lx references\n" - "section \"%s\" which is not executable, IOW\n" - "the kernel will fault if it ever tries to\n" - "jump to it. Something is seriously wrong\n" - "and should be fixed.\n", - fromsec, (long)r->r_offset, tosec); - } + else if (!is_executable_section(elf, get_secindex(elf, sym))) + error("%s+0x%lx references non-executable section '%s'\n", + fromsec, (long)r->r_offset, tosec); } static void check_section_mismatch(const char *modname, struct elf_info *elf, @@ -1574,8 +1524,6 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rela, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } @@ -1635,8 +1583,6 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - if (is_second_extable_reloc(start, rel, fromsec)) - find_extable_entry_size(fromsec, &r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } -- cgit v1.2.3 From 6c90d36be3e5140c93d3af360d012fa26966304a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:20 +0900 Subject: modpost: remove fromsym info in __ex_table section mismatch warning report_extable_warnings() prints "from" in a pretty form, but we know it is always located in the __ex_table section, i.e. a collection of struct exception_table_entry. It is very likely to fail to get the symbol name and ends up with meaningless message: ... in reference from the (unknown reference) (unknown) to ... Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ba4577aa4f1d..bbe066f7adbc 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1297,23 +1297,16 @@ static void report_extable_warnings(const char* modname, struct elf_info* elf, Elf_Rela* r, Elf_Sym* sym, const char* fromsec, const char* tosec) { - Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec); - const char* fromsym_name = sym_name(elf, fromsym); Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym); const char* tosym_name = sym_name(elf, tosym); - const char* from_pretty_name; - const char* from_pretty_name_p; const char* to_pretty_name; const char* to_pretty_name_p; - get_pretty_name(is_function(fromsym), - &from_pretty_name, &from_pretty_name_p); get_pretty_name(is_function(tosym), &to_pretty_name, &to_pretty_name_p); - warn("%s(%s+0x%lx): Section mismatch in reference from the %s %s%s to the %s %s:%s%s\n", - modname, fromsec, (long)r->r_offset, from_pretty_name, - fromsym_name, from_pretty_name_p, + warn("%s(%s+0x%lx): Section mismatch in reference to the %s %s:%s%s\n", + modname, fromsec, (long)r->r_offset, to_pretty_name, tosec, tosym_name, to_pretty_name_p); if (!match(tosec, mismatch->bad_tosec) && -- cgit v1.2.3 From 6691e6f5fc3e9fa76c9a50970fa851829df7d9f2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:21 +0900 Subject: modpost: remove get_prettyname() This is the last user of get_pretty_name() - it is just used to distinguish whether the symbol is a function or not. It is not valuable information. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bbe066f7adbc..371891d67175 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1207,23 +1207,6 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } -static int is_function(Elf_Sym *sym) -{ - if (sym) - return ELF_ST_TYPE(sym->st_info) == STT_FUNC; - else - return -1; -} - -static inline void get_pretty_name(int is_func, const char** name, const char** name_p) -{ - switch (is_func) { - case 0: *name = "variable"; *name_p = ""; break; - case 1: *name = "function"; *name_p = "()"; break; - default: *name = "(unknown reference)"; *name_p = ""; break; - } -} - /* * Print a warning about a section mismatch. * Try to find symbols near it so user can find it. @@ -1299,15 +1282,9 @@ static void report_extable_warnings(const char* modname, struct elf_info* elf, { Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym); const char* tosym_name = sym_name(elf, tosym); - const char* to_pretty_name; - const char* to_pretty_name_p; - - get_pretty_name(is_function(tosym), - &to_pretty_name, &to_pretty_name_p); - warn("%s(%s+0x%lx): Section mismatch in reference to the %s %s:%s%s\n", - modname, fromsec, (long)r->r_offset, - to_pretty_name, tosec, tosym_name, to_pretty_name_p); + warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", + modname, fromsec, (long)r->r_offset, tosec, tosym_name); if (!match(tosec, mismatch->bad_tosec) && is_executable_section(elf, get_secindex(elf, sym))) -- cgit v1.2.3 From faee9defd8fc376864efb39b87d59f667deeb488 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:22 +0900 Subject: modpost: squash report_extable_warnings() into extable_mismatch_handler() Collect relevant code into one place to clarify all the cases are covered by 'if () ... else if ... else ...'. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 371891d67175..7a9a3ef8ca0d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1275,40 +1275,19 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); } -static void report_extable_warnings(const char* modname, struct elf_info* elf, - const struct sectioncheck* const mismatch, - Elf_Rela* r, Elf_Sym* sym, - const char* fromsec, const char* tosec) -{ - Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym); - const char* tosym_name = sym_name(elf, tosym); - - warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", - modname, fromsec, (long)r->r_offset, tosec, tosym_name); - - if (!match(tosec, mismatch->bad_tosec) && - is_executable_section(elf, get_secindex(elf, sym))) - fprintf(stderr, - "The relocation at %s+0x%lx references\n" - "section \"%s\" which is not in the list of\n" - "authorized sections. If you're adding a new section\n" - "and/or if this reference is valid, add \"%s\" to the\n" - "list of authorized sections to jump to on fault.\n" - "This can be achieved by adding \"%s\" to \n" - "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", - fromsec, (long)r->r_offset, tosec, tosec, tosec); -} - static void extable_mismatch_handler(const char* modname, struct elf_info *elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, const char *fromsec) { const char* tosec = sec_name(elf, get_secindex(elf, sym)); + Elf_Sym *tosym = find_elf_symbol(elf, r->r_addend, sym); + const char *tosym_name = sym_name(elf, tosym); sec_mismatch_count++; - report_extable_warnings(modname, elf, mismatch, r, sym, fromsec, tosec); + warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", + modname, fromsec, (long)r->r_offset, tosec, tosym_name); if (match(tosec, mismatch->bad_tosec)) fatal("The relocation at %s+0x%lx references\n" @@ -1317,7 +1296,16 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf, "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", fromsec, (long)r->r_offset, tosec, modname); - else if (!is_executable_section(elf, get_secindex(elf, sym))) + else if (is_executable_section(elf, get_secindex(elf, sym))) + warn("The relocation at %s+0x%lx references\n" + "section \"%s\" which is not in the list of\n" + "authorized sections. If you're adding a new section\n" + "and/or if this reference is valid, add \"%s\" to the\n" + "list of authorized sections to jump to on fault.\n" + "This can be achieved by adding \"%s\" to\n" + "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", + fromsec, (long)r->r_offset, tosec, tosec, tosec); + else error("%s+0x%lx references non-executable section '%s'\n", fromsec, (long)r->r_offset, tosec); } -- cgit v1.2.3 From fc5fa862c49a4d9e23617fbda7d249d2c1b72e56 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:23 +0900 Subject: modpost: squash report_sec_mismatch() into default_mismatch_handler() report_sec_mismatch() and default_mismatch_handler() are small enough to be merged together. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 55 +++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7a9a3ef8ca0d..bb7d1d87bae7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1207,17 +1207,27 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } -/* - * Print a warning about a section mismatch. - * Try to find symbols near it so user can find it. - * Check whitelist before warning - it may be a false positive. - */ -static void report_sec_mismatch(const char *modname, - const struct sectioncheck *mismatch, - const char *fromsec, - const char *fromsym, - const char *tosec, const char *tosym) +static void default_mismatch_handler(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { + const char *tosec; + Elf_Sym *to; + Elf_Sym *from; + const char *tosym; + const char *fromsym; + + from = find_elf_symbol2(elf, r->r_offset, fromsec); + fromsym = sym_name(elf, from); + + tosec = sec_name(elf, get_secindex(elf, sym)); + to = find_elf_symbol(elf, r->r_addend, sym); + tosym = sym_name(elf, to); + + /* check whitelist - we may ignore it */ + if (!secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym)) + return; + sec_mismatch_count++; switch (mismatch->mismatch) { @@ -1242,31 +1252,6 @@ static void report_sec_mismatch(const char *modname, } } -static void default_mismatch_handler(const char *modname, struct elf_info *elf, - const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec) -{ - const char *tosec; - Elf_Sym *to; - Elf_Sym *from; - const char *tosym; - const char *fromsym; - - from = find_elf_symbol2(elf, r->r_offset, fromsec); - fromsym = sym_name(elf, from); - - tosec = sec_name(elf, get_secindex(elf, sym)); - to = find_elf_symbol(elf, r->r_addend, sym); - tosym = sym_name(elf, to); - - /* check whitelist - we may ignore it */ - if (secref_whitelist(mismatch, - fromsec, fromsym, tosec, tosym)) { - report_sec_mismatch(modname, mismatch, - fromsec, fromsym, tosec, tosym); - } -} - static int is_executable_section(struct elf_info* elf, unsigned int section_index) { if (section_index > elf->num_sections) -- cgit v1.2.3 From f4c35484e7f11458c1834b88ee55b746cdabbb09 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:24 +0900 Subject: modpost: clean up is_executable_section() SHF_EXECINSTR is a bit flag (#define SHF_EXECINSTR 0x4). Compare the masked flag to '!= 0'. There is no good reason to stop modpost immediately even if a special section index is given. You will get a section mismatch error anyway. Also, change the return type to bool. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bb7d1d87bae7..0bda2f22c985 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1207,6 +1207,14 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } +static bool is_executable_section(struct elf_info *elf, unsigned int secndx) +{ + if (secndx > elf->num_sections) + return false; + + return (elf->sechdrs[secndx].sh_flags & SHF_EXECINSTR) != 0; +} + static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) @@ -1252,14 +1260,6 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, } } -static int is_executable_section(struct elf_info* elf, unsigned int section_index) -{ - if (section_index > elf->num_sections) - fatal("section_index is outside elf->num_sections!\n"); - - return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); -} - static void extable_mismatch_handler(const char* modname, struct elf_info *elf, const struct sectioncheck* const mismatch, Elf_Rela* r, Elf_Sym* sym, -- cgit v1.2.3 From 856567d5599e7df75d7cad1fef1311d7c1854200 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:25 +0900 Subject: modpost: squash extable_mismatch_handler() into default_mismatch_handler() Merging these two reduces several lines of code. The extable section mismatch is already distinguished by EXTABLE_TO_NON_TEXT. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 84 ++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 58 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0bda2f22c985..49357a716519 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -881,27 +881,14 @@ enum mismatch { * targeting sections in this array (white-list). Can be empty. * * @mismatch: Type of mismatch. - * - * @handler: Specific handler to call when a match is found. If NULL, - * default_mismatch_handler() will be called. - * */ struct sectioncheck { const char *fromsec[20]; const char *bad_tosec[20]; const char *good_tosec[20]; enum mismatch mismatch; - void (*handler)(const char *modname, struct elf_info *elf, - const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec); - }; -static void extable_mismatch_handler(const char *modname, struct elf_info *elf, - const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, - const char *fromsec); - static const struct sectioncheck sectioncheck[] = { /* Do not reference init/exit code/data from * normal code and data @@ -974,7 +961,6 @@ static const struct sectioncheck sectioncheck[] = { .bad_tosec = { ".altinstr_replacement", NULL }, .good_tosec = {ALL_TEXT_SECTIONS , NULL}, .mismatch = EXTABLE_TO_NON_TEXT, - .handler = extable_mismatch_handler, } }; @@ -1255,60 +1241,42 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, modname, tosym, tosec); break; case EXTABLE_TO_NON_TEXT: - fatal("There's a special handler for this mismatch type, we should never get here.\n"); + warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", + modname, fromsec, (long)r->r_offset, tosec, tosym); + + if (match(tosec, mismatch->bad_tosec)) + fatal("The relocation at %s+0x%lx references\n" + "section \"%s\" which is black-listed.\n" + "Something is seriously wrong and should be fixed.\n" + "You might get more information about where this is\n" + "coming from by using scripts/check_extable.sh %s\n", + fromsec, (long)r->r_offset, tosec, modname); + else if (is_executable_section(elf, get_secindex(elf, sym))) + warn("The relocation at %s+0x%lx references\n" + "section \"%s\" which is not in the list of\n" + "authorized sections. If you're adding a new section\n" + "and/or if this reference is valid, add \"%s\" to the\n" + "list of authorized sections to jump to on fault.\n" + "This can be achieved by adding \"%s\" to\n" + "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", + fromsec, (long)r->r_offset, tosec, tosec, tosec); + else + error("%s+0x%lx references non-executable section '%s'\n", + fromsec, (long)r->r_offset, tosec); break; } } -static void extable_mismatch_handler(const char* modname, struct elf_info *elf, - const struct sectioncheck* const mismatch, - Elf_Rela* r, Elf_Sym* sym, - const char *fromsec) -{ - const char* tosec = sec_name(elf, get_secindex(elf, sym)); - Elf_Sym *tosym = find_elf_symbol(elf, r->r_addend, sym); - const char *tosym_name = sym_name(elf, tosym); - - sec_mismatch_count++; - - warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", - modname, fromsec, (long)r->r_offset, tosec, tosym_name); - - if (match(tosec, mismatch->bad_tosec)) - fatal("The relocation at %s+0x%lx references\n" - "section \"%s\" which is black-listed.\n" - "Something is seriously wrong and should be fixed.\n" - "You might get more information about where this is\n" - "coming from by using scripts/check_extable.sh %s\n", - fromsec, (long)r->r_offset, tosec, modname); - else if (is_executable_section(elf, get_secindex(elf, sym))) - warn("The relocation at %s+0x%lx references\n" - "section \"%s\" which is not in the list of\n" - "authorized sections. If you're adding a new section\n" - "and/or if this reference is valid, add \"%s\" to the\n" - "list of authorized sections to jump to on fault.\n" - "This can be achieved by adding \"%s\" to\n" - "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", - fromsec, (long)r->r_offset, tosec, tosec, tosec); - else - error("%s+0x%lx references non-executable section '%s'\n", - fromsec, (long)r->r_offset, tosec); -} - static void check_section_mismatch(const char *modname, struct elf_info *elf, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { const char *tosec = sec_name(elf, get_secindex(elf, sym)); const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec); - if (mismatch) { - if (mismatch->handler) - mismatch->handler(modname, elf, mismatch, - r, sym, fromsec); - else - default_mismatch_handler(modname, elf, mismatch, - r, sym, fromsec); - } + if (!mismatch) + return; + + default_mismatch_handler(modname, elf, mismatch, r, sym, fromsec); } static unsigned int *reloc_location(struct elf_info *elf, -- cgit v1.2.3 From dbf7cc2e4e78dfecad02ff17ff5c9971b42da462 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:26 +0900 Subject: modpost: pass 'tosec' down to default_mismatch_handler() default_mismatch_handler() does not need to compute 'tosec' because it is calculated by the caller. Pass it down to default_mismatch_handler() instead of calling sec_name() twice. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 49357a716519..2cc9c2a4aadc 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1203,9 +1203,9 @@ static bool is_executable_section(struct elf_info *elf, unsigned int secndx) static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec) + Elf_Rela *r, Elf_Sym *sym, const char *fromsec, + const char *tosec) { - const char *tosec; Elf_Sym *to; Elf_Sym *from; const char *tosym; @@ -1214,7 +1214,6 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, from = find_elf_symbol2(elf, r->r_offset, fromsec); fromsym = sym_name(elf, from); - tosec = sec_name(elf, get_secindex(elf, sym)); to = find_elf_symbol(elf, r->r_addend, sym); tosym = sym_name(elf, to); @@ -1276,7 +1275,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, if (!mismatch) return; - default_mismatch_handler(modname, elf, mismatch, r, sym, fromsec); + default_mismatch_handler(modname, elf, mismatch, r, sym, fromsec, tosec); } static unsigned int *reloc_location(struct elf_info *elf, -- cgit v1.2.3 From 9990ca35870b7c57d39f8b325d676dfd028035b4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:27 +0900 Subject: modpost: pass section index to find_elf_symbol2() find_elf_symbol2() converts the section index to the section name, then compares the two strings in each iteration. This is slow. It is faster to compare the section indices (i.e. integers) directly. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2cc9c2a4aadc..3b7b78e69137 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1169,19 +1169,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, * it is, but this works for now. **/ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, - const char *sec) + unsigned int secndx) { Elf_Sym *sym; Elf_Sym *near = NULL; Elf_Addr distance = ~0; for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { - const char *symsec; - - if (is_shndx_special(sym->st_shndx)) - continue; - symsec = sec_name(elf, get_secindex(elf, sym)); - if (strcmp(symsec, sec) != 0) + if (get_secindex(elf, sym) != secndx) continue; if (!is_valid_name(elf, sym)) continue; @@ -1203,7 +1198,8 @@ static bool is_executable_section(struct elf_info *elf, unsigned int secndx) static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec, + Elf_Rela *r, Elf_Sym *sym, + unsigned int fsecndx, const char *fromsec, const char *tosec) { Elf_Sym *to; @@ -1211,7 +1207,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, const char *tosym; const char *fromsym; - from = find_elf_symbol2(elf, r->r_offset, fromsec); + from = find_elf_symbol2(elf, r->r_offset, fsecndx); fromsym = sym_name(elf, from); to = find_elf_symbol(elf, r->r_addend, sym); @@ -1267,7 +1263,8 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, } static void check_section_mismatch(const char *modname, struct elf_info *elf, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec) + Elf_Rela *r, Elf_Sym *sym, + unsigned int fsecndx, const char *fromsec) { const char *tosec = sec_name(elf, get_secindex(elf, sym)); const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec); @@ -1275,7 +1272,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, if (!mismatch) return; - default_mismatch_handler(modname, elf, mismatch, r, sym, fromsec, tosec); + default_mismatch_handler(modname, elf, mismatch, r, sym, fsecndx, fromsec, + tosec); } static unsigned int *reloc_location(struct elf_info *elf, @@ -1390,12 +1388,11 @@ static void section_rela(const char *modname, struct elf_info *elf, Elf_Rela *rela; Elf_Rela r; unsigned int r_sym; - const char *fromsec; - + unsigned int fsecndx = sechdr->sh_info; + const char *fromsec = sec_name(elf, fsecndx); Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rela *stop = (void *)start + sechdr->sh_size; - fromsec = sec_name(elf, sechdr->sh_info); /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; @@ -1434,7 +1431,7 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - check_section_mismatch(modname, elf, &r, sym, fromsec); + check_section_mismatch(modname, elf, &r, sym, fsecndx, fromsec); } } @@ -1445,12 +1442,11 @@ static void section_rel(const char *modname, struct elf_info *elf, Elf_Rel *rel; Elf_Rela r; unsigned int r_sym; - const char *fromsec; - + unsigned int fsecndx = sechdr->sh_info; + const char *fromsec = sec_name(elf, fsecndx); Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rel *stop = (void *)start + sechdr->sh_size; - fromsec = sec_name(elf, sechdr->sh_info); /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; @@ -1493,7 +1489,7 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - check_section_mismatch(modname, elf, &r, sym, fromsec); + check_section_mismatch(modname, elf, &r, sym, fsecndx, fromsec); } } -- cgit v1.2.3 From ac263349b91bf34b7c8419f5645c84b4f88de846 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 15 May 2023 00:27:28 +0900 Subject: modpost: rename find_elf_symbol() and find_elf_symbol2() find_elf_symbol() and find_elf_symbol2() are not good names. Rename them to find_tosym(), find_fromsym(), respectively. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3b7b78e69137..0d2c2aff2c03 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1124,8 +1124,8 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) * In other cases the symbol needs to be looked up in the symbol table * based on section and address. * **/ -static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, - Elf_Sym *relsym) +static Elf_Sym *find_tosym(struct elf_info *elf, Elf64_Sword addr, + Elf_Sym *relsym) { Elf_Sym *sym; Elf_Sym *near = NULL; @@ -1168,8 +1168,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, * The ELF format may have a better way to detect what type of symbol * it is, but this works for now. **/ -static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, - unsigned int secndx) +static Elf_Sym *find_fromsym(struct elf_info *elf, Elf_Addr addr, + unsigned int secndx) { Elf_Sym *sym; Elf_Sym *near = NULL; @@ -1207,10 +1207,10 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, const char *tosym; const char *fromsym; - from = find_elf_symbol2(elf, r->r_offset, fsecndx); + from = find_fromsym(elf, r->r_offset, fsecndx); fromsym = sym_name(elf, from); - to = find_elf_symbol(elf, r->r_addend, sym); + to = find_tosym(elf, r->r_addend, sym); tosym = sym_name(elf, to); /* check whitelist - we may ignore it */ -- cgit v1.2.3 From e1b37563caffc410bb4b55f153ccb14dede66815 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 15 May 2023 19:32:16 +0200 Subject: scripts/tags.sh: Resolve gtags empty index generation gtags considers any file outside of its current working directory "outside the source tree" and refuses to index it. For O= kernel builds, or when "make" is invoked from a directory other then the kernel source tree, gtags ignores the entire kernel source and generates an empty index. Force-set gtags current working directory to the kernel source tree. Due to commit 9da0763bdd82 ("kbuild: Use relative path when building in a subdir of the source tree"), if the kernel build is done in a sub-directory of the kernel source tree, the kernel Makefile will set the kernel's $srctree to ".." for shorter compile-time and run-time warnings. Consequently, the list of files to be indexed will be in the "../*" form, rendering all such paths invalid once gtags switches to the kernel source tree as its current working directory. If gtags indexing is requested and the build directory is not the kernel source tree, index all files in absolute-path form. Note, indexing in absolute-path form will not affect the generated index, as paths in gtags indices are always relative to the gtags "root directory" anyway (as evidenced by "gtags --dump"). Signed-off-by: Ahmed S. Darwish Cc: Signed-off-by: Masahiro Yamada --- scripts/tags.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index ea31640b2671..f6b3c7cd39c7 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -32,6 +32,13 @@ else tree=${srctree}/ fi +# gtags(1) refuses to index any file outside of its current working dir. +# If gtags indexing is requested and the build output directory is not +# the kernel source tree, index all files in absolute-path form. +if [[ "$1" == "gtags" && -n "${tree}" ]]; then + tree=$(realpath "$tree")/ +fi + # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH if [ "${ALLSOURCE_ARCHS}" = "" ]; then ALLSOURCE_ARCHS=${SRCARCH} @@ -131,7 +138,7 @@ docscope() dogtags() { - all_target_sources | gtags -i -f - + all_target_sources | gtags -i -C "${tree:-.}" -f - "$PWD" } # Basic regular expressions with an optional /kind-spec/ for ctags and -- cgit v1.2.3 From b230235b386589d8f0d631b1c77a95ca79bb0732 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 15 May 2023 19:32:17 +0200 Subject: docs: Set minimal gtags / GNU GLOBAL version to 6.6.5 Kernel build now uses the gtags "-C (--directory)" option, available since GNU GLOBAL v6.6.5. Update the documentation accordingly. Signed-off-by: Ahmed S. Darwish Cc: Link: https://lists.gnu.org/archive/html/info-global/2020-09/msg00000.html Signed-off-by: Masahiro Yamada --- Documentation/process/changes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index ef540865ad22..a9ef00509c9b 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -60,6 +60,7 @@ openssl & libcrypto 1.0.0 openssl version bc 1.06.95 bc --version Sphinx\ [#f1]_ 1.7 sphinx-build --version cpio any cpio --version +gtags (optional) 6.6.5 gtags --version ====================== =============== ======================================== .. [#f1] Sphinx is needed only to build the Kernel documentation @@ -174,6 +175,12 @@ You will need openssl to build kernels 3.7 and higher if module signing is enabled. You will also need openssl development packages to build kernels 4.3 and higher. +gtags / GNU GLOBAL (optional) +----------------------------- + +The kernel build requires GNU GLOBAL version 6.6.5 or later to generate +tag files through ``make gtags``. This is due to its use of the gtags +``-C (--directory)`` flag. System utilities **************** -- cgit v1.2.3 From 49c386ebbb43394ff4773ce24f726f6afc4c30c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 21 May 2023 22:23:35 +0900 Subject: Revert "kheaders: substituting --sort in archive creation" This reverts commit 700dea5a0bea9f64eba89fae7cb2540326fdfdc1. The reason for that commit was --sort=ORDER introduced in tar 1.28 (2014). More than 3 years have passed since then. Requiring GNU tar 1.28 should be fine now because we require GCC 5.1 (2015). Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- kernel/gen_kheaders.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 1ef9a87511f5..6d443ea22bb7 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -83,12 +83,9 @@ find $cpio_dir -type f -print0 | xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' # Create archive and try to normalize metadata for reproducibility. -# For compatibility with older versions of tar, files are fed to tar -# pre-sorted, as --sort=name might not be available. -find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ - tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ - --owner=0 --group=0 --numeric-owner --no-recursion \ - -I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null +tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ + --owner=0 --group=0 --sort=name --numeric-owner \ + -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null echo $headers_md5 > kernel/kheaders.md5 echo "$this_file_md5" >> kernel/kheaders.md5 -- cgit v1.2.3 From c584476d477e7617478dc9a305350629aa155f5c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 21 May 2023 22:23:36 +0900 Subject: doc: Add tar requirement to changes.rst tar is used to build the kernel with CONFIG_IKHEADERS. GNU tar 1.28 or later is required. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier --- Documentation/process/changes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index a9ef00509c9b..3c0074214d75 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -60,6 +60,7 @@ openssl & libcrypto 1.0.0 openssl version bc 1.06.95 bc --version Sphinx\ [#f1]_ 1.7 sphinx-build --version cpio any cpio --version +GNU tar 1.28 tar --version gtags (optional) 6.6.5 gtags --version ====================== =============== ======================================== @@ -175,6 +176,12 @@ You will need openssl to build kernels 3.7 and higher if module signing is enabled. You will also need openssl development packages to build kernels 4.3 and higher. +Tar +--- + +GNU tar is needed if you want to enable access to the kernel headers via sysfs +(CONFIG_IKHEADERS). + gtags / GNU GLOBAL (optional) ----------------------------- -- cgit v1.2.3 From 17b53f10aba7c17e92bcf713179bc577cba059b7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:06 +0900 Subject: Revert "modpost: skip ELF local symbols during section mismatch check" This reverts commit a4d26f1a0958bb1c2b60c6f1e67c6f5d43e2647b. The variable 'fromsym' never starts with ".L" since commit 87e5b1e8f257 ("module: Sync code of is_arm_mapping_symbol()"). In other words, Pattern 6 is now dead code. Previously, the .LANCHOR1 hid the symbols listed in Pattern 2. 87e5b1e8f257 provided a better solution. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0d2c2aff2c03..71de14544432 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1034,14 +1034,6 @@ static const struct sectioncheck *section_mismatch( * fromsec = text section * refsymname = *.constprop.* * - * Pattern 6: - * Hide section mismatch warnings for ELF local symbols. The goal - * is to eliminate false positive modpost warnings caused by - * compiler-generated ELF local symbol names such as ".LANCHOR1". - * Autogenerated symbol names bypass modpost's "Pattern 2" - * whitelisting, which relies on pattern-matching against symbol - * names to work. (One situation where gcc can autogenerate ELF - * local symbols is when "-fsection-anchors" is used.) **/ static int secref_whitelist(const struct sectioncheck *mismatch, const char *fromsec, const char *fromsym, @@ -1092,10 +1084,6 @@ static int secref_whitelist(const struct sectioncheck *mismatch, match(fromsym, optim_symbols)) return 0; - /* Check for pattern 6 */ - if (strstarts(fromsym, ".L")) - return 0; - return 1; } -- cgit v1.2.3 From 05bb0704672dec59cbdc6b901130098ecfe7a846 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:09 +0900 Subject: modpost: remove unused argument from secref_whitelist() secref_whitelist() does not use the argument 'mismatch'. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 71de14544432..c0b262b68d50 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1035,8 +1035,7 @@ static const struct sectioncheck *section_mismatch( * refsymname = *.constprop.* * **/ -static int secref_whitelist(const struct sectioncheck *mismatch, - const char *fromsec, const char *fromsym, +static int secref_whitelist(const char *fromsec, const char *fromsym, const char *tosec, const char *tosym) { /* Check for pattern 1 */ @@ -1202,7 +1201,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, tosym = sym_name(elf, to); /* check whitelist - we may ignore it */ - if (!secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym)) + if (!secref_whitelist(fromsec, fromsym, tosec, tosym)) return; sec_mismatch_count++; -- cgit v1.2.3 From a23e7584ecf33df2b27ac176185c7b030ab0736f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:11 +0900 Subject: modpost: unify 'sym' and 'to' in default_mismatch_handler() find_tosym() takes 'sym' and stores the return value to another variable 'to'. You can use the same variable because we want to replace the original one when appropriate. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c0b262b68d50..9290e0f804cf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1185,11 +1185,10 @@ static bool is_executable_section(struct elf_info *elf, unsigned int secndx) static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *sym, + Elf_Rela *r, Elf_Sym *tsym, unsigned int fsecndx, const char *fromsec, const char *tosec) { - Elf_Sym *to; Elf_Sym *from; const char *tosym; const char *fromsym; @@ -1197,8 +1196,8 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, from = find_fromsym(elf, r->r_offset, fsecndx); fromsym = sym_name(elf, from); - to = find_tosym(elf, r->r_addend, sym); - tosym = sym_name(elf, to); + tsym = find_tosym(elf, r->r_addend, tsym); + tosym = sym_name(elf, tsym); /* check whitelist - we may ignore it */ if (!secref_whitelist(fromsec, fromsym, tosec, tosym)) @@ -1233,7 +1232,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", fromsec, (long)r->r_offset, tosec, modname); - else if (is_executable_section(elf, get_secindex(elf, sym))) + else if (is_executable_section(elf, get_secindex(elf, tsym))) warn("The relocation at %s+0x%lx references\n" "section \"%s\" which is not in the list of\n" "authorized sections. If you're adding a new section\n" -- cgit v1.2.3 From 04ed3b476306c1b4c6e544e40d10f477c8193435 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:12 +0900 Subject: modpost: replace r->r_offset, r->r_addend with faddr, taddr r_offset/r_addend holds the offset address from/to which a symbol is referenced. It is unclear unless you are familiar with ELF. Rename them to faddr, taddr, respectively. The prefix 'f' means 'from', 't' means 'to'. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9290e0f804cf..c339d9eda402 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1185,18 +1185,18 @@ static bool is_executable_section(struct elf_info *elf, unsigned int secndx) static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, - Elf_Rela *r, Elf_Sym *tsym, - unsigned int fsecndx, const char *fromsec, - const char *tosec) + Elf_Sym *tsym, + unsigned int fsecndx, const char *fromsec, Elf_Addr faddr, + const char *tosec, Elf_Addr taddr) { Elf_Sym *from; const char *tosym; const char *fromsym; - from = find_fromsym(elf, r->r_offset, fsecndx); + from = find_fromsym(elf, faddr, fsecndx); fromsym = sym_name(elf, from); - tsym = find_tosym(elf, r->r_addend, tsym); + tsym = find_tosym(elf, taddr, tsym); tosym = sym_name(elf, tsym); /* check whitelist - we may ignore it */ @@ -1223,7 +1223,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, break; case EXTABLE_TO_NON_TEXT: warn("%s(%s+0x%lx): Section mismatch in reference to the %s:%s\n", - modname, fromsec, (long)r->r_offset, tosec, tosym); + modname, fromsec, (long)faddr, tosec, tosym); if (match(tosec, mismatch->bad_tosec)) fatal("The relocation at %s+0x%lx references\n" @@ -1231,7 +1231,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, "Something is seriously wrong and should be fixed.\n" "You might get more information about where this is\n" "coming from by using scripts/check_extable.sh %s\n", - fromsec, (long)r->r_offset, tosec, modname); + fromsec, (long)faddr, tosec, modname); else if (is_executable_section(elf, get_secindex(elf, tsym))) warn("The relocation at %s+0x%lx references\n" "section \"%s\" which is not in the list of\n" @@ -1240,17 +1240,18 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, "list of authorized sections to jump to on fault.\n" "This can be achieved by adding \"%s\" to\n" "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n", - fromsec, (long)r->r_offset, tosec, tosec, tosec); + fromsec, (long)faddr, tosec, tosec, tosec); else error("%s+0x%lx references non-executable section '%s'\n", - fromsec, (long)r->r_offset, tosec); + fromsec, (long)faddr, tosec); break; } } static void check_section_mismatch(const char *modname, struct elf_info *elf, - Elf_Rela *r, Elf_Sym *sym, - unsigned int fsecndx, const char *fromsec) + Elf_Sym *sym, + unsigned int fsecndx, const char *fromsec, + Elf_Addr faddr, Elf_Addr taddr) { const char *tosec = sec_name(elf, get_secindex(elf, sym)); const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec); @@ -1258,8 +1259,9 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, if (!mismatch) return; - default_mismatch_handler(modname, elf, mismatch, r, sym, fsecndx, fromsec, - tosec); + default_mismatch_handler(modname, elf, mismatch, sym, + fsecndx, fromsec, faddr, + tosec, taddr); } static unsigned int *reloc_location(struct elf_info *elf, @@ -1417,7 +1419,8 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - check_section_mismatch(modname, elf, &r, sym, fsecndx, fromsec); + check_section_mismatch(modname, elf, sym, + fsecndx, fromsec, r.r_offset, r.r_addend); } } @@ -1475,7 +1478,8 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (is_shndx_special(sym->st_shndx)) continue; - check_section_mismatch(modname, elf, &r, sym, fsecndx, fromsec); + check_section_mismatch(modname, elf, sym, + fsecndx, fromsec, r.r_offset, r.r_addend); } } -- cgit v1.2.3 From a9bb3e5d57293773d7f925dd07e45f6e13e94947 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:13 +0900 Subject: modpost: remove is_shndx_special() check from section_rel(a) This check is unneeded. Without it, sec_name() will returns the null string "", then section_mismatch() will return immediately. Anyway, special section indices rarely appear in these loops. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 16 ++++------------ scripts/mod/modpost.h | 5 ----- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c339d9eda402..1018cd9ced71 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1372,7 +1372,6 @@ static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) static void section_rela(const char *modname, struct elf_info *elf, Elf_Shdr *sechdr) { - Elf_Sym *sym; Elf_Rela *rela; Elf_Rela r; unsigned int r_sym; @@ -1415,11 +1414,8 @@ static void section_rela(const char *modname, struct elf_info *elf, continue; break; } - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (is_shndx_special(sym->st_shndx)) - continue; - check_section_mismatch(modname, elf, sym, + + check_section_mismatch(modname, elf, elf->symtab_start + r_sym, fsecndx, fromsec, r.r_offset, r.r_addend); } } @@ -1427,7 +1423,6 @@ static void section_rela(const char *modname, struct elf_info *elf, static void section_rel(const char *modname, struct elf_info *elf, Elf_Shdr *sechdr) { - Elf_Sym *sym; Elf_Rel *rel; Elf_Rela r; unsigned int r_sym; @@ -1474,11 +1469,8 @@ static void section_rel(const char *modname, struct elf_info *elf, default: fatal("Please add code to calculate addend for this architecture\n"); } - sym = elf->symtab_start + r_sym; - /* Skip special sections */ - if (is_shndx_special(sym->st_shndx)) - continue; - check_section_mismatch(modname, elf, sym, + + check_section_mismatch(modname, elf, elf->symtab_start + r_sym, fsecndx, fromsec, r.r_offset, r.r_addend); } } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 1178f40a73f3..b1e2d95f8047 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -151,11 +151,6 @@ struct elf_info { Elf32_Word *symtab_shndx_stop; }; -static inline int is_shndx_special(unsigned int i) -{ - return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; -} - /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ static inline unsigned int get_secindex(const struct elf_info *info, const Elf_Sym *sym) -- cgit v1.2.3 From d4323e83505247d2aca1e2488f69da9aab8ad03f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:21 +0900 Subject: modpost: merge fromsec=DATA_SECTIONS entries in sectioncheck table You can merge these entries. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1018cd9ced71..21417a4a7655 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -900,12 +900,7 @@ static const struct sectioncheck sectioncheck[] = { }, { .fromsec = { DATA_SECTIONS, NULL }, - .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL }, - .mismatch = DATA_TO_ANY_INIT, -}, -{ - .fromsec = { DATA_SECTIONS, NULL }, - .bad_tosec = { INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_XXXINIT_SECTIONS, INIT_SECTIONS, NULL }, .mismatch = DATA_TO_ANY_INIT, }, { -- cgit v1.2.3 From abc23979ac90396c5a5dff03dcea198b5bd0c50d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:22 +0900 Subject: modpost: merge bad_tosec=ALL_EXIT_SECTIONS entries in sectioncheck table There is no distinction between TEXT_TO_ANY_EXIT and DATA_TO_ANY_EXIT. Just merge them. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers --- scripts/mod/modpost.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 21417a4a7655..cc4cf40a360f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -859,8 +859,7 @@ static const char *const optim_symbols[] = { "*.constprop.*", NULL }; enum mismatch { TEXT_TO_ANY_INIT, DATA_TO_ANY_INIT, - TEXT_TO_ANY_EXIT, - DATA_TO_ANY_EXIT, + TEXTDATA_TO_ANY_EXIT, XXXINIT_TO_SOME_INIT, XXXEXIT_TO_SOME_EXIT, ANY_INIT_TO_ANY_EXIT, @@ -904,14 +903,9 @@ static const struct sectioncheck sectioncheck[] = { .mismatch = DATA_TO_ANY_INIT, }, { - .fromsec = { TEXT_SECTIONS, NULL }, - .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, - .mismatch = TEXT_TO_ANY_EXIT, -}, -{ - .fromsec = { DATA_SECTIONS, NULL }, + .fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, - .mismatch = DATA_TO_ANY_EXIT, + .mismatch = TEXTDATA_TO_ANY_EXIT, }, /* Do not reference init code/data from meminit code/data */ { @@ -1203,8 +1197,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, switch (mismatch->mismatch) { case TEXT_TO_ANY_INIT: case DATA_TO_ANY_INIT: - case TEXT_TO_ANY_EXIT: - case DATA_TO_ANY_EXIT: + case TEXTDATA_TO_ANY_EXIT: case XXXINIT_TO_SOME_INIT: case XXXEXIT_TO_SOME_EXIT: case ANY_INIT_TO_ANY_EXIT: -- cgit v1.2.3 From 1df380ff3018521bd1b129dff60984b61ade8cee Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 22 May 2023 01:04:23 +0900 Subject: modpost: remove *_sections[] arrays Use PATTERNS() macros to remove unneeded array definitions. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index cc4cf40a360f..7031e5da62e5 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -838,24 +838,6 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \ TEXT_SECTIONS, OTHER_TEXT_SECTIONS -/* init data sections */ -static const char *const init_data_sections[] = - { ALL_INIT_DATA_SECTIONS, NULL }; - -/* all init sections */ -static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL }; - -/* all text sections */ -static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL }; - -/* data section */ -static const char *const data_sections[] = { DATA_SECTIONS, NULL }; - -static const char *const head_sections[] = { ".head.text*", NULL }; -static const char *const linker_symbols[] = - { "__init_begin", "_sinittext", "_einittext", NULL }; -static const char *const optim_symbols[] = { "*.constprop.*", NULL }; - enum mismatch { TEXT_TO_ANY_INIT, DATA_TO_ANY_INIT, @@ -1028,14 +1010,14 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, const char *tosec, const char *tosym) { /* Check for pattern 1 */ - if (match(tosec, init_data_sections) && - match(fromsec, data_sections) && + if (match(tosec, PATTERNS(ALL_INIT_DATA_SECTIONS)) && + match(fromsec, PATTERNS(DATA_SECTIONS)) && strstarts(fromsym, "__param")) return 0; /* Check for pattern 1a */ if (strcmp(tosec, ".init.text") == 0 && - match(fromsec, data_sections) && + match(fromsec, PATTERNS(DATA_SECTIONS)) && strstarts(fromsym, "__param_ops_")) return 0; @@ -1058,18 +1040,18 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, return 0; /* Check for pattern 3 */ - if (match(fromsec, head_sections) && - match(tosec, init_sections)) + if (strstarts(fromsec, ".head.text") && + match(tosec, PATTERNS(ALL_INIT_SECTIONS))) return 0; /* Check for pattern 4 */ - if (match(tosym, linker_symbols)) + if (match(tosym, PATTERNS("__init_begin", "_sinittext", "_einittext"))) return 0; /* Check for pattern 5 */ - if (match(fromsec, text_sections) && - match(tosec, init_sections) && - match(fromsym, optim_symbols)) + if (match(fromsec, PATTERNS(ALL_TEXT_SECTIONS)) && + match(tosec, PATTERNS(ALL_INIT_SECTIONS)) && + match(fromsym, PATTERNS("*.constprop.*"))) return 0; return 1; -- cgit v1.2.3 From b7c63520f6703a25eebb4f8138fed764fcae1c6f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 1 Jun 2023 21:09:55 +0900 Subject: modpost: fix section mismatch message for R_ARM_ABS32 addend_arm_rel() processes R_ARM_ABS32 in a wrong way. Here, test code. [test code 1] #include int __initdata foo; int get_foo(void) { return foo; } If you compile it with ARM versatile_defconfig, modpost will show the symbol name, (unknown). WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> (unknown) (section: .init.data) (You need to use GNU linker instead of LLD to reproduce it.) If you compile it for other architectures, modpost will show the correct symbol name. WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data) For R_ARM_ABS32, addend_arm_rel() sets r->r_addend to a wrong value. I just mimicked the code in arch/arm/kernel/module.c. However, there is more difficulty for ARM. Here, test code. [test code 2] #include int __initdata foo; int get_foo(void) { return foo; } int __initdata bar; int get_bar(void) { return bar; } With this commit applied, modpost will show the following messages for ARM versatile_defconfig: WARNING: modpost: vmlinux.o: section mismatch in reference: get_foo (section: .text) -> foo (section: .init.data) WARNING: modpost: vmlinux.o: section mismatch in reference: get_bar (section: .text) -> foo (section: .init.data) The reference from 'get_bar' to 'foo' seems wrong. I have no solution for this because it is true in assembly level. In the following output, relocation at 0x1c is no longer associated with 'bar'. The two relocation entries point to the same symbol, and the offset to 'bar' is encoded in the instruction 'r0, [r3, #4]'. Disassembly of section .text: 00000000 : 0: e59f3004 ldr r3, [pc, #4] @ c 4: e5930000 ldr r0, [r3] 8: e12fff1e bx lr c: 00000000 .word 0x00000000 00000010 : 10: e59f3004 ldr r3, [pc, #4] @ 1c 14: e5930004 ldr r0, [r3, #4] 18: e12fff1e bx lr 1c: 00000000 .word 0x00000000 Relocation section '.rel.text' at offset 0x244 contains 2 entries: Offset Info Type Sym.Value Sym. Name 0000000c 00000c02 R_ARM_ABS32 00000000 .init.data 0000001c 00000c02 R_ARM_ABS32 00000000 .init.data When find_elf_symbol() gets into a situation where relsym->st_name is zero, there is no guarantee to get the symbol name as written in C. I am keeping the current logic because it is useful in many architectures, but the symbol name is not always correct depending on the optimization. I left some comments in find_tosym(). Fixes: 56a974fa2d59 ("kbuild: make better section mismatch reports on arm") Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7031e5da62e5..c68dad45ace2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1094,6 +1094,10 @@ static Elf_Sym *find_tosym(struct elf_info *elf, Elf64_Sword addr, if (relsym->st_name != 0) return relsym; + /* + * Strive to find a better symbol name, but the resulting name may not + * match the symbol referenced in the original code. + */ relsym_secindex = get_secindex(elf, relsym);