Commit ae4ac12323c0ff80528cac3269151d580e23f923

Authored by Atsushi Nemoto
Committed by Sam Ravnborg
1 parent b70e325cfe

kbuild: make better section mismatch reports on i386 and mips

On i386 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.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>

Showing 2 changed files with 76 additions and 0 deletions Side-by-side Diff

scripts/mod/modpost.c
... ... @@ -374,6 +374,7 @@
374 374 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
375 375 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
376 376 hdr->e_machine = TO_NATIVE(hdr->e_machine);
  377 + hdr->e_type = TO_NATIVE(hdr->e_type);
377 378 sechdrs = (void *)hdr + hdr->e_shoff;
378 379 info->sechdrs = sechdrs;
379 380  
... ... @@ -384,6 +385,8 @@
384 385 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
385 386 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
386 387 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
  388 + sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
  389 + sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
387 390 }
388 391 /* Find symbol table. */
389 392 for (i = 1; i < hdr->e_shnum; i++) {
... ... @@ -753,6 +756,8 @@
753 756 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
754 757 if (sym->st_shndx != relsym->st_shndx)
755 758 continue;
  759 + if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  760 + continue;
756 761 if (sym->st_value == addr)
757 762 return sym;
758 763 }
... ... @@ -895,6 +900,58 @@
895 900 }
896 901 }
897 902  
  903 +static unsigned int *reloc_location(struct elf_info *elf,
  904 + int rsection, Elf_Rela *r)
  905 +{
  906 + Elf_Shdr *sechdrs = elf->sechdrs;
  907 + int section = sechdrs[rsection].sh_info;
  908 +
  909 + return (void *)elf->hdr + sechdrs[section].sh_offset +
  910 + (r->r_offset - sechdrs[section].sh_addr);
  911 +}
  912 +
  913 +static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
  914 +{
  915 + unsigned int r_typ = ELF_R_TYPE(r->r_info);
  916 + unsigned int *location = reloc_location(elf, rsection, r);
  917 +
  918 + switch (r_typ) {
  919 + case R_386_32:
  920 + r->r_addend = TO_NATIVE(*location);
  921 + break;
  922 + case R_386_PC32:
  923 + r->r_addend = TO_NATIVE(*location) + 4;
  924 + /* For CONFIG_RELOCATABLE=y */
  925 + if (elf->hdr->e_type == ET_EXEC)
  926 + r->r_addend += r->r_offset;
  927 + break;
  928 + }
  929 + return 0;
  930 +}
  931 +
  932 +static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
  933 +{
  934 + unsigned int r_typ = ELF_R_TYPE(r->r_info);
  935 + unsigned int *location = reloc_location(elf, rsection, r);
  936 + unsigned int inst;
  937 +
  938 + if (r_typ == R_MIPS_HI16)
  939 + return 1; /* skip this */
  940 + inst = TO_NATIVE(*location);
  941 + switch (r_typ) {
  942 + case R_MIPS_LO16:
  943 + r->r_addend = inst & 0xffff;
  944 + break;
  945 + case R_MIPS_26:
  946 + r->r_addend = (inst & 0x03ffffff) << 2;
  947 + break;
  948 + case R_MIPS_32:
  949 + r->r_addend = inst;
  950 + break;
  951 + }
  952 + return 0;
  953 +}
  954 +
898 955 /**
899 956 * A module includes a number of sections that are discarded
900 957 * either when loaded or when used as built-in.
901 958  
... ... @@ -938,8 +995,11 @@
938 995 r.r_offset = TO_NATIVE(rela->r_offset);
939 996 #if KERNEL_ELFCLASS == ELFCLASS64
940 997 if (hdr->e_machine == EM_MIPS) {
  998 + unsigned int r_typ;
941 999 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
942 1000 r_sym = TO_NATIVE(r_sym);
  1001 + r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
  1002 + r.r_info = ELF64_R_INFO(r_sym, r_typ);
943 1003 } else {
944 1004 r.r_info = TO_NATIVE(rela->r_info);
945 1005 r_sym = ELF_R_SYM(r.r_info);
946 1006  
... ... @@ -972,8 +1032,11 @@
972 1032 r.r_offset = TO_NATIVE(rel->r_offset);
973 1033 #if KERNEL_ELFCLASS == ELFCLASS64
974 1034 if (hdr->e_machine == EM_MIPS) {
  1035 + unsigned int r_typ;
975 1036 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
976 1037 r_sym = TO_NATIVE(r_sym);
  1038 + r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
  1039 + r.r_info = ELF64_R_INFO(r_sym, r_typ);
977 1040 } else {
978 1041 r.r_info = TO_NATIVE(rel->r_info);
979 1042 r_sym = ELF_R_SYM(r.r_info);
... ... @@ -983,6 +1046,16 @@
983 1046 r_sym = ELF_R_SYM(r.r_info);
984 1047 #endif
985 1048 r.r_addend = 0;
  1049 + switch (hdr->e_machine) {
  1050 + case EM_386:
  1051 + if (addend_386_rel(elf, i, &r))
  1052 + continue;
  1053 + break;
  1054 + case EM_MIPS:
  1055 + if (addend_mips_rel(elf, i, &r))
  1056 + continue;
  1057 + break;
  1058 + }
986 1059 sym = elf->symtab_start + r_sym;
987 1060 /* Skip special sections */
988 1061 if (sym->st_shndx >= SHN_LORESERVE)
scripts/mod/modpost.h
... ... @@ -60,6 +60,9 @@
60 60 #define ELF64_MIPS_R_SYM(i) \
61 61 ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
62 62  
  63 +#define ELF64_MIPS_R_TYPE(i) \
  64 + ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
  65 +
63 66 #if KERNEL_ELFDATA != HOST_ELFDATA
64 67  
65 68 static inline void __endian(const void *src, void *dest, unsigned int size)