modpost: Ignore relaxation and alignment marker relocs on LoongArch
authorWANG Xuerui <git@xen0n.name>
Wed, 17 Jan 2024 04:42:59 +0000 (12:42 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 17 Jan 2024 04:42:59 +0000 (12:42 +0800)
With recent trunk versions of binutils and gcc, alignment directives are
represented with R_LARCH_ALIGN relocs on LoongArch, which is necessary
for the linker to maintain alignment requirements during its relaxation
passes. And even though the kernel is built with relaxation disabled, so
far a small number of R_LARCH_RELAX marker relocs are still emitted as
part of la.* pseudo instructions in assembly. These two kinds of relocs
do not refer to symbols, which can trip up modpost's section mismatch
checks, because the r_offset of said relocs can be zero or any other
meaningless value, eventually leading to a `from == NULL` condition in
default_mismatch_handler and SIGSEGV.

As the two kinds of relocs are not concerned with symbols, just ignore
them for section mismatch check purposes.

Signed-off-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
scripts/mod/modpost.c

index cb6406f485a960041db048a5f5e8ae5bfad40bb5..68ab45273a22ff5690ca6281c093e93ba8e48d4b 100644 (file)
@@ -1346,6 +1346,14 @@ static Elf_Addr addend_mips_rel(uint32_t *location, unsigned int r_type)
 #define R_LARCH_SUB32          55
 #endif
 
+#ifndef R_LARCH_RELAX
+#define R_LARCH_RELAX          100
+#endif
+
+#ifndef R_LARCH_ALIGN
+#define R_LARCH_ALIGN          102
+#endif
+
 static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
                                 unsigned int *r_type, unsigned int *r_sym)
 {
@@ -1400,9 +1408,16 @@ static void section_rela(struct module *mod, struct elf_info *elf,
                                continue;
                        break;
                case EM_LOONGARCH:
-                       if (!strcmp("__ex_table", fromsec) &&
-                           r_type == R_LARCH_SUB32)
+                       switch (r_type) {
+                       case R_LARCH_SUB32:
+                               if (!strcmp("__ex_table", fromsec))
+                                       continue;
+                               break;
+                       case R_LARCH_RELAX:
+                       case R_LARCH_ALIGN:
+                               /* These relocs do not refer to symbols */
                                continue;
+                       }
                        break;
                }