History

kbuild: make better section mismatch reports on i386, arm and mips

On i386, ARM and MIPS, warn_sec_mismatch() sometimes fails to show usefull symbol name. This is because empty 'refsym' due to 0 r_addend value. This patch is to adjust r_addend value, consulting with apply_relocate() routine in kernel code. Without this patch: MODPOST vmlinux WARNING: init/built-in.o - Section mismatch: reference to .init.text: from .text between 'rest_init' (at offset 0xf4) and 'try_name' WARNING: mm/built-in.o - Section mismatch: reference to .init.text: from .text between 'kmem_cache_create' (at offset 0x18a39) and 'cache_reap' WARNING: mm/built-in.o - Section mismatch: reference to .init.text: from .text between 'kmem_cache_create' (at offset 0x18a6b) and 'cache_reap' With this patch: MODPOST vmlinux WARNING: mm/built-in.o - Section mismatch: reference to .init.text:set_up_list3s from .text between 'kmem_cache_create' (at offset 0x18a39) and 'cache_reap' WARNING: mm/built-in.o - Section mismatch: reference to .init.text:set_up_list3s from .text between 'kmem_cache_create' (at offset 0x18a6b) and 'cache_reap' Now modpost can detect "kernel_init" name (and whitelist it) and show "set_up_list3s" name.

Atsushi Nemoto committed 19 years ago

Commit f892b7d1 parent 25601202 files · +82 −0Browse files

Showing the changes to scripts (2 of 2 files). Show all

Unified · Split

2 files
  1. scripts/mod/modpost.c +79 −0
  2. scripts/mod/modpost.h +3 −0
scripts/mod/modpost.c+79−0
@@ -384,6 +384,7 @@ static int parse_elf(struct elf_info *info, const char *filename) · 383 unmodified lines
384384 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
385385 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
386386 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
387+ sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
387388 }
388389 /* Find symbol table. */
389390 for (i = 1; i < hdr->e_shnum; i++) {
@@ -773,6 +774,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, · 383 unmodified lines
773774 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
774775 if (sym->st_shndx != relsym->st_shndx)
775776 continue;
777+ if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
778+ continue;
776779 if (sym->st_value == addr)
777780 return sym;
778781 }
@@ -910,6 +913,68 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, · 131 unmodified lines
910913 }
911914 }
912915
916+static void addend_386_rel(struct elf_info *elf, int section, Elf_Rela *r)
917+{
918+ Elf_Shdr *sechdrs = elf->sechdrs;
919+ unsigned int r_typ;
920+ unsigned int *location;
921+
922+ r_typ = ELF_R_TYPE(r->r_info);
923+ location = (void *)elf->hdr +
924+ sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset;
925+ switch (r_typ) {
926+ case R_386_32:
927+ r->r_addend = TO_NATIVE(*location);
928+ break;
929+ case R_386_PC32:
930+ r->r_addend = TO_NATIVE(*location) + 4;
931+ break;
932+ }
933+}
934+
935+static void addend_arm_rel(struct elf_info *elf, int section, Elf_Rela *r)
936+{
937+ Elf_Shdr *sechdrs = elf->sechdrs;
938+ unsigned int r_typ;
939+ unsigned int *location;
940+
941+ r_typ = ELF_R_TYPE(r->r_info);
942+ location = (void *)elf->hdr +
943+ sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset;
944+ switch (r_typ) {
945+ case R_ARM_ABS32:
946+ r->r_addend = TO_NATIVE(*location);
947+ break;
948+ case R_ARM_PC24:
949+ r->r_addend = ((TO_NATIVE(*location) & 0x00ffffff) << 2) + 8;
950+ break;
951+ }
952+}
953+
954+static int addend_mips_rel(struct elf_info *elf, int section, Elf_Rela *r)
955+{
956+ Elf_Shdr *sechdrs = elf->sechdrs;
957+ unsigned int r_typ;
958+ unsigned int *location;
959+ unsigned int inst;
960+
961+ r_typ = ELF_R_TYPE(r->r_info);
962+ if (r_typ == R_MIPS_HI16)
963+ return 1; /* skip this */
964+ location = (void *)elf->hdr +
965+ sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset;
966+ inst = TO_NATIVE(*location);
967+ switch (r_typ) {
968+ case R_MIPS_LO16:
969+ r->r_addend = ((inst & 0xffff) ^ 0x8000) - 0x8000;
970+ break;
971+ case R_MIPS_26:
972+ r->r_addend = (inst & 0x03ffffff) << 2;
973+ break;
974+ }
975+ return 0;
976+}
977+
913978 /**
914979 * A module includes a number of sections that are discarded
915980 * either when loaded or when used as built-in.
@@ -953,8 +1018,11 @@ static void check_sec_ref(struct module *mod, const char *modname, · 37 unmodified lines
9531018 r.r_offset = TO_NATIVE(rela->r_offset);
9541019 #if KERNEL_ELFCLASS == ELFCLASS64
9551020 if (hdr->e_machine == EM_MIPS) {
1021+ unsigned int r_typ;
9561022 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
9571023 r_sym = TO_NATIVE(r_sym);
1024+ r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1025+ r.r_info = ELF64_R_INFO(r_sym, r_typ);
9581026 } else {
9591027 r.r_info = TO_NATIVE(rela->r_info);
9601028 r_sym = ELF_R_SYM(r.r_info);
@@ -987,8 +1055,11 @@ static void check_sec_ref(struct module *mod, const char *modname, · 26 unmodified lines
9871055 r.r_offset = TO_NATIVE(rel->r_offset);
9881056 #if KERNEL_ELFCLASS == ELFCLASS64
9891057 if (hdr->e_machine == EM_MIPS) {
1058+ unsigned int r_typ;
9901059 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
9911060 r_sym = TO_NATIVE(r_sym);
1061+ r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1062+ r.r_info = ELF64_R_INFO(r_sym, r_typ);
9921063 } else {
9931064 r.r_info = TO_NATIVE(rel->r_info);
9941065 r_sym = ELF_R_SYM(r.r_info);
@@ -998,6 +1069,14 @@ static void check_sec_ref(struct module *mod, const char *modname, · 3 unmodified lines
9981069 r_sym = ELF_R_SYM(r.r_info);
9991070 #endif
10001071 r.r_addend = 0;
1072+ if (hdr->e_machine == EM_386)
1073+ addend_386_rel(elf, i, &r);
1074+ else if (hdr->e_machine == EM_ARM)
1075+ addend_arm_rel(elf, i, &r);
1076+ else if (hdr->e_machine == EM_MIPS) {
1077+ if (addend_mips_rel(elf, i, &r))
1078+ continue;
1079+ }
10011080 sym = elf->symtab_start + r_sym;
10021081 /* Skip special sections */
10031082 if (sym->st_shndx >= SHN_LORESERVE)
scripts/mod/modpost.h+3−0
@@ -60,6 +60,9 @@ typedef union · 59 unmodified lines
6060 #define ELF64_MIPS_R_SYM(i) \
6161 ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
6262
63+#define ELF64_MIPS_R_TYPE(i) \
64+ ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
65+
6366 #if KERNEL_ELFDATA != HOST_ELFDATA
6467
6568 static inline void __endian(const void *src, void *dest, unsigned int size)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t